@lmzhen/dsh-evolution-commands 0.7.0 → 0.9.0
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/lib/index.js +111 -63
- package/lib/types/params.d.ts +0 -6
- package/package.json +5 -5
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { effectiveSessionPolicy } from "@lmzhen/dsh-evolution-approval";
|
|
4
4
|
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
5
|
-
import { DEFAULT_SKILL_LIMITS, MAX_TIMER_DELAY_MS, PARAM_EXPOSURE, PARAM_NAMESPACES, appendEvolutionEvent, assertSkillsRootAliasRetired, buildLearnPrompt, canonicalWriteId, clampedNumber, composePresetComposition, eventsFile, evolutionRoot, isDeprecatedParamId, isMissingPath, newSkillLibrary, policyStageLimits, resolveParamId, resolveRootConfig, scopedProbeReport } from "@lmzhen/dsh-evolution-core";
|
|
5
|
+
import { DEFAULT_SKILL_LIMITS, MAX_TIMER_DELAY_MS, PARAM_EXPOSURE, PARAM_GROUP_LABELS, PARAM_NAMESPACES, appendEvolutionEvent, assertSkillsRootAliasRetired, buildLearnPrompt, canonicalWriteId, clampedNumber, composePresetComposition, errorText, eventsFile, evolutionRoot, isDeprecatedParamId, isMissingPath, newSkillLibrary, policyStageLimits, resolveParamId, resolveRootConfig, scopedProbeReport } from "@lmzhen/dsh-evolution-core";
|
|
6
6
|
import { buildEnrichment, buildMaintainFacts, runMaintain, snapshotFromLibrary } from "@lmzhen/dsh-evolution-maintenance";
|
|
7
7
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { dirname, join } from "node:path";
|
|
@@ -643,15 +643,46 @@ function renderValue(value) {
|
|
|
643
643
|
if (typeof value === "string") return value;
|
|
644
644
|
return JSON.stringify(value);
|
|
645
645
|
}
|
|
646
|
+
const WIDE_CHAR = new RegExp("[" + [
|
|
647
|
+
"ᄀ-ᅟ",
|
|
648
|
+
"⺀-〾",
|
|
649
|
+
"ぁ-㏿",
|
|
650
|
+
"㐀-䶿",
|
|
651
|
+
"一-鿿",
|
|
652
|
+
"가-힣",
|
|
653
|
+
"豈-",
|
|
654
|
+
"︰-",
|
|
655
|
+
"-⦆",
|
|
656
|
+
"¢-₩"
|
|
657
|
+
].join("") + "]");
|
|
646
658
|
/**
|
|
647
|
-
*
|
|
648
|
-
* @param
|
|
649
|
-
* @param
|
|
650
|
-
* @returns the
|
|
659
|
+
* Pad one cell to a display width, counting CJK characters as two columns.
|
|
660
|
+
* @param text - the cell text.
|
|
661
|
+
* @param columns - the target width in terminal columns.
|
|
662
|
+
* @returns the text plus at least one space, so columns never touch.
|
|
651
663
|
*/
|
|
664
|
+
function pad(text, columns) {
|
|
665
|
+
let used = 0;
|
|
666
|
+
for (const char of text) used += WIDE_CHAR.test(char) ? 2 : 1;
|
|
667
|
+
return text + " ".repeat(Math.max(1, columns - used));
|
|
668
|
+
}
|
|
669
|
+
/** Settings timing, in the operator's words. */
|
|
670
|
+
const APPLIES_LABELS = Object.freeze({
|
|
671
|
+
live: "立即",
|
|
672
|
+
restart: "重启后",
|
|
673
|
+
none: "不生效"
|
|
674
|
+
});
|
|
675
|
+
/** Where a row's effective value comes from, in the operator's words. */
|
|
676
|
+
const SOURCE_LABELS = Object.freeze({
|
|
677
|
+
user: "我改过",
|
|
678
|
+
deployment: "默认",
|
|
679
|
+
unregistered: "不可改"
|
|
680
|
+
});
|
|
681
|
+
/** What the E-tiers mean, so the count line reads without the docs. */
|
|
682
|
+
const TIER_LEGEND = "档位:E0 固定/E1 只读/E2 安装时定/E3 你可改/E4 装完固化。";
|
|
652
683
|
function renderParamRows(rows, options) {
|
|
653
|
-
const header = "
|
|
654
|
-
const body = rows.map((row) => row.id
|
|
684
|
+
const header = pad("参数", 36) + pad("分组", 12) + pad("档位", 6) + pad("生效", 8) + pad("来源", 10) + "当前值";
|
|
685
|
+
const body = rows.map((row) => pad(row.id, 36) + pad(PARAM_GROUP_LABELS[row.group], 12) + pad(row.tier, 6) + pad(APPLIES_LABELS[row.applies] ?? row.applies, 8) + pad(SOURCE_LABELS[row.source] ?? row.source, 10) + renderValue(row.value));
|
|
655
686
|
const tiers = [
|
|
656
687
|
"E0",
|
|
657
688
|
"E1",
|
|
@@ -660,13 +691,14 @@ function renderParamRows(rows, options) {
|
|
|
660
691
|
"E4"
|
|
661
692
|
].map((tier) => `${tier} ${rows.filter((row) => row.tier === tier).length}`).join(" / ");
|
|
662
693
|
const userRows = rows.filter((row) => row.source === "user").length;
|
|
663
|
-
const
|
|
664
|
-
const note = options.providerMounted ? "
|
|
694
|
+
const counts = options.providerMounted ? `共 ${rows.length} 个参数:${tiers};你改过的:${userRows} 项。` : `共 ${rows.length} 个参数:${tiers};是否改过:未知(没有设置服务)。`;
|
|
695
|
+
const note = options.providerMounted ? "来源:我改过=你在设置里改的;默认=安装时的配置;不可改=该功能不提供用户可改项。" : "设置服务未挂载——读不到你改过的值,所以每行显示的都是安装时的配置(这不等于「你没改过」)。";
|
|
665
696
|
return [
|
|
666
697
|
header,
|
|
667
698
|
...body,
|
|
668
699
|
"",
|
|
669
|
-
|
|
700
|
+
counts,
|
|
701
|
+
TIER_LEGEND,
|
|
670
702
|
note
|
|
671
703
|
].join("\n");
|
|
672
704
|
}
|
|
@@ -709,79 +741,79 @@ function renderParamJson(rows) {
|
|
|
709
741
|
const COMMAND_ENTRIES = [
|
|
710
742
|
{
|
|
711
743
|
usage: "pending [--detail]",
|
|
712
|
-
summary: "
|
|
744
|
+
summary: "列出暂存的写入(--detail 显示参数)"
|
|
713
745
|
},
|
|
714
746
|
{
|
|
715
747
|
usage: "approve <id>",
|
|
716
|
-
summary: "
|
|
748
|
+
summary: "执行一条已批准的写入"
|
|
717
749
|
},
|
|
718
750
|
{
|
|
719
751
|
usage: "reject <id>",
|
|
720
|
-
summary: "
|
|
752
|
+
summary: "丢弃一条暂存写入,不执行"
|
|
721
753
|
},
|
|
722
754
|
{
|
|
723
755
|
usage: "release <id>",
|
|
724
|
-
summary: "
|
|
756
|
+
summary: "把卡在执行中的写入放回待批窗口(先确认效果再批准 or reject)"
|
|
725
757
|
},
|
|
726
758
|
{
|
|
727
759
|
usage: "doctor [--json]",
|
|
728
|
-
summary: "
|
|
760
|
+
summary: "只读自检:安装形态、冲突、环境、服务(--json 供脚本用)"
|
|
729
761
|
},
|
|
730
762
|
{
|
|
731
763
|
usage: "curator run|pause|resume|status|report|scope",
|
|
732
|
-
summary: "
|
|
764
|
+
summary: "立即运行一次自动整理,或暂停/恢复/查看状态"
|
|
733
765
|
},
|
|
734
766
|
{
|
|
735
767
|
usage: "mutations",
|
|
736
|
-
summary: "
|
|
768
|
+
summary: "列出技能改动记录"
|
|
737
769
|
},
|
|
738
770
|
{
|
|
739
771
|
usage: "restore",
|
|
740
|
-
summary: "
|
|
772
|
+
summary: "从最近的快照恢复技能"
|
|
741
773
|
},
|
|
742
774
|
{
|
|
743
775
|
usage: "consolidate <target> <sources...> [--plan <runId>]",
|
|
744
|
-
summary: "
|
|
776
|
+
summary: "把若干技能合并进一个总括技能"
|
|
745
777
|
},
|
|
746
778
|
{
|
|
747
779
|
usage: "skill restore <name>",
|
|
748
|
-
summary: "
|
|
780
|
+
summary: "按名字恢复一个已归档的技能"
|
|
749
781
|
},
|
|
750
782
|
{
|
|
751
783
|
usage: "skills health",
|
|
752
|
-
summary: "
|
|
784
|
+
summary: "技能库结构体检"
|
|
753
785
|
},
|
|
754
786
|
{
|
|
755
787
|
usage: "skills refresh",
|
|
756
|
-
summary: "
|
|
788
|
+
summary: "丢弃目录缓存并重新读取技能树"
|
|
757
789
|
},
|
|
758
790
|
{
|
|
759
791
|
usage: "learn [request]",
|
|
760
|
-
summary: "
|
|
792
|
+
summary: "向本会话发一条学习请求"
|
|
761
793
|
},
|
|
762
794
|
{
|
|
763
795
|
usage: "maintain [--timeout=<ms> | --facts]",
|
|
764
|
-
summary: "
|
|
796
|
+
summary: "运行一次维护扫描(--facts 为 0 token 预览)"
|
|
765
797
|
},
|
|
766
798
|
{
|
|
767
799
|
usage: "policy set <id> <value> [--expect <revision>]",
|
|
768
|
-
summary: "
|
|
800
|
+
summary: "通过设置服务写入一个你可改的参数 (E3 only; E1/E2 stay in cordis.yml)"
|
|
769
801
|
},
|
|
770
802
|
{
|
|
771
803
|
usage: "params [--group <name>] [--json]",
|
|
772
|
-
summary: "
|
|
804
|
+
summary: "列出全部参数:分组、档位、生效时机、来源与当前值(--json feeds scripts)"
|
|
773
805
|
},
|
|
774
806
|
{
|
|
775
807
|
usage: "preset install [--base <name>[,<name>...]]",
|
|
776
|
-
summary: "
|
|
808
|
+
summary: "按指定基础生成自进化 Agent 预设到用户 root (bases from the agent package's bases.json)"
|
|
777
809
|
},
|
|
778
810
|
{
|
|
779
811
|
usage: "restructure <name> \"<heading>\" <to_file> [--plan <runId>]",
|
|
780
|
-
summary: "
|
|
812
|
+
summary: "把技能正文的一节移到 references 文件"
|
|
781
813
|
},
|
|
782
814
|
{
|
|
783
815
|
usage: "replay",
|
|
784
|
-
summary: "
|
|
816
|
+
summary: "比较不同会话与重启之间的计划结果(从活动记录回填)"
|
|
785
817
|
}
|
|
786
818
|
];
|
|
787
819
|
/** The input-declaration hint (single line, ` | `-separated). */
|
|
@@ -818,7 +850,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
818
850
|
const commands = commandCtx.commands;
|
|
819
851
|
const evolutionCommand = {
|
|
820
852
|
name: "evolution",
|
|
821
|
-
description: "
|
|
853
|
+
description: "自进化:状态与待批准写入",
|
|
822
854
|
recordInput: false,
|
|
823
855
|
input: { hint: renderHint() },
|
|
824
856
|
run: async (invocation) => {
|
|
@@ -833,18 +865,18 @@ function apply(ctx, rawConfig = {}) {
|
|
|
833
865
|
text
|
|
834
866
|
});
|
|
835
867
|
const invocationAgent = invocation.agent;
|
|
836
|
-
const agentMissing = (need) => invocationAgent === void 0 ? err(
|
|
868
|
+
const agentMissing = (need) => invocationAgent === void 0 ? err(errorText("e-305-this-invocation-carries-no", { a1: need })) : void 0;
|
|
837
869
|
const unreplayableWriteRefusal = (what) => {
|
|
838
870
|
if (approval === void 0) return void 0;
|
|
839
871
|
const session = invocationAgent?.session;
|
|
840
872
|
const sessionPolicy = effectiveSessionPolicy(ctx, session);
|
|
841
873
|
if (!(approval.isEnabled !== false && sessionPolicy !== "never" && approval.stageForeground !== false)) return void 0;
|
|
842
|
-
return err(
|
|
874
|
+
return err(errorText("e-306-this-deployment-stages-foreground", { a1: what }));
|
|
843
875
|
};
|
|
844
876
|
const approval = ctx.get("evolutionApproval");
|
|
845
877
|
const pendingMatch = /^pending(?: --detail)?$/.exec(input);
|
|
846
878
|
if (pendingMatch) {
|
|
847
|
-
if (!approval) return err("
|
|
879
|
+
if (!approval) return err(errorText("e-301-approval-service-not-mounted"));
|
|
848
880
|
const listed = [...await approval.list("pending"), ...await approval.list("executing")];
|
|
849
881
|
const pending = [...new Map(listed.map((row) => [row.id, row])).values()];
|
|
850
882
|
if (pending.length === 0) return ok("No pending evolution writes.");
|
|
@@ -860,7 +892,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
860
892
|
const id = input.slice(8).trim();
|
|
861
893
|
const result = approval ? await approval.approve(id) : {
|
|
862
894
|
ok: false,
|
|
863
|
-
message: "
|
|
895
|
+
message: errorText("e-301-approval-service-not-mounted-2")
|
|
864
896
|
};
|
|
865
897
|
return result.ok ? ok(result.message) : err(result.message);
|
|
866
898
|
}
|
|
@@ -868,27 +900,27 @@ function apply(ctx, rawConfig = {}) {
|
|
|
868
900
|
const id = input.slice(7).trim();
|
|
869
901
|
const result = approval ? await approval.reject(id) : {
|
|
870
902
|
ok: false,
|
|
871
|
-
message: "
|
|
903
|
+
message: errorText("e-301-approval-service-not-mounted-2")
|
|
872
904
|
};
|
|
873
905
|
return result.ok ? ok(result.message) : err(result.message);
|
|
874
906
|
}
|
|
875
907
|
if (input.startsWith("release ")) {
|
|
876
908
|
const id = input.slice(8).trim();
|
|
877
|
-
if (!approval) return err("
|
|
878
|
-
if (!approval.release) return err("
|
|
909
|
+
if (!approval) return err(errorText("e-301-approval-service-not-mounted-2"));
|
|
910
|
+
if (!approval.release) return err(errorText("e-304-the-mounted-approval-service"));
|
|
879
911
|
const result = await approval.release(id);
|
|
880
912
|
return result.ok ? ok(result.message) : err(result.message);
|
|
881
913
|
}
|
|
882
914
|
if (input === "curator run") {
|
|
883
915
|
const curator = ctx.get("evolutionCurator");
|
|
884
|
-
if (!curator) return err("
|
|
916
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
885
917
|
const result = await curator.run({ ignoreGates: true });
|
|
886
918
|
if (result.skipped !== void 0) return ok(`Curator run skipped (${result.skipped}): no curation pass was executed.\nrunId=${result.report.runId}`);
|
|
887
919
|
return ok(`Curator run complete: ${result.stale.length} stale, ${result.archived.length} archived, ${result.errors.length} failed.\nrunId=${result.report.runId}${result.report.snapshotPath ? `\nsnapshot=${result.report.snapshotPath}` : ""}`);
|
|
888
920
|
}
|
|
889
921
|
if (input === "curator pause" || input === "curator resume") {
|
|
890
922
|
const curator = ctx.get("evolutionCurator");
|
|
891
|
-
if (!curator) return err("
|
|
923
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
892
924
|
const paused = input === "curator pause";
|
|
893
925
|
await curator.setPaused(paused);
|
|
894
926
|
const notPersisted = ctx.get("evolutionState") !== void 0 ? "" : "\nNOTE: no evolution state service is mounted — this setting is NOT persisted and will not survive this process.";
|
|
@@ -896,7 +928,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
896
928
|
}
|
|
897
929
|
if (input === "curator status") {
|
|
898
930
|
const curator = ctx.get("evolutionCurator");
|
|
899
|
-
if (!curator) return err("
|
|
931
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
900
932
|
const state = await curator.status();
|
|
901
933
|
if (!state) return ok("No curator state yet: the first automatic pass is deferred until the interval elapses.");
|
|
902
934
|
const lastRun = typeof state.lastRunAt === "number" && Number.isFinite(state.lastRunAt) && state.lastRunAt > 0 ? new Date(state.lastRunAt).toISOString() : "unknown";
|
|
@@ -909,7 +941,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
909
941
|
}
|
|
910
942
|
if (input === "mutations") {
|
|
911
943
|
const curator = ctx.get("evolutionCurator");
|
|
912
|
-
if (!curator) return err("
|
|
944
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
913
945
|
const records = await curator.skills.listMutations();
|
|
914
946
|
const usable = Array.isArray(records) ? records.filter((row) => typeof row === "object" && row !== null && typeof row.at === "string" && typeof row.skillName === "string" && typeof row.action === "string" && typeof row.summary === "string") : [];
|
|
915
947
|
if (usable.length === 0) return ok("No mutation records yet.");
|
|
@@ -918,7 +950,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
918
950
|
}
|
|
919
951
|
if (input === "curator scope") {
|
|
920
952
|
const curator = ctx.get("evolutionCurator");
|
|
921
|
-
if (!curator) return err("
|
|
953
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
922
954
|
const view = await curator.scopeView();
|
|
923
955
|
const line = (label, names) => `${label}: ${names.length}${names.length === 0 ? "" : `\n ${names.join(", ")}`}`;
|
|
924
956
|
return ok([
|
|
@@ -932,7 +964,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
932
964
|
}
|
|
933
965
|
if (input === "curator report") {
|
|
934
966
|
const curator = ctx.get("evolutionCurator");
|
|
935
|
-
if (!curator) return err("
|
|
967
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
936
968
|
const report = await curator.latestReport();
|
|
937
969
|
if (!report) return ok("No curator report available.");
|
|
938
970
|
if (typeof report !== "object" || typeof report.runId !== "string" || typeof report.startedAt !== "string" || !Array.isArray(report.archived) || !Array.isArray(report.failed)) return err("Report file unreadable.");
|
|
@@ -958,7 +990,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
958
990
|
const curator = ctx.get("evolutionCurator");
|
|
959
991
|
const result = curator ? await curator.restoreSnapshot() : {
|
|
960
992
|
ok: false,
|
|
961
|
-
message: "
|
|
993
|
+
message: errorText("e-302-curator-service-not-mounted")
|
|
962
994
|
};
|
|
963
995
|
return result.ok ? ok(result.message) : err(result.message);
|
|
964
996
|
}
|
|
@@ -972,7 +1004,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
972
1004
|
const curator = ctx.get("evolutionCurator");
|
|
973
1005
|
const result = curator ? await curator.consolidate(target, sources) : {
|
|
974
1006
|
ok: false,
|
|
975
|
-
message: "
|
|
1007
|
+
message: errorText("e-302-curator-service-not-mounted")
|
|
976
1008
|
};
|
|
977
1009
|
if (!result.ok) return err(result.message);
|
|
978
1010
|
return ok(planRunId ? `${result.message}\n[audit] plan=${planRunId}` : result.message);
|
|
@@ -985,13 +1017,13 @@ function apply(ctx, rawConfig = {}) {
|
|
|
985
1017
|
const curator = ctx.get("evolutionCurator");
|
|
986
1018
|
const result = curator ? await curator.restore(name) : {
|
|
987
1019
|
ok: false,
|
|
988
|
-
message: "
|
|
1020
|
+
message: errorText("e-302-curator-service-not-mounted")
|
|
989
1021
|
};
|
|
990
1022
|
return result.ok ? ok(result.message) : err(result.message);
|
|
991
1023
|
}
|
|
992
1024
|
if (input === "skills health") {
|
|
993
1025
|
const curator = ctx.get("evolutionCurator");
|
|
994
|
-
if (!curator) return err("
|
|
1026
|
+
if (!curator) return err(errorText("e-302-curator-service-not-mounted"));
|
|
995
1027
|
const [rows, observed] = await Promise.all([curator.healthView(), curator.usageObserved()]);
|
|
996
1028
|
const banner = observed ? "" : "Usage observation not yet established — churn (write-ghost) rows are suppressed.";
|
|
997
1029
|
const line = (row) => `${row.verdict.padEnd(18)} ${row.name}${row.reasons.length > 0 ? ` — ${row.reasons.join("; ")}` : ""}`;
|
|
@@ -1024,7 +1056,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
1024
1056
|
agent.followup(message);
|
|
1025
1057
|
woke = true;
|
|
1026
1058
|
} else if (typeof agent.inject === "function") agent.inject(message);
|
|
1027
|
-
else return err("
|
|
1059
|
+
else return err(errorText("e-305-the-invocation-agent-exposes"));
|
|
1028
1060
|
const eventIo = ctx.get("evolutionIo")?.provider();
|
|
1029
1061
|
if (eventIo) appendEvolutionEvent(eventIo, eventsFile(evolutionRoot()), {
|
|
1030
1062
|
type: "learn",
|
|
@@ -1203,7 +1235,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
1203
1235
|
const session = invocationAgent?.session;
|
|
1204
1236
|
const sessionPolicy = effectiveSessionPolicy(ctx, session);
|
|
1205
1237
|
const stagesForeground = approval.isEnabled !== false && sessionPolicy !== "never" && approval.stageForeground !== false;
|
|
1206
|
-
if (stagesForeground && session === void 0) return err("
|
|
1238
|
+
if (stagesForeground && session === void 0) return err(errorText("e-306-this-deployment-stages-foreground-2"));
|
|
1207
1239
|
if (stagesForeground && !approval.hasRunner("skill")) return err("Restructure cannot be staged: no skill replay runner is registered — mount the tool-skill-manage row (evolution-agent preset, or evolution-all) or disable evolution-approval.");
|
|
1208
1240
|
const decision = await approval.request({
|
|
1209
1241
|
kind: "skill",
|
|
@@ -1248,7 +1280,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
1248
1280
|
}
|
|
1249
1281
|
if (input === "replay") {
|
|
1250
1282
|
const replay = ctx.get("evolutionReplay");
|
|
1251
|
-
if (!replay) return err("
|
|
1283
|
+
if (!replay) return err(errorText("e-303-replay-service-not-mounted"));
|
|
1252
1284
|
return ok(replay.compare().report);
|
|
1253
1285
|
}
|
|
1254
1286
|
const paramsMatch = /^params(?: --group ([a-z-]+))?(?: --json)?$/.exec(input);
|
|
@@ -1264,52 +1296,68 @@ function apply(ctx, rawConfig = {}) {
|
|
|
1264
1296
|
sections.set(descriptor.ns, section);
|
|
1265
1297
|
}
|
|
1266
1298
|
} catch (error) {
|
|
1267
|
-
return err(
|
|
1299
|
+
return err(errorText("e-307-the-settings-service-could", { a1: error instanceof Error ? error.message : String(error) }));
|
|
1268
1300
|
}
|
|
1269
1301
|
const rows = paramSurfaceRows(sections, PARAM_EXPOSURE);
|
|
1270
1302
|
const group = paramsMatch[1];
|
|
1271
1303
|
const selected = group === void 0 ? rows : rows.filter((row) => row.group === group);
|
|
1272
|
-
if (group !== void 0 && selected.length === 0) return err(
|
|
1304
|
+
if (group !== void 0 && selected.length === 0) return err(errorText("e-308-unknown-parameter-group-group", {
|
|
1305
|
+
a1: group,
|
|
1306
|
+
a2: paramGroups(PARAM_EXPOSURE).join(", ")
|
|
1307
|
+
}));
|
|
1273
1308
|
if (input.endsWith("--json")) return ok(renderParamJson(selected));
|
|
1274
1309
|
return ok(renderParamRows(selected, { providerMounted: provider !== void 0 }));
|
|
1275
1310
|
}
|
|
1276
1311
|
const policySetMatch = /^policy set ([A-Za-z][A-Za-z0-9.-]*) (.+?)(?: --expect (\d+))?$/.exec(input);
|
|
1277
1312
|
if (policySetMatch) {
|
|
1278
1313
|
const provider = ctx.get("settings");
|
|
1279
|
-
if (provider?.update === void 0 || provider.describe === void 0) return err("
|
|
1314
|
+
if (provider?.update === void 0 || provider.describe === void 0) return err(errorText("e-311-no-settings-service-is"));
|
|
1280
1315
|
const rawId = policySetMatch[1] ?? "";
|
|
1281
1316
|
const rawValue = policySetMatch[2] ?? "";
|
|
1282
1317
|
let id;
|
|
1283
1318
|
try {
|
|
1284
1319
|
id = canonicalWriteId(rawId);
|
|
1285
1320
|
} catch (error) {
|
|
1286
|
-
return err(
|
|
1321
|
+
return err(errorText("e-312-error-instanceof-Error-error", { a1: error instanceof Error ? error.message : String(error) }));
|
|
1287
1322
|
}
|
|
1288
1323
|
const entry = PARAM_EXPOSURE.find((candidate) => candidate.id === id);
|
|
1289
|
-
if (entry === void 0) return err(
|
|
1290
|
-
if (entry.tier !== "E3") return err(
|
|
1324
|
+
if (entry === void 0) return err(errorText("e-313-unknown-parameter-id-evolution", { a1: id }));
|
|
1325
|
+
if (entry.tier !== "E3") return err(errorText("e-314-id-is-a-deployment", {
|
|
1326
|
+
a1: id,
|
|
1327
|
+
a2: entry.tier,
|
|
1328
|
+
a3: entry.owner
|
|
1329
|
+
}));
|
|
1291
1330
|
const namespace = PARAM_NAMESPACES[entry.owner];
|
|
1292
|
-
if (namespace === void 0) return err(
|
|
1331
|
+
if (namespace === void 0) return err(errorText("e-315-id-has-no-user", {
|
|
1332
|
+
a1: id,
|
|
1333
|
+
a2: entry.owner
|
|
1334
|
+
}));
|
|
1293
1335
|
let descriptor;
|
|
1294
1336
|
try {
|
|
1295
1337
|
descriptor = provider.describe({ redactSecrets: false }).find((candidate) => candidate.ns === namespace);
|
|
1296
1338
|
} catch (error) {
|
|
1297
|
-
return err(
|
|
1339
|
+
return err(errorText("e-307-the-settings-service-could-2", { a1: error instanceof Error ? error.message : String(error) }));
|
|
1298
1340
|
}
|
|
1299
|
-
if (descriptor === void 0) return err(
|
|
1341
|
+
if (descriptor === void 0) return err(errorText("e-316-namespace-namespace-is-not", {
|
|
1342
|
+
a1: namespace,
|
|
1343
|
+
a2: entry.owner
|
|
1344
|
+
}));
|
|
1300
1345
|
const current = descriptor.value;
|
|
1301
1346
|
const resolved = typeof current === "object" && current !== null ? current : void 0;
|
|
1302
1347
|
const expectedRaw = policySetMatch[3];
|
|
1303
1348
|
const expected = expectedRaw === void 0 ? descriptor.revision : Number(expectedRaw);
|
|
1304
|
-
if (expectedRaw !== void 0 && descriptor.revision !== void 0 && Number(expectedRaw) !== descriptor.revision) return err(
|
|
1349
|
+
if (expectedRaw !== void 0 && descriptor.revision !== void 0 && Number(expectedRaw) !== descriptor.revision) return err(errorText("e-309-revision-conflict-you-sent", {
|
|
1350
|
+
a1: expectedRaw,
|
|
1351
|
+
a2: descriptor.revision
|
|
1352
|
+
}));
|
|
1305
1353
|
const value = parseParamValue(rawValue);
|
|
1306
1354
|
try {
|
|
1307
1355
|
await provider.update(namespace, { [id]: value }, expected);
|
|
1308
1356
|
} catch (error) {
|
|
1309
1357
|
const code = error?.code;
|
|
1310
1358
|
const message = error instanceof Error ? error.message : String(error);
|
|
1311
|
-
if (code === "SETTINGS_CONFLICT") return err(
|
|
1312
|
-
return err(
|
|
1359
|
+
if (code === "SETTINGS_CONFLICT") return err(errorText("e-309-revision-conflict-message-Re", { a1: message }));
|
|
1360
|
+
return err(errorText("e-310-the-settings-service-refused", { a1: message }));
|
|
1313
1361
|
}
|
|
1314
1362
|
return ok(renderPolicySet({
|
|
1315
1363
|
id,
|
|
@@ -1325,7 +1373,7 @@ function apply(ctx, rawConfig = {}) {
|
|
|
1325
1373
|
if (input === "doctor --json") return ok(JSON.stringify(report, null, 2));
|
|
1326
1374
|
return ok(renderDoctorText(report));
|
|
1327
1375
|
}
|
|
1328
|
-
return ok(
|
|
1376
|
+
return ok(`自进化:记忆、技能、会话回顾、技能整理——状态、待批准写入与维护。\n${renderHelpText()}`);
|
|
1329
1377
|
},
|
|
1330
1378
|
handler: (invocation) => evolutionCommand.run(invocation).catch((error) => ({
|
|
1331
1379
|
kind: "error",
|
package/lib/types/params.d.ts
CHANGED
|
@@ -52,12 +52,6 @@ export declare function paramSurfaceRows(sections: ReadonlyMap<string, ParamSect
|
|
|
52
52
|
* @returns distinct group names.
|
|
53
53
|
*/
|
|
54
54
|
export declare function paramGroups(entries?: readonly ParamExposure[]): string[];
|
|
55
|
-
/**
|
|
56
|
-
* Render the rows as fixed-width text (one parameter per line, never truncated).
|
|
57
|
-
* @param rows - rows from {@link paramSurfaceRows}.
|
|
58
|
-
* @param options - whether the settings service answered at all.
|
|
59
|
-
* @returns the command text.
|
|
60
|
-
*/
|
|
61
55
|
export declare function renderParamRows(rows: readonly ParamSurfaceRow[], options: {
|
|
62
56
|
providerMounted: boolean;
|
|
63
57
|
}): string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lmzhen/dsh-evolution-commands",
|
|
3
3
|
"description": "Human commands for the evolution family (/evolution pending|curator|maintain|doctor) (community build)",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
30
|
-
"@lmzhen/dsh-evolution-approval": "^0.
|
|
31
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
32
|
-
"@lmzhen/dsh-evolution-maintenance": "^0.
|
|
30
|
+
"@lmzhen/dsh-evolution-approval": "^0.9.0",
|
|
31
|
+
"@lmzhen/dsh-evolution-core": "^0.9.0",
|
|
32
|
+
"@lmzhen/dsh-evolution-maintenance": "^0.9.0"
|
|
33
33
|
},
|
|
34
34
|
"optionalDependencies": {
|
|
35
|
-
"@lmzhen/dsh-evolution-agent-preset": "^0.
|
|
35
|
+
"@lmzhen/dsh-evolution-agent-preset": "^0.9.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@deepseek-ai/cordis": "^4.0.1",
|