dsh-manage-session 0.2.3 → 0.4.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/CHANGELOG.ja.md +19 -0
- package/CHANGELOG.ko.md +18 -0
- package/CHANGELOG.md +40 -0
- package/README.en.md +14 -0
- package/README.ja.md +14 -0
- package/README.ko.md +14 -0
- package/README.md +14 -0
- package/dsh.plugin.json +4 -4
- package/lib/client.js +179 -36
- package/lib/index.d.ts +288 -16
- package/lib/index.js +1003 -384
- package/package.json +125 -121
- package/screenshots.json +5 -1
- package/src/client/card.tsx +150 -153
- package/src/client/health-panel.tsx +56 -1
- package/src/client/host-api.ts +19 -1
- package/src/client/index.ts +337 -234
- package/src/client/locales.ts +22 -2
- package/src/host/health/cache.ts +1 -1
- package/src/host/health/decode.ts +19 -1
- package/src/host/health/gates.ts +94 -3
- package/src/host/health/generation.ts +216 -0
- package/src/host/health/repair.ts +28 -7
- package/src/host/health/scan.ts +84 -27
- package/src/host/health/source-kind.ts +350 -0
- package/src/host/history/archive.ts +4 -1
- package/src/host/history/purge.ts +51 -4
- package/src/index.ts +83 -55
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
1
2
|
//#region node_modules/cosmokit/lib/index.d.ts
|
|
2
3
|
type Dict<T = any, K extends string | symbol = string> = { [key in K]: T; };
|
|
3
4
|
type Promisify<T> = Promise<T extends Promise<infer S> ? S : T>;
|
|
@@ -571,6 +572,14 @@ interface SessionLogRead {
|
|
|
571
572
|
turn: number;
|
|
572
573
|
step: number;
|
|
573
574
|
};
|
|
575
|
+
/**
|
|
576
|
+
* 日志首行的 header(`type: 'session'` 记录)。
|
|
577
|
+
*
|
|
578
|
+
* 取它是为了拿到 `version`(格式代次):文件名代次与 header 代次都由宿主的
|
|
579
|
+
* 代次发布路径写入,二者一致是发布不变量。首行不是 JSON 时为 undefined,
|
|
580
|
+
* 由 `log-integrity` 门按解码问题如实报出,不在这里抛。
|
|
581
|
+
*/
|
|
582
|
+
header?: Record<string, unknown>;
|
|
574
583
|
}
|
|
575
584
|
/** 解码后的事件(结构子集)。 */
|
|
576
585
|
interface DecodedEvent {
|
|
@@ -600,7 +609,7 @@ interface OfficialDecoders {
|
|
|
600
609
|
}
|
|
601
610
|
/**
|
|
602
611
|
* 读取一个会话日志文件(zip 帧扫描 + 解包 + seq 连续性)。
|
|
603
|
-
* @param file -
|
|
612
|
+
* @param file - 当前代日志的绝对路径(由代次解析得出,不假定具体文件名)。
|
|
604
613
|
* @param bytes - 文件内容(调用方读取,便于测试注入)。
|
|
605
614
|
* @param decoders - 可选官方解码器(缺省用本地等价实现)。
|
|
606
615
|
* @returns 事件、统计与问题清单。
|
|
@@ -609,6 +618,96 @@ declare function decodeSessionLogBytes(file: string, bytes: Buffer, decoders?: O
|
|
|
609
618
|
/** 从文件读取并解码。 */
|
|
610
619
|
declare function decodeSessionLogFile(file: string, decoders?: OfficialDecoders): SessionLogRead;
|
|
611
620
|
//#endregion
|
|
621
|
+
//#region src/host/health/generation.d.ts
|
|
622
|
+
/** 日志的物理编码(对齐宿主的 `JsonlCompression`)。 */
|
|
623
|
+
type LogCompression = 'zstd' | 'none';
|
|
624
|
+
/** 处置优先级:`high` = 该会话的当前代是从暂存(TMP)发布出来的。 */
|
|
625
|
+
type SessionPriority = 'high' | 'normal';
|
|
626
|
+
/** 一份日志产物在磁盘上的事实。 */
|
|
627
|
+
interface LogArtifact {
|
|
628
|
+
/** 文件名(不含目录)。 */
|
|
629
|
+
name: string;
|
|
630
|
+
/** 绝对路径。 */
|
|
631
|
+
path: string;
|
|
632
|
+
bytes: number;
|
|
633
|
+
/** mtime(epoch ms)。 */
|
|
634
|
+
mtimeMs: number;
|
|
635
|
+
}
|
|
636
|
+
/** 一份规范代次产物。 */
|
|
637
|
+
interface GenerationArtifact extends LogArtifact {
|
|
638
|
+
/** 该文件承载的格式代次;0 为无版本号的历史代。 */
|
|
639
|
+
version: number;
|
|
640
|
+
/** 该文件的物理编码。 */
|
|
641
|
+
compression: LogCompression;
|
|
642
|
+
}
|
|
643
|
+
/** 一个会话目录的代次事实。 */
|
|
644
|
+
interface SessionGenerations {
|
|
645
|
+
/** 目录内全部规范产物,按代次升序(同代次再按 mtime 升序)。 */
|
|
646
|
+
canonical: GenerationArtifact[];
|
|
647
|
+
/** 当前代 = 规范产物中代次最高的一份;目录内没有规范产物时为 undefined。 */
|
|
648
|
+
current?: GenerationArtifact;
|
|
649
|
+
/** 历史代(代次 0);宿主按契约保留已提交的旧代次,不删不改。 */
|
|
650
|
+
legacy?: GenerationArtifact;
|
|
651
|
+
/** 迁移暂存残留(发布源)。 */
|
|
652
|
+
staging: LogArtifact[];
|
|
653
|
+
/** 只有历史代、尚无更高代次:宿主首次写访问才会发布,冷读要全量内存迁移。 */
|
|
654
|
+
legacyOnly: boolean;
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* 某代次的规范日志文件名。
|
|
658
|
+
* @param version - 非负安全整数的格式代次。
|
|
659
|
+
* @param compression - 物理编码(缺省 zstd)。
|
|
660
|
+
* @returns 该代次在会话目录内的文件名。
|
|
661
|
+
*/
|
|
662
|
+
declare function generationLogFilename(version: number, compression?: LogCompression): string;
|
|
663
|
+
/**
|
|
664
|
+
* 把一个规范日志名解析回代次。
|
|
665
|
+
*
|
|
666
|
+
* 与宿主 `parseGenerationLogFilename` 同语义:非规范名(临时、大写、前导零、
|
|
667
|
+
* `.v0`、别的压缩后缀)一律返回 undefined,**不猜**。
|
|
668
|
+
* @param filename - 会话目录里的一个文件名。
|
|
669
|
+
* @param compression - 该目录使用的物理编码(缺省 zstd)。
|
|
670
|
+
* @returns 其格式代次,或名字不构成规范代次时的 undefined。
|
|
671
|
+
*/
|
|
672
|
+
declare function parseGenerationLogFilename(filename: string, compression?: LogCompression): number | undefined;
|
|
673
|
+
/**
|
|
674
|
+
* 两种压缩编码都试一遍,判定该名字是不是某代的规范产物。
|
|
675
|
+
*
|
|
676
|
+
* 发现路径不能假设部署里的 `compression` 配置:配置在 profile 侧,插件读不到,
|
|
677
|
+
* 而日志就在磁盘上。因此按名字本身分类,编码作为结果一并带回。
|
|
678
|
+
* @param filename - 会话目录里的一个文件名。
|
|
679
|
+
* @returns 代次与编码,或该名字不是规范代次时的 undefined。
|
|
680
|
+
*/
|
|
681
|
+
declare function classifyGenerationFilename(filename: string): {
|
|
682
|
+
version: number;
|
|
683
|
+
compression: LogCompression;
|
|
684
|
+
} | undefined;
|
|
685
|
+
/**
|
|
686
|
+
* 该文件名是否是迁移暂存(当前代的发布源)。
|
|
687
|
+
* @param filename - 会话目录里的一个文件名。
|
|
688
|
+
* @returns 是否形如 `session.migration.<token>.jsonl[.zstd].tmp`。
|
|
689
|
+
*/
|
|
690
|
+
declare function isMigrationStagingFilename(filename: string): boolean;
|
|
691
|
+
/**
|
|
692
|
+
* 读取一个会话目录的代次事实(只读,不碰任何文件内容)。
|
|
693
|
+
* @param dir - 会话目录的绝对路径。
|
|
694
|
+
* @returns 规范产物(按代次升序)、当前代、历史代与暂存残留。
|
|
695
|
+
*/
|
|
696
|
+
declare function readSessionGenerations(dir: string): SessionGenerations;
|
|
697
|
+
/** 目录内全部已识别产物的最新 mtime。 */
|
|
698
|
+
declare function latestArtifactMtime(facts: SessionGenerations): number | undefined;
|
|
699
|
+
/**
|
|
700
|
+
* 该会话的处置优先级。
|
|
701
|
+
*
|
|
702
|
+
* `high` 的判据就是「从 TMP 移出来」本身:当前代次非 0(当前代是经
|
|
703
|
+
* `session.migration.*.tmp` 暂存发布出来的),或目录内仍有暂存残留。
|
|
704
|
+
* 代次 0 的历史代是宿主按契约保留的未发布会话,旧发现逻辑读的就是它 —— 这类
|
|
705
|
+
* 会话既没有发布痕迹、也没有被读错,故为 `normal`。
|
|
706
|
+
* @param facts - 会话目录的代次事实。
|
|
707
|
+
* @returns 处置优先级。
|
|
708
|
+
*/
|
|
709
|
+
declare function sessionPriority(facts: SessionGenerations): SessionPriority;
|
|
710
|
+
//#endregion
|
|
612
711
|
//#region src/host/health/gates.d.ts
|
|
613
712
|
/**
|
|
614
713
|
* gate 严重级。
|
|
@@ -636,7 +735,7 @@ interface GateAttribution {
|
|
|
636
735
|
}
|
|
637
736
|
/** 一个 gate 的结果。 */
|
|
638
737
|
interface GateResult {
|
|
639
|
-
id: 'log-integrity' | 'projection-cache' | 'lossless-json' | 'cold-read';
|
|
738
|
+
id: 'generation' | 'log-integrity' | 'projection-cache' | 'lossless-json' | 'cold-read' | 'source-kind';
|
|
640
739
|
level: GateLevel;
|
|
641
740
|
evidence: string;
|
|
642
741
|
attribution?: GateAttribution;
|
|
@@ -646,6 +745,12 @@ interface GateResult {
|
|
|
646
745
|
interface SessionHealthReport {
|
|
647
746
|
sessionId: string;
|
|
648
747
|
level: GateLevel;
|
|
748
|
+
/**
|
|
749
|
+
* 处置优先级:`high` = 该会话的当前代是从迁移暂存(TMP)发布出来的。
|
|
750
|
+
*
|
|
751
|
+
* 与 `level` 正交:优先级答「先看谁」,档位答「要不要处置」。
|
|
752
|
+
*/
|
|
753
|
+
priority: SessionPriority;
|
|
649
754
|
gates: GateResult[];
|
|
650
755
|
generatedAt: number;
|
|
651
756
|
}
|
|
@@ -658,6 +763,12 @@ interface GateContext {
|
|
|
658
763
|
logPath?: string;
|
|
659
764
|
/** 已解码的日志(复用,避免重复解码)。 */
|
|
660
765
|
log?: SessionLogRead;
|
|
766
|
+
/**
|
|
767
|
+
* 会话目录的代次事实(见 `generation.ts`)。
|
|
768
|
+
*
|
|
769
|
+
* 不提供时 `generation` 门记 `skipped`(无从判定),不猜、也不当作正常。
|
|
770
|
+
*/
|
|
771
|
+
generations?: SessionGenerations;
|
|
661
772
|
/** 热态:宿主 `sessionProjections.checkpoint(session)` 的逐行状态。 */
|
|
662
773
|
projectionState?: Record<string, unknown>;
|
|
663
774
|
/** 归属查询函数(投影 key → 包名)。 */
|
|
@@ -681,6 +792,22 @@ interface TailFacts {
|
|
|
681
792
|
}
|
|
682
793
|
/** 从解码事件推导尾部事实。 */
|
|
683
794
|
declare function readTailFacts(log: SessionLogRead): TailFacts;
|
|
795
|
+
/**
|
|
796
|
+
* gate 0:代次事实(当前代是历史代还是已发布代、有没有暂存残留)。
|
|
797
|
+
*
|
|
798
|
+
* 存在的理由:一个会话目录里可以有多份日志产物,而**读哪一份**决定了后面所有
|
|
799
|
+
* 门的结论。早期版本固定读 `session.jsonl.zstd`,于是对已发布当前代的会话要么
|
|
800
|
+
* 读错(读历史代那份,12MB 全量回放)、要么完全发现不了。本门把这个前提显式化成
|
|
801
|
+
* 可判定的证据,档位判据只取「有据可依」的三条:
|
|
802
|
+
* - 没有任何规范产物(只剩暂存)→ `fail`:当前代尚未发布;
|
|
803
|
+
* - 有暂存残留 → `warn`:发布源仍在原地(发布完成未清,或尚未发布);
|
|
804
|
+
* - 文件名代次与 header 代次不一致 → `warn`:发布不变量被破坏。
|
|
805
|
+
* 历史代与当前代并存是宿主**契约要求**(已提交代次不删不改),故记 `ok` 并写进
|
|
806
|
+
* 证据,不抬档 —— 抬档会把 34 个完全正常的会话变成噪声。
|
|
807
|
+
* @param facts - 会话目录的代次事实;缺省表示无从判定。
|
|
808
|
+
* @param log - 已解码的日志(用于取 header.version 交叉核对)。
|
|
809
|
+
*/
|
|
810
|
+
declare function gateGeneration(facts: SessionGenerations | undefined, log?: SessionLogRead): GateResult;
|
|
684
811
|
/** gate 1:日志完整性(可解码、seq 连续、无撕裂尾帧)。 */
|
|
685
812
|
declare function gateLogIntegrity(log: SessionLogRead): GateResult;
|
|
686
813
|
/** 投影缓存行的体检事实。 */
|
|
@@ -701,7 +828,7 @@ declare function gateProjectionCache(facts: ProjectionCacheFacts): GateResult;
|
|
|
701
828
|
declare function gateLosslessJson(projectionState: Record<string, unknown> | undefined, attribute?: (projection: string) => GateAttribution | undefined): GateResult;
|
|
702
829
|
/** gate 4:冷读成本与可接续性。 */
|
|
703
830
|
declare function gateColdRead(facts: TailFacts): GateResult;
|
|
704
|
-
/**
|
|
831
|
+
/** 聚合全部 gate 结果为一份报告。 */
|
|
705
832
|
declare function buildSessionReport(context: GateContext): SessionHealthReport;
|
|
706
833
|
//#endregion
|
|
707
834
|
//#region src/host/health/cache.d.ts
|
|
@@ -757,6 +884,8 @@ interface StewardHistoryRow {
|
|
|
757
884
|
bytes: number;
|
|
758
885
|
/** 投影缓存占用字节数。 */
|
|
759
886
|
cacheBytes: number;
|
|
887
|
+
/** 署名转换备份(`*.pre-sourcemigrate-<ts>`)占用字节数——`bytes` 的子集,单列防误读为日志体积。 */
|
|
888
|
+
backupBytes: number;
|
|
760
889
|
}
|
|
761
890
|
/** 列表结果。 */
|
|
762
891
|
interface StewardHistoryListResult {
|
|
@@ -818,13 +947,30 @@ interface StewardSessionUsage {
|
|
|
818
947
|
sessionId: string;
|
|
819
948
|
/** 转录目录绝对路径(不存在时缺省)。 */
|
|
820
949
|
dir?: string;
|
|
821
|
-
/**
|
|
950
|
+
/** 转录目录占用字节数(**含**署名转换备份;备份单列在 `backupBytes`)。 */
|
|
822
951
|
bytes: number;
|
|
952
|
+
/**
|
|
953
|
+
* 署名转换备份(`*.pre-sourcemigrate-<ts>`,见 `SOURCE_MIGRATE_BACKUP_SUFFIX`)
|
|
954
|
+
* 占用字节数 —— 是 `bytes` 的子集,单列出来免得被当作日志体积误读。
|
|
955
|
+
*/
|
|
956
|
+
backupBytes: number;
|
|
957
|
+
/** 备份文件个数。 */
|
|
958
|
+
backupCount: number;
|
|
823
959
|
/** 投影缓存文件绝对路径(不存在时缺省)。 */
|
|
824
960
|
cacheFile?: string;
|
|
825
961
|
/** 投影缓存占用字节数。 */
|
|
826
962
|
cacheBytes: number;
|
|
827
963
|
}
|
|
964
|
+
/** 是否署名转换备份文件(`*.pre-sourcemigrate-<ts>`)。 */
|
|
965
|
+
declare function isSourceMigrateBackupName(name: string): boolean;
|
|
966
|
+
/**
|
|
967
|
+
* 列出一个转录目录里的署名转换备份(只扫顶层:备份与日志同目录落盘)。
|
|
968
|
+
* @returns 备份绝对路径与合计字节数;目录不存在时为空。
|
|
969
|
+
*/
|
|
970
|
+
declare function backupFilesIn(dir: string): {
|
|
971
|
+
files: string[];
|
|
972
|
+
bytes: number;
|
|
973
|
+
};
|
|
828
974
|
/** 转录根目录(`<dshHome>/sessions`)。 */
|
|
829
975
|
declare function sessionsRootFor(dshHome: string): string;
|
|
830
976
|
/**
|
|
@@ -870,8 +1016,10 @@ interface StewardHistoryPurgeResult {
|
|
|
870
1016
|
ok: boolean;
|
|
871
1017
|
/** 成功清理的会话数。 */
|
|
872
1018
|
purged?: number;
|
|
873
|
-
/** 释放的字节数(转录 +
|
|
1019
|
+
/** 释放的字节数(转录 + 投影缓存;含随目录删除的署名转换备份)。 */
|
|
874
1020
|
freedBytes?: number;
|
|
1021
|
+
/** 一并删除的署名转换备份(`*.pre-sourcemigrate-<ts>`)个数。 */
|
|
1022
|
+
backupsRemoved?: number;
|
|
875
1023
|
/** 逐条失败原因;不阻断其余条目。 */
|
|
876
1024
|
failures?: {
|
|
877
1025
|
sessionId: string;
|
|
@@ -896,6 +1044,88 @@ interface StewardPurgeOptions {
|
|
|
896
1044
|
*/
|
|
897
1045
|
declare function purgeHistory(payload: unknown, log?: (msg: string) => void, options?: StewardPurgeOptions): StewardHistoryPurgeResult;
|
|
898
1046
|
//#endregion
|
|
1047
|
+
//#region src/host/health/source-kind.d.ts
|
|
1048
|
+
/** v4 线起点的宿主版本(会话格式 v4 引入 producer-owned source kind)。 */
|
|
1049
|
+
declare const V4_HOST_MIN = "0.1.7-rc.1";
|
|
1050
|
+
/** 一份日志里的旧署名事实。 */
|
|
1051
|
+
interface SourceKindFacts {
|
|
1052
|
+
/** 旧署名事件总数。 */
|
|
1053
|
+
legacyCount: number;
|
|
1054
|
+
/** 按生产者插件名统计。 */
|
|
1055
|
+
byPlugin: Record<string, number>;
|
|
1056
|
+
/** 命中样例(seq + 插件名),最多 5 条,供证据展示。 */
|
|
1057
|
+
examples: {
|
|
1058
|
+
seq: number;
|
|
1059
|
+
plugin: string;
|
|
1060
|
+
}[];
|
|
1061
|
+
/** 日志 header 的格式代次(无从读取时 undefined)。 */
|
|
1062
|
+
headerVersion?: number;
|
|
1063
|
+
}
|
|
1064
|
+
/** 从解码后的日志提取旧署名事实(只读)。 */
|
|
1065
|
+
declare function readSourceKindFacts(log: SessionLogRead): SourceKindFacts;
|
|
1066
|
+
/**
|
|
1067
|
+
* gate 5:插件署名格式(v4 线要求 producer-owned kind)。
|
|
1068
|
+
*
|
|
1069
|
+
* 档位判据(有据才抬档):
|
|
1070
|
+
* - header.version ≥ 4 且观测到旧署名行 → `warn`:v4 校验拒绝这种署名;存量行让
|
|
1071
|
+
* 未适配插件的读回判断(`kind === 'plugin' && plugin === name`)失配,转换可消除;
|
|
1072
|
+
* - header.version < 4 → `ok`:v3 及更早线旧行合法,宿主迁移负责,**不动**(防过度操作);
|
|
1073
|
+
* - header.version 无从读取 → `skipped`:无从判定该走哪条版本线。
|
|
1074
|
+
* @param facts - 旧署名事实;undefined 表示未提供(无日志)。
|
|
1075
|
+
*/
|
|
1076
|
+
declare function gateSourceKind(facts: SourceKindFacts | undefined): {
|
|
1077
|
+
id: 'source-kind';
|
|
1078
|
+
level: GateLevel;
|
|
1079
|
+
evidence: string;
|
|
1080
|
+
detail?: Record<string, unknown>;
|
|
1081
|
+
};
|
|
1082
|
+
/** 转换结果。 */
|
|
1083
|
+
interface SourceKindMigrationOutcome {
|
|
1084
|
+
ok: boolean;
|
|
1085
|
+
sessionId: string;
|
|
1086
|
+
/** 被改写的日志路径。 */
|
|
1087
|
+
path: string;
|
|
1088
|
+
/** 备份路径(改写前的完整副本;ok 且 changed 时必有)。 */
|
|
1089
|
+
backup?: string;
|
|
1090
|
+
/** 改写的行数。 */
|
|
1091
|
+
changedRows?: number;
|
|
1092
|
+
/** 按生产者插件名统计的改写行数。 */
|
|
1093
|
+
byPlugin?: Record<string, number>;
|
|
1094
|
+
/**
|
|
1095
|
+
* 按生产者名统计的**跳过**行数(第一方名,宿主迁移职权,见
|
|
1096
|
+
* `isFirstPartyLegacyProducer`)。跳过是如实上报,不是静默丢弃。
|
|
1097
|
+
*/
|
|
1098
|
+
skippedFirstParty?: Record<string, number>;
|
|
1099
|
+
error?: string;
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
* 从旧署名对象构造新署名:`{ kind: 'plugin', plugin: name, …rest }` → `{ kind: 'plugin:name', …rest }`。
|
|
1103
|
+
* 非 legacy(缺 plugin 字段 / kind 不符)返回 undefined,调用方跳过该行。
|
|
1104
|
+
*
|
|
1105
|
+
* ⚠️ 只对**第三方**生产者名成立(第四轮审计 ST1):宿主 `producerKind`
|
|
1106
|
+
* (dsh-session-format-v3-to-v4@0.1.7-rc.2 lib/index.js:88-96)对第一方名走改名表
|
|
1107
|
+
* 或同名裸 kind,本函数无条件加前缀会对那 30 个名字写出宿主永不产出的 kind。
|
|
1108
|
+
* 第一方名由 `FIRST_PARTY_RENAMED_PRODUCERS` / `FIRST_PARTY_SAME_NAME_PRODUCERS`
|
|
1109
|
+
* 判定,`migrateSessionSourceKind` 命中即跳过并如实上报(宿主迁移职权,不代转换)。
|
|
1110
|
+
*/
|
|
1111
|
+
declare function migrateLegacySource(source: unknown): Record<string, unknown> | undefined;
|
|
1112
|
+
/**
|
|
1113
|
+
* 转换一个会话日志里的旧署名行(v4 线专用;先备份,只动署名字段)。
|
|
1114
|
+
*
|
|
1115
|
+
* 执行闸(任一不满足即拒绝,不写盘):
|
|
1116
|
+
* 1. 日志可整体解码且无完整性问题(撕裂尾帧 / 解码失败 / seq 缺口);
|
|
1117
|
+
* 2. header.version ≥ 4(v3 及更早的旧行按契约由宿主迁移,不动);
|
|
1118
|
+
* 3. 确有旧署名行(没有则空手而归,不做无谓重压缩)。
|
|
1119
|
+
* @param sessionId - 会话 id(用于结果标注)。
|
|
1120
|
+
* @param logPath - 当前代日志路径(必须 .zstd 结尾)。
|
|
1121
|
+
* @param log - 已解码的日志(复用体检结果,闸 1/2 在其上判定)。
|
|
1122
|
+
* @param dshHome - DSH home(备份不依赖它,参数保留与其它处置一致的面)。
|
|
1123
|
+
* @param now - 时间源(备份后缀,测试可控)。
|
|
1124
|
+
*/
|
|
1125
|
+
declare function migrateSessionSourceKind(sessionId: string, logPath: string, log: SessionLogRead, dshHome?: string, now?: () => number): SourceKindMigrationOutcome;
|
|
1126
|
+
/** 备份文件的后缀约定(purge/清理工具可据此识别并一并处置)。 */
|
|
1127
|
+
declare const SOURCE_MIGRATE_BACKUP_SUFFIX = ".pre-sourcemigrate-";
|
|
1128
|
+
//#endregion
|
|
899
1129
|
//#region src/host/health/lossless.d.ts
|
|
900
1130
|
/**
|
|
901
1131
|
* 无损 JSON 判定 —— 本次事故的核心 gate 判据。
|
|
@@ -976,7 +1206,7 @@ declare function quarantineProjectionCache(sessionId: string, dshHome?: string,
|
|
|
976
1206
|
declare function prescribe(report: SessionHealthReport, dshHome?: string): string[];
|
|
977
1207
|
/** 处置结果的定性分类。 */
|
|
978
1208
|
type RepairVerdict =
|
|
979
|
-
/**
|
|
1209
|
+
/** 全部检查通过,没有要做的事。 */
|
|
980
1210
|
'nothing-to-do' |
|
|
981
1211
|
/** 处置生效且异常已消除。 */
|
|
982
1212
|
'repaired' |
|
|
@@ -1014,24 +1244,52 @@ declare function assessRepair(input: {
|
|
|
1014
1244
|
}): RepairAssessment;
|
|
1015
1245
|
//#endregion
|
|
1016
1246
|
//#region src/host/health/scan.d.ts
|
|
1017
|
-
/**
|
|
1247
|
+
/** 一个已发现的会话。 */
|
|
1018
1248
|
interface DiscoveredSession {
|
|
1019
1249
|
sessionId: string;
|
|
1020
|
-
|
|
1250
|
+
/** 承载日志的代次目录。 */
|
|
1251
|
+
dir: string;
|
|
1252
|
+
/**
|
|
1253
|
+
* 当前代日志路径。
|
|
1254
|
+
*
|
|
1255
|
+
* 目录内只有迁移暂存(尚未发布当前代)时为 undefined —— 该会话确实存在,
|
|
1256
|
+
* 但没有可读的规范产物,由 `generation` / `log-integrity` 两门如实报出,
|
|
1257
|
+
* 而不是当作「没有这个会话」。
|
|
1258
|
+
*/
|
|
1259
|
+
logPath?: string;
|
|
1260
|
+
/** 代次事实(当前代 / 历史代 / 暂存残留)。 */
|
|
1261
|
+
generations: SessionGenerations;
|
|
1262
|
+
/** 处置优先级:`high` = 当前代是从暂存(TMP)发布出来的。 */
|
|
1263
|
+
priority: SessionPriority;
|
|
1021
1264
|
updatedAt: number;
|
|
1022
1265
|
bytes: number;
|
|
1023
1266
|
}
|
|
1024
|
-
/**
|
|
1267
|
+
/**
|
|
1268
|
+
* 枚举全部会话(按 mtime 倒序),带可选上限。
|
|
1269
|
+
*
|
|
1270
|
+
* 「是会话目录」的判据是**目录里有规范代次产物或迁移暂存**,不要求任何具体文件名。
|
|
1271
|
+
* @param dshHome - DSH home(缺省 ~/.dsh)。
|
|
1272
|
+
* @param limit - 返回上限(缺省 `DISCOVERY_LIMIT`)。
|
|
1273
|
+
*/
|
|
1025
1274
|
declare function discoverSessions(dshHome?: string, limit?: number): DiscoveredSession[];
|
|
1026
1275
|
/**
|
|
1027
1276
|
* 语料总数:只做目录枚举,**不跑体检**。
|
|
1028
1277
|
*
|
|
1029
|
-
* 用于判断缓存是否已过期——枚举很便宜,而重扫要解 zstd
|
|
1278
|
+
* 用于判断缓存是否已过期——枚举很便宜,而重扫要解 zstd、跑门。
|
|
1030
1279
|
* 正因为两者代价差着量级,「对账」才不构成缓存失效策略本身。
|
|
1031
1280
|
* @param dshHome - DSH home(缺省 ~/.dsh)。
|
|
1032
1281
|
*/
|
|
1033
1282
|
declare function countCorpus(dshHome?: string): number;
|
|
1034
|
-
/**
|
|
1283
|
+
/** 按 id 定位一个会话(跨工程目录查找)。 */
|
|
1284
|
+
declare function findSession(sessionId: string, dshHome?: string): DiscoveredSession | undefined;
|
|
1285
|
+
/**
|
|
1286
|
+
* 定位一个会话的**当前代**日志路径(跨工程目录查找)。
|
|
1287
|
+
*
|
|
1288
|
+
* 返回 undefined 有两种含义,调用方必须区分:会话不存在,或会话存在但尚未发布
|
|
1289
|
+
* 当前代(只有迁移暂存)。需要区分时用 `findSession`。
|
|
1290
|
+
* @param sessionId - 会话 id。
|
|
1291
|
+
* @param dshHome - DSH home(缺省 ~/.dsh)。
|
|
1292
|
+
*/
|
|
1035
1293
|
declare function findSessionLog(sessionId: string, dshHome?: string): string | undefined;
|
|
1036
1294
|
/** 扫描结果。 */
|
|
1037
1295
|
interface HealthScanResult {
|
|
@@ -1056,6 +1314,9 @@ interface HealthScanResult {
|
|
|
1056
1314
|
* 语料先整体列出(按 mtime 倒序,≤ DISCOVERY_LIMIT),再按 `[offset, offset+limit)`
|
|
1057
1315
|
* 切片扫描。这样客户端可以用小批次连续调用、自己累计真实进度,而宿主保持无状态
|
|
1058
1316
|
* ——不必把同步循环改成异步,也不必新增进度轮询端点。
|
|
1317
|
+
*
|
|
1318
|
+
* 批内**命中顺序**按处置优先级排(`high` 在前,稳定排序)。分批切片仍按 mtime,
|
|
1319
|
+
* 所以 offset/total 的算术不受影响:只有同一批里的呈现顺序变了。
|
|
1059
1320
|
* @param options - dshHome / 批大小 / 批起点 / 是否只返回非 ok / 归属查询 / 热态状态提供者。
|
|
1060
1321
|
*/
|
|
1061
1322
|
declare function scanSessions(options: {
|
|
@@ -1071,6 +1332,16 @@ declare function scanSessions(options: {
|
|
|
1071
1332
|
//#region src/index.d.ts
|
|
1072
1333
|
/** 本插件声明的宿主服务(与 toggle 相同的注入面)。 */
|
|
1073
1334
|
declare const inject: string[];
|
|
1335
|
+
/** 运行时配置 schema(与 src/config.ts 的形状保持一致)。0.1.7:volatile 字段即设置表单。 */
|
|
1336
|
+
declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
1337
|
+
enabled: z<boolean, boolean, "volatile-defined">;
|
|
1338
|
+
historyFiles: z<boolean, boolean, "volatile-defined">;
|
|
1339
|
+
healthCheck: z<boolean, boolean, "volatile-defined">;
|
|
1340
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
1341
|
+
enabled: z<boolean, boolean, "volatile-defined">;
|
|
1342
|
+
historyFiles: z<boolean, boolean, "volatile-defined">;
|
|
1343
|
+
healthCheck: z<boolean, boolean, "volatile-defined">;
|
|
1344
|
+
}>>, "plain">;
|
|
1074
1345
|
/** 运行时依赖。 */
|
|
1075
1346
|
interface StewardRuntime {
|
|
1076
1347
|
config: () => Required<StewardConfig>;
|
|
@@ -1098,7 +1369,7 @@ interface StewardRuntime {
|
|
|
1098
1369
|
* prune = 取消归档状态(可逆,会话回到侧边栏);purge = 清理归档文件(不可逆,真删实体)。
|
|
1099
1370
|
*/
|
|
1100
1371
|
declare const HISTORY_METHODS: readonly ["session-history-list", "session-history-prune", "session-history-purge"];
|
|
1101
|
-
declare const HEALTH_METHODS: readonly ["session-health-status", "session-health-scan", "session-health-session", "session-health-repair"];
|
|
1372
|
+
declare const HEALTH_METHODS: readonly ["session-health-status", "session-health-scan", "session-health-session", "session-health-repair", "session-health-source-migrate"];
|
|
1102
1373
|
/** 依据开关判定某方法是否启用。 */
|
|
1103
1374
|
declare function methodEnabled(method: string, config: Required<StewardConfig>): boolean;
|
|
1104
1375
|
/**
|
|
@@ -1109,9 +1380,10 @@ declare function methodEnabled(method: string, config: Required<StewardConfig>):
|
|
|
1109
1380
|
*/
|
|
1110
1381
|
declare function handleMethod(method: string, payload: unknown, runtime: StewardRuntime): Promise<unknown>;
|
|
1111
1382
|
/**
|
|
1112
|
-
*
|
|
1113
|
-
* @param ctx - host 插件上下文(webServer / webRuntime / 可选
|
|
1383
|
+
* 插件主体:装配运行时、挂载 fenced 路由。
|
|
1384
|
+
* @param ctx - host 插件上下文(webServer / webRuntime / 可选 sessionQuery、sessions、sessionProjections)。
|
|
1385
|
+
* @param config - 组合条目(0.1.7:`.volatile()` 字段为 live ref)。
|
|
1114
1386
|
*/
|
|
1115
|
-
declare function apply(ctx: Context): void;
|
|
1387
|
+
declare function apply(ctx: Context, config?: Partial<StewardConfig>): void;
|
|
1116
1388
|
//#endregion
|
|
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 };
|
|
1389
|
+
export { Config, DEFAULT_CONFIG, type DiscoveredSession, type GenerationArtifact, HEALTH_METHODS, HISTORY_METHODS, HealthCache, type HealthCacheEntry, type LogArtifact, type LogCompression, type RepairAssessment, type RepairVerdict, SOURCE_MIGRATE_BACKUP_SUFFIX, STEWARD_API_PREFIX, STEWARD_SETTINGS_NAMESPACE, type SessionGenerations, type SessionPriority, type StewardConfig, StewardRuntime, V4_HOST_MIN, apply, assessRepair, backupFilesIn, buildProjectionOwnerIndex, buildSessionReport, classifyGenerationFilename, countCorpus, createAttributor, decodeSessionLogBytes, decodeSessionLogFile, dirSize, discoverSessions, editWorkspaceDocument, findSession, findSessionLog, firstLosslessViolation, gateColdRead, gateGeneration, gateLogIntegrity, gateLosslessJson, gateProjectionCache, gateSourceKind, generationLogFilename, handleMethod, indexSessionDirs, inject, isLossless, isMigrationStagingFilename, isSafeChild, isSourceMigrateBackupName, latestArtifactMtime, listHistory, locateSessionUsage, methodEnabled, migrateLegacySource, migrateSessionSourceKind, parseGenerationLogFilename, prescribe, projCacheRootFor, pruneArchiveFile, pruneHistory, purgeHistory, quarantineProjectionCache, readArchiveSet, readProjectionCache, readSessionGenerations, readSourceKindFacts, readTailFacts, scanSessions, scanZstdFrames, sessionPriority, sessionsRootFor };
|