@dsh-plus/agent-preset-rea 0.1.1 → 0.1.2
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/client.js +363 -105
- package/lib/index.d.ts +127 -20
- package/lib/index.js +510 -196
- package/package.json +2 -2
- package/src/client/api.ts +7 -6
- package/src/client/card.tsx +8 -4
- package/src/client/client.ts +2 -2
- package/src/client/draft.ts +21 -2
- package/src/client/i18n.ts +42 -2
- package/src/client/install.tsx +157 -58
- package/src/client/toggles.tsx +57 -0
- package/src/config.ts +34 -5
- package/src/definition.ts +6 -6
- package/src/dto.ts +29 -3
- package/src/exec.ts +34 -12
- package/src/index.ts +21 -1
- package/src/manager.ts +14 -9
- package/src/reverse.ts +335 -0
- package/src/routes.ts +108 -66
- package/src/skill.ts +23 -8
package/lib/client.js
CHANGED
|
@@ -54,6 +54,29 @@ window.__ModuleLoader__.load({
|
|
|
54
54
|
]
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* 勾选行:自绘圆角扁平开关(switch),对齐官方 WebUI 无原生 checkbox 的
|
|
59
|
+
* 设计语言(官方选择类控件全走胶囊/菜单,见 cardCss 的 -switch 规则)。
|
|
60
|
+
* 语义保持 checkbox(无障碍树与表单语义不变),视觉自绘。
|
|
61
|
+
*/
|
|
62
|
+
function CheckRow(props) {
|
|
63
|
+
const p = props.prefix ?? "dshp";
|
|
64
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
65
|
+
className: `${p}-checkRow`,
|
|
66
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
67
|
+
id: props.id,
|
|
68
|
+
type: "checkbox",
|
|
69
|
+
role: "switch",
|
|
70
|
+
"aria-checked": props.checked,
|
|
71
|
+
checked: props.checked,
|
|
72
|
+
disabled: props.disabled === true,
|
|
73
|
+
onChange: (event) => props.onEdit(event.target.checked)
|
|
74
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
75
|
+
htmlFor: props.id,
|
|
76
|
+
children: props.label
|
|
77
|
+
})]
|
|
78
|
+
});
|
|
79
|
+
}
|
|
57
80
|
//#endregion
|
|
58
81
|
//#region ../shared/src/client/card.tsx
|
|
59
82
|
const IDLE_STATUS = {
|
|
@@ -490,11 +513,20 @@ ${extra}
|
|
|
490
513
|
* @module @dsh-plus/agent-preset-rea/ns
|
|
491
514
|
*/
|
|
492
515
|
const SETTINGS_NS = "dsh-plus-agent-preset-rea";
|
|
516
|
+
//#endregion
|
|
517
|
+
//#region src/client/draft.ts
|
|
518
|
+
/** 布尔字段收窄(缺席或类型不符回落默认值)。 */
|
|
519
|
+
function boolOf(value, fallback) {
|
|
520
|
+
return typeof value === "boolean" ? value : fallback;
|
|
521
|
+
}
|
|
493
522
|
/** 解析值 → 草稿(类型不符一律回落默认)。 */
|
|
494
523
|
function draftFromValue(value) {
|
|
495
524
|
return {
|
|
496
525
|
personaPrefix: typeof value.personaPrefix === "string" ? value.personaPrefix : "",
|
|
497
|
-
proxyPort: typeof value.proxyPort === "number" ? String(value.proxyPort) : ""
|
|
526
|
+
proxyPort: typeof value.proxyPort === "number" ? String(value.proxyPort) : "",
|
|
527
|
+
mcpEnabled: boolOf(value.mcpEnabled, true),
|
|
528
|
+
skillEnabled: boolOf(value.skillEnabled, true),
|
|
529
|
+
reverseSkillEnabled: boolOf(value.reverseSkillEnabled, true)
|
|
498
530
|
};
|
|
499
531
|
}
|
|
500
532
|
/**
|
|
@@ -512,7 +544,10 @@ ${extra}
|
|
|
512
544
|
function toPatch(draft) {
|
|
513
545
|
return {
|
|
514
546
|
personaPrefix: draft.personaPrefix,
|
|
515
|
-
proxyPort: parseProxyPort(draft.proxyPort) ?? 0
|
|
547
|
+
proxyPort: parseProxyPort(draft.proxyPort) ?? 0,
|
|
548
|
+
mcpEnabled: draft.mcpEnabled,
|
|
549
|
+
skillEnabled: draft.skillEnabled,
|
|
550
|
+
reverseSkillEnabled: draft.reverseSkillEnabled
|
|
516
551
|
};
|
|
517
552
|
}
|
|
518
553
|
//#endregion
|
|
@@ -538,7 +573,8 @@ ${extra}
|
|
|
538
573
|
const install = body["install"];
|
|
539
574
|
const skill = body["skill"];
|
|
540
575
|
const mcp = body["mcp"];
|
|
541
|
-
|
|
576
|
+
const reverse = body["reverse"];
|
|
577
|
+
return typeof install === "object" && install !== null && typeof skill === "object" && skill !== null && typeof mcp === "object" && mcp !== null && typeof reverse === "object" && reverse !== null && typeof body["config"] === "object" && body["config"] !== null;
|
|
542
578
|
}
|
|
543
579
|
/** JobActionDto 守卫。 */
|
|
544
580
|
const isJobAction = (value) => {
|
|
@@ -552,7 +588,8 @@ ${extra}
|
|
|
552
588
|
}
|
|
553
589
|
/**
|
|
554
590
|
* 启动作业。
|
|
555
|
-
* @param kind - `install` = 安装/更新 REA 包;`skill` =
|
|
591
|
+
* @param kind - `install` = 安装/更新 REA 包;`skill` = 更新 REA skill 副本;
|
|
592
|
+
* `reverse` = 更新 reverse-skill(GitHub 源)。
|
|
556
593
|
* @param proxyPort - 草稿里当前填的代理端口(未保存也即时生效)。
|
|
557
594
|
*/
|
|
558
595
|
async function startJob(kind, proxyPort) {
|
|
@@ -565,8 +602,8 @@ ${extra}
|
|
|
565
602
|
//#endregion
|
|
566
603
|
//#region src/client/install.tsx
|
|
567
604
|
/**
|
|
568
|
-
* 卡片的「REA 安装与更新」区:只读状态表 +
|
|
569
|
-
*
|
|
605
|
+
* 卡片的「REA 安装与更新」区:只读状态表 + 四个动作(安装/更新 REA、更新 REA skill、
|
|
606
|
+
* 更新 reverse-skill、取消作业)+ 运行中作业的阶段进度条、已用时与日志尾部。
|
|
570
607
|
*
|
|
571
608
|
* 状态与作业都来自宿主半的同源端点(见 client/api.ts 与宿主 routes.ts):这里只管
|
|
572
609
|
* 轮询与呈现。作业在跑时按 {@link PROGRESS_POLL_MS} 轮询——进度是宿主侧的真事实,
|
|
@@ -595,6 +632,16 @@ ${extra}
|
|
|
595
632
|
error: "Error",
|
|
596
633
|
cancelled: "Cancelled"
|
|
597
634
|
};
|
|
635
|
+
/** 作业种类 → 文案键。 */
|
|
636
|
+
const JOB_LABEL = {
|
|
637
|
+
install: "jobInstall",
|
|
638
|
+
skill: "jobSkill",
|
|
639
|
+
reverse: "jobReverse"
|
|
640
|
+
};
|
|
641
|
+
/** 进度条百分比(防御性收窄,避免越界宽度)。 */
|
|
642
|
+
function widthOf(percent) {
|
|
643
|
+
return `${Math.max(0, Math.min(100, percent))}%`;
|
|
644
|
+
}
|
|
598
645
|
/** 作业进度块:状态徽标 + 阶段 + 进度条 + 日志尾部。 */
|
|
599
646
|
function JobPanel(props) {
|
|
600
647
|
const { t, job } = props;
|
|
@@ -612,7 +659,7 @@ ${extra}
|
|
|
612
659
|
}),
|
|
613
660
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
614
661
|
className: "apr-jobTitle",
|
|
615
|
-
children: t(job.kind
|
|
662
|
+
children: t(JOB_LABEL[job.kind])
|
|
616
663
|
}),
|
|
617
664
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
618
665
|
className: "apr-hint",
|
|
@@ -644,7 +691,7 @@ ${extra}
|
|
|
644
691
|
"aria-valuenow": job.progress.percent,
|
|
645
692
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
646
693
|
className: "apr-barFill",
|
|
647
|
-
style: { width:
|
|
694
|
+
style: { width: widthOf(job.progress.percent) }
|
|
648
695
|
})
|
|
649
696
|
}),
|
|
650
697
|
job.error === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -678,85 +725,220 @@ ${extra}
|
|
|
678
725
|
})]
|
|
679
726
|
});
|
|
680
727
|
}
|
|
681
|
-
/**
|
|
682
|
-
function
|
|
728
|
+
/** 状态徽标(已就绪 / 未就绪 / 已关闭)。 */
|
|
729
|
+
function Pill(props) {
|
|
730
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
731
|
+
className: `apr-pill ${props.ok ? "apr-pillOk" : "apr-pillMiss"}`,
|
|
732
|
+
children: props.label
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
/** REA 包与 MCP 行状态。 */
|
|
736
|
+
function InstallRows(props) {
|
|
683
737
|
const { t, status } = props;
|
|
684
|
-
const skillLabel = status.skill.source === "updated" ? t("skillUpdated") : t("skillBundled");
|
|
685
738
|
const mcpLabel = !status.mcp.enabled ? status.config.mcpEnabled ? t("mcpMissing") : t("mcpOff") : status.mcp.mode === "custom" ? t("mcpCustom") : t("mcpInstalled");
|
|
686
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
739
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
740
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(StatusRow, {
|
|
741
|
+
label: t("installPackage"),
|
|
742
|
+
children: [
|
|
743
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pill, {
|
|
744
|
+
ok: status.install.installed,
|
|
745
|
+
label: t(status.install.installed ? "installed" : "notInstalled")
|
|
746
|
+
}),
|
|
747
|
+
status.install.version === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
748
|
+
className: "apr-mono",
|
|
749
|
+
children: status.install.version
|
|
750
|
+
}),
|
|
751
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
752
|
+
className: "apr-hint",
|
|
753
|
+
children: [
|
|
754
|
+
t("installTarget"),
|
|
755
|
+
" ",
|
|
756
|
+
status.config.reaVersion
|
|
757
|
+
]
|
|
758
|
+
})
|
|
759
|
+
]
|
|
760
|
+
}),
|
|
761
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusRow, {
|
|
762
|
+
label: t("installPath"),
|
|
763
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
764
|
+
className: "apr-mono",
|
|
765
|
+
children: status.install.root
|
|
766
|
+
})
|
|
767
|
+
}),
|
|
768
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(StatusRow, {
|
|
769
|
+
label: t("mcpRow"),
|
|
770
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
771
|
+
className: "apr-mono",
|
|
772
|
+
children: mcpLabel
|
|
773
|
+
}), status.mcp.command === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("code", {
|
|
774
|
+
className: "apr-mono",
|
|
691
775
|
children: [
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
}),
|
|
696
|
-
status.install.version === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
697
|
-
className: "apr-mono",
|
|
698
|
-
children: status.install.version
|
|
699
|
-
}),
|
|
700
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
701
|
-
className: "apr-hint",
|
|
702
|
-
children: [
|
|
703
|
-
t("installTarget"),
|
|
704
|
-
" ",
|
|
705
|
-
status.config.reaVersion
|
|
706
|
-
]
|
|
707
|
-
})
|
|
776
|
+
status.mcp.command,
|
|
777
|
+
" ",
|
|
778
|
+
status.mcp.args.join(" ")
|
|
708
779
|
]
|
|
780
|
+
})]
|
|
781
|
+
})
|
|
782
|
+
] });
|
|
783
|
+
}
|
|
784
|
+
/** REA 官方 skill 状态。 */
|
|
785
|
+
function SkillRows(props) {
|
|
786
|
+
const { t, skill, enabled } = props;
|
|
787
|
+
const version = skill.version === null ? "" : ` · ${skill.version}`;
|
|
788
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(StatusRow, {
|
|
789
|
+
label: t("skillSource"),
|
|
790
|
+
children: [
|
|
791
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pill, {
|
|
792
|
+
ok: enabled,
|
|
793
|
+
label: t(enabled ? "enabled" : "disabled")
|
|
709
794
|
}),
|
|
710
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
711
|
-
|
|
712
|
-
children:
|
|
713
|
-
className: "apr-mono",
|
|
714
|
-
children: status.install.root
|
|
715
|
-
})
|
|
795
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
796
|
+
className: "apr-mono",
|
|
797
|
+
children: t(skill.source === "updated" ? "skillUpdated" : "skillBundled")
|
|
716
798
|
}),
|
|
717
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
718
|
-
|
|
799
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
800
|
+
className: "apr-hint",
|
|
719
801
|
children: [
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
725
|
-
className: "apr-hint",
|
|
726
|
-
children: [
|
|
727
|
-
t("skillFiles"),
|
|
728
|
-
" ",
|
|
729
|
-
status.skill.files,
|
|
730
|
-
status.skill.version === null ? "" : ` · ${status.skill.version}`
|
|
731
|
-
]
|
|
732
|
-
}),
|
|
733
|
-
status.skill.updatedAt === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
734
|
-
className: "apr-hint",
|
|
735
|
-
children: [
|
|
736
|
-
t("updatedAt"),
|
|
737
|
-
" ",
|
|
738
|
-
status.skill.updatedAt
|
|
739
|
-
]
|
|
740
|
-
})
|
|
802
|
+
t("skillFiles"),
|
|
803
|
+
" ",
|
|
804
|
+
skill.files,
|
|
805
|
+
version
|
|
741
806
|
]
|
|
742
807
|
}),
|
|
743
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
744
|
-
|
|
745
|
-
children: [
|
|
808
|
+
skill.updatedAt === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
809
|
+
className: "apr-hint",
|
|
810
|
+
children: [
|
|
811
|
+
t("updatedAt"),
|
|
812
|
+
" ",
|
|
813
|
+
skill.updatedAt
|
|
814
|
+
]
|
|
815
|
+
})
|
|
816
|
+
]
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
/** reverse-skill(GitHub 源)状态。 */
|
|
820
|
+
function ReverseRows(props) {
|
|
821
|
+
const { t, reverse, enabled } = props;
|
|
822
|
+
const active = reverse.activeGroups.length === 0 ? "—" : reverse.activeGroups.join(", ");
|
|
823
|
+
const all = reverse.groups.length === 0 ? "—" : reverse.groups.join(", ");
|
|
824
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
825
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(StatusRow, {
|
|
826
|
+
label: t("reverseSource"),
|
|
827
|
+
children: [
|
|
828
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pill, {
|
|
829
|
+
ok: reverse.installed,
|
|
830
|
+
label: t(reverse.installed ? "installed" : "notInstalled")
|
|
831
|
+
}),
|
|
832
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
746
833
|
className: "apr-mono",
|
|
747
|
-
children:
|
|
748
|
-
}),
|
|
834
|
+
children: reverse.repo
|
|
835
|
+
}),
|
|
836
|
+
reverse.sha === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
837
|
+
className: "apr-hint",
|
|
838
|
+
children: [
|
|
839
|
+
t("reverseCommit"),
|
|
840
|
+
" ",
|
|
841
|
+
reverse.sha.slice(0, 12),
|
|
842
|
+
reverse.version === null ? "" : ` · v${reverse.version}`
|
|
843
|
+
]
|
|
844
|
+
})
|
|
845
|
+
]
|
|
846
|
+
}),
|
|
847
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(StatusRow, {
|
|
848
|
+
label: t("reverseGroups"),
|
|
849
|
+
children: [
|
|
850
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pill, {
|
|
851
|
+
ok: enabled,
|
|
852
|
+
label: t(enabled ? "enabled" : "disabled")
|
|
853
|
+
}),
|
|
854
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
749
855
|
className: "apr-mono",
|
|
856
|
+
children: active
|
|
857
|
+
}),
|
|
858
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
859
|
+
className: "apr-hint",
|
|
750
860
|
children: [
|
|
751
|
-
|
|
861
|
+
t("reverseGroupsHint"),
|
|
752
862
|
" ",
|
|
753
|
-
|
|
863
|
+
all
|
|
754
864
|
]
|
|
755
|
-
})
|
|
865
|
+
})
|
|
866
|
+
]
|
|
867
|
+
}),
|
|
868
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(StatusRow, {
|
|
869
|
+
label: t("reversePath"),
|
|
870
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
871
|
+
className: "apr-mono",
|
|
872
|
+
children: reverse.tree
|
|
873
|
+
}), reverse.updatedAt === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
874
|
+
className: "apr-hint",
|
|
875
|
+
children: [
|
|
876
|
+
t("updatedAt"),
|
|
877
|
+
" ",
|
|
878
|
+
reverse.updatedAt
|
|
879
|
+
]
|
|
880
|
+
})]
|
|
881
|
+
})
|
|
882
|
+
] });
|
|
883
|
+
}
|
|
884
|
+
/** 只读状态表:REA 包 / MCP 行 / REA skill / reverse-skill。 */
|
|
885
|
+
function StatusTable(props) {
|
|
886
|
+
const { t, status } = props;
|
|
887
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
|
|
888
|
+
className: "apr-install",
|
|
889
|
+
children: [
|
|
890
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstallRows, {
|
|
891
|
+
t,
|
|
892
|
+
status
|
|
893
|
+
}),
|
|
894
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkillRows, {
|
|
895
|
+
t,
|
|
896
|
+
skill: status.skill,
|
|
897
|
+
enabled: status.config.skillEnabled
|
|
898
|
+
}),
|
|
899
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReverseRows, {
|
|
900
|
+
t,
|
|
901
|
+
reverse: status.reverse,
|
|
902
|
+
enabled: status.config.reverseSkillEnabled
|
|
756
903
|
})
|
|
757
904
|
]
|
|
758
905
|
});
|
|
759
906
|
}
|
|
907
|
+
/** 动作按钮行。 */
|
|
908
|
+
function ActionRow(props) {
|
|
909
|
+
const { t, busy, running, disabled, proxyPort, onAction, onCancel } = props;
|
|
910
|
+
const blocked = disabled || busy || running || proxyPort === null;
|
|
911
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
912
|
+
className: "apr-btnRow",
|
|
913
|
+
children: [
|
|
914
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
915
|
+
prefix: "apr",
|
|
916
|
+
variant: "primary",
|
|
917
|
+
label: t("installAction"),
|
|
918
|
+
disabled: blocked,
|
|
919
|
+
onClick: () => onAction("install")
|
|
920
|
+
}),
|
|
921
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
922
|
+
prefix: "apr",
|
|
923
|
+
label: t("skillAction"),
|
|
924
|
+
disabled: blocked,
|
|
925
|
+
onClick: () => onAction("skill")
|
|
926
|
+
}),
|
|
927
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
928
|
+
prefix: "apr",
|
|
929
|
+
label: t("reverseAction"),
|
|
930
|
+
disabled: blocked,
|
|
931
|
+
onClick: () => onAction("reverse")
|
|
932
|
+
}),
|
|
933
|
+
running ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
934
|
+
prefix: "apr",
|
|
935
|
+
label: t("cancelAction"),
|
|
936
|
+
disabled: busy,
|
|
937
|
+
onClick: onCancel
|
|
938
|
+
}) : null
|
|
939
|
+
]
|
|
940
|
+
});
|
|
941
|
+
}
|
|
760
942
|
function InstallSection(props) {
|
|
761
943
|
const { t, disabled, proxyPort } = props;
|
|
762
944
|
const [status, setStatus] = (0, react.useState)(null);
|
|
@@ -805,7 +987,6 @@ ${extra}
|
|
|
805
987
|
if (alive.current) setBusy(false);
|
|
806
988
|
});
|
|
807
989
|
}, [load, t]);
|
|
808
|
-
const blocked = disabled || busy || running === true;
|
|
809
990
|
const job = status?.job ?? null;
|
|
810
991
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
811
992
|
className: "apr-field",
|
|
@@ -830,35 +1011,18 @@ ${extra}
|
|
|
830
1011
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusTable, {
|
|
831
1012
|
t,
|
|
832
1013
|
status
|
|
833
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
846
|
-
prefix: "apr",
|
|
847
|
-
label: t("skillAction"),
|
|
848
|
-
disabled: blocked || proxyPort === null,
|
|
849
|
-
onClick: () => {
|
|
850
|
-
runAction(() => startJob("skill", proxyPort ?? 0));
|
|
851
|
-
}
|
|
852
|
-
}),
|
|
853
|
-
running === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
854
|
-
prefix: "apr",
|
|
855
|
-
label: t("cancelAction"),
|
|
856
|
-
disabled: busy,
|
|
857
|
-
onClick: () => {
|
|
858
|
-
runAction(() => cancelJob());
|
|
859
|
-
}
|
|
860
|
-
}) : null
|
|
861
|
-
]
|
|
1014
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionRow, {
|
|
1015
|
+
t,
|
|
1016
|
+
busy,
|
|
1017
|
+
running: running === true,
|
|
1018
|
+
disabled,
|
|
1019
|
+
proxyPort,
|
|
1020
|
+
onAction: (kind) => {
|
|
1021
|
+
runAction(() => startJob(kind, proxyPort ?? 0));
|
|
1022
|
+
},
|
|
1023
|
+
onCancel: () => {
|
|
1024
|
+
runAction(() => cancelJob());
|
|
1025
|
+
}
|
|
862
1026
|
})] }),
|
|
863
1027
|
job === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(JobPanel, {
|
|
864
1028
|
t,
|
|
@@ -876,6 +1040,61 @@ ${extra}
|
|
|
876
1040
|
});
|
|
877
1041
|
}
|
|
878
1042
|
//#endregion
|
|
1043
|
+
//#region src/client/toggles.tsx
|
|
1044
|
+
/**
|
|
1045
|
+
* 卡片的「能力开关」区:三个一键开关(REA MCP 行 / REA 官方 skill / reverse-skill
|
|
1046
|
+
* 技能包)。三者都是活动字段,保存后本预设换代注册——新建会话按新装配起(REA 工具
|
|
1047
|
+
* 与 skill 根的有无),已存在会话保持既有装配。
|
|
1048
|
+
*
|
|
1049
|
+
* 开关只管「挂不挂」,不管「装没装」:关掉不会删磁盘上的安装副本(更新/回滚仍是
|
|
1050
|
+
* 显式动作,见 install.tsx)。
|
|
1051
|
+
* @module agent-preset-rea/client/toggles
|
|
1052
|
+
*/
|
|
1053
|
+
/** 三个开关的键与文案键。 */
|
|
1054
|
+
const TOGGLES = [
|
|
1055
|
+
{
|
|
1056
|
+
field: "mcpEnabled",
|
|
1057
|
+
id: "apr-toggle-mcp",
|
|
1058
|
+
label: "toggleMcp",
|
|
1059
|
+
hint: "toggleMcpHint"
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
field: "skillEnabled",
|
|
1063
|
+
id: "apr-toggle-skill",
|
|
1064
|
+
label: "toggleSkill",
|
|
1065
|
+
hint: "toggleSkillHint"
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
field: "reverseSkillEnabled",
|
|
1069
|
+
id: "apr-toggle-reverse",
|
|
1070
|
+
label: "toggleReverse",
|
|
1071
|
+
hint: "toggleReverseHint"
|
|
1072
|
+
}
|
|
1073
|
+
];
|
|
1074
|
+
function ToggleSection(props) {
|
|
1075
|
+
const { t, draft, disabled, onEdit } = props;
|
|
1076
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1077
|
+
className: "apr-field",
|
|
1078
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1079
|
+
className: "apr-head",
|
|
1080
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1081
|
+
className: "apr-label",
|
|
1082
|
+
children: t("toggleSection")
|
|
1083
|
+
})
|
|
1084
|
+
}), TOGGLES.map((toggle) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CheckRow, {
|
|
1085
|
+
prefix: "apr",
|
|
1086
|
+
id: toggle.id,
|
|
1087
|
+
label: t(toggle.label),
|
|
1088
|
+
checked: draft[toggle.field],
|
|
1089
|
+
disabled,
|
|
1090
|
+
onEdit: (checked) => onEdit({ [toggle.field]: checked })
|
|
1091
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1092
|
+
className: "apr-hint",
|
|
1093
|
+
children: t(toggle.hint)
|
|
1094
|
+
})] }, toggle.field))]
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
//#endregion
|
|
879
1098
|
//#region src/client/card.tsx
|
|
880
1099
|
/**
|
|
881
1100
|
* 「逆向工程」预设配置卡片:提示词(活动字段)+ 代理端口(活动字段)+ 安装维护区。
|
|
@@ -885,11 +1104,12 @@ ${extra}
|
|
|
885
1104
|
* (CardChrome + useNamespaceDraft:staged 草稿、脏判定、revision fencing、
|
|
886
1105
|
* Host 更新不覆盖在途编辑),安装维护区见 client/install.tsx。
|
|
887
1106
|
*
|
|
888
|
-
*
|
|
1107
|
+
* 五个活动字段(`Config` 里标 `.volatile()` 的)都在这里给出编辑器:
|
|
889
1108
|
* - `personaPrefix`:system-prompt 的 persona 前缀段;
|
|
890
|
-
* - `proxyPort
|
|
891
|
-
*
|
|
892
|
-
*
|
|
1109
|
+
* - `proxyPort`:安装/更新时的本机代理端口;
|
|
1110
|
+
* - `mcpEnabled` / `skillEnabled` / `reverseSkillEnabled`:三个能力开关(见 toggles.tsx)。
|
|
1111
|
+
* 其余字段(受管目录、版本钉、skill 组、MCP 参数、超时、附加 skill 根)属部署方平面,
|
|
1112
|
+
* 由 profile 的 cordis.patch.yml 行级配置覆盖,卡片只读展示关键事实。
|
|
893
1113
|
*
|
|
894
1114
|
* 安装维护为什么不放在注册期自动做:启动期 `npx`/npm 安装会跑依赖安装脚本
|
|
895
1115
|
* (原生 prebuild 下载),卡住即吊死预设激活与整个名册;因此改成显式动作
|
|
@@ -989,6 +1209,12 @@ ${extra}
|
|
|
989
1209
|
disabled,
|
|
990
1210
|
onEdit: (text) => state.edit({ proxyPort: text })
|
|
991
1211
|
}),
|
|
1212
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToggleSection, {
|
|
1213
|
+
t,
|
|
1214
|
+
draft,
|
|
1215
|
+
disabled,
|
|
1216
|
+
onEdit: state.edit
|
|
1217
|
+
}),
|
|
992
1218
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InstallSection, {
|
|
993
1219
|
t,
|
|
994
1220
|
disabled,
|
|
@@ -1008,7 +1234,7 @@ ${extra}
|
|
|
1008
1234
|
const ownZh = {
|
|
1009
1235
|
title: "逆向工程预设",
|
|
1010
1236
|
description: "REA 提示词与安装维护:提示词留空即空 persona,工具指引与运行时上下文照常注入。",
|
|
1011
|
-
summaryLine: "
|
|
1237
|
+
summaryLine: "编辑「逆向工程」预设的提示词、开关 REA MCP 与两类 skill,并安装/更新",
|
|
1012
1238
|
prompt: "系统提示词(persona 前缀)",
|
|
1013
1239
|
promptHint: "写入 system-prompt 的 persona 前缀段,仅对「逆向工程」预设的新会话生效;留空 = 不注入 persona 段(官方工具指引、项目指令与运行时上下文不受影响)。保存后新建会话即用新值。",
|
|
1014
1240
|
promptPlaceholder: "例如:先做证据分级,再动手改二进制;每一步给出可复核的证据链……",
|
|
@@ -1052,6 +1278,22 @@ ${extra}
|
|
|
1052
1278
|
jobFinishedAt: "结束于",
|
|
1053
1279
|
jobElapsed: "已用时",
|
|
1054
1280
|
jobLogEmpty: "(暂无输出)",
|
|
1281
|
+
toggleSection: "能力开关",
|
|
1282
|
+
toggleMcp: "REA MCP 工具(mcp__rea__*)",
|
|
1283
|
+
toggleMcpHint: "关掉即从本预设摘掉 REA MCP 行,模型面看不到 mcp__rea__* 工具;REA 仍留在磁盘上,随时可开回来(保存后新建会话生效)。",
|
|
1284
|
+
toggleSkill: "REA 官方 skill",
|
|
1285
|
+
toggleSkillHint: "关掉即不挂 REA 官方 skill 根(reverse-engineer-anything),其余 skill 根不受影响。",
|
|
1286
|
+
toggleReverse: "reverse-skill 技能包",
|
|
1287
|
+
toggleReverseHint: "关掉即不挂 zhaoxuya520/reverse-skill 的技能组(默认挂主包根:路由技能 + 各模块技能);安装副本仍在,可从下面重新更新。",
|
|
1288
|
+
enabled: "已挂载",
|
|
1289
|
+
disabled: "已关闭",
|
|
1290
|
+
reverseSource: "reverse-skill",
|
|
1291
|
+
reverseCommit: "提交",
|
|
1292
|
+
reverseGroups: "技能组",
|
|
1293
|
+
reverseGroupsHint: "树内可选组:",
|
|
1294
|
+
reversePath: "技能包目录",
|
|
1295
|
+
reverseAction: "更新 reverse-skill",
|
|
1296
|
+
jobReverse: "更新 reverse-skill",
|
|
1055
1297
|
proxyPort: "安装代理端口",
|
|
1056
1298
|
proxyPortHint: "安装/更新时供 npm 与原生依赖(node-pty)prebuild 下载使用的本机代理端口;0 或留空 = 直连。未保存也用于本次安装,保存后长期生效。",
|
|
1057
1299
|
proxyPortInvalid: "代理端口必须是 0..65535 的整数。"
|
|
@@ -1059,7 +1301,7 @@ ${extra}
|
|
|
1059
1301
|
const ownEn = {
|
|
1060
1302
|
title: "Reverse-engineering preset",
|
|
1061
1303
|
description: "REA prompt and installation: an empty prompt means a blank persona; tool guidance and runtime context stay in place.",
|
|
1062
|
-
summaryLine: "Edit the “逆向工程” prompt
|
|
1304
|
+
summaryLine: "Edit the “逆向工程” prompt, toggle REA MCP/skills, install and update them",
|
|
1063
1305
|
prompt: "System prompt (persona prefix)",
|
|
1064
1306
|
promptHint: "Written to the persona-prefix section of the system prompt for new sessions of this preset only. Empty means no persona section (official tool guidance, project instructions and runtime context are unaffected). New sessions pick up the saved value.",
|
|
1065
1307
|
promptPlaceholder: "e.g. Grade the evidence first, then patch the binary; every step needs a checkable chain of evidence…",
|
|
@@ -1103,6 +1345,22 @@ ${extra}
|
|
|
1103
1345
|
jobFinishedAt: "Finished",
|
|
1104
1346
|
jobElapsed: "Elapsed",
|
|
1105
1347
|
jobLogEmpty: "(no output yet)",
|
|
1348
|
+
toggleSection: "Capability switches",
|
|
1349
|
+
toggleMcp: "REA MCP tools (mcp__rea__*)",
|
|
1350
|
+
toggleMcpHint: "Turning this off drops the REA MCP row from this preset, so mcp__rea__* tools disappear; REA stays on disk and can be switched back on. New sessions pick up the change.",
|
|
1351
|
+
toggleSkill: "REA official skill",
|
|
1352
|
+
toggleSkillHint: "Turning this off unmounts the bundled REA skill root (reverse-engineer-anything); other skill roots are unaffected.",
|
|
1353
|
+
toggleReverse: "reverse-skill pack",
|
|
1354
|
+
toggleReverseHint: "Turning this off unmounts the skill groups of zhaoxuya520/reverse-skill (the main pack root is mounted by default: router skill plus module skills). The installed copy stays on disk and can be updated again below.",
|
|
1355
|
+
enabled: "Mounted",
|
|
1356
|
+
disabled: "Off",
|
|
1357
|
+
reverseSource: "reverse-skill",
|
|
1358
|
+
reverseCommit: "Commit",
|
|
1359
|
+
reverseGroups: "Skill groups",
|
|
1360
|
+
reverseGroupsHint: "Available in tree: ",
|
|
1361
|
+
reversePath: "Pack directory",
|
|
1362
|
+
reverseAction: "Update reverse-skill",
|
|
1363
|
+
jobReverse: "Update reverse-skill",
|
|
1106
1364
|
proxyPort: "Install proxy port",
|
|
1107
1365
|
proxyPortHint: "Local proxy port used by npm and by the native node-pty prebuild download during install/update; 0 or empty means direct. The unsaved value is used for the next install and applies permanently once saved.",
|
|
1108
1366
|
proxyPortInvalid: "Proxy port must be an integer in 0..65535."
|