@miphamai/cli 0.32.7 → 0.33.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/package.json +1 -1
- package/src/core/auto-corrector.ts +220 -0
- package/src/core/auto-memory.ts +29 -0
- package/src/core/engine.ts +97 -1
- package/src/core/error-signature-db.ts +324 -0
- package/src/core/immune-memory-gc.ts +187 -0
- package/src/core/meta-rule-engine.ts +602 -0
- package/src/core/preflight-checker.ts +218 -0
- package/src/ui/commands.ts +268 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIS (Self-Immune System) Phase 0: Pre-Flight Checker
|
|
3
|
+
*
|
|
4
|
+
* Pre-execution interception layer that checks tool calls against:
|
|
5
|
+
* 1. ErrorSignatureDB — known error patterns with proven fixes
|
|
6
|
+
* 2. ExperienceRuleEngine — CRSI Phase 1 dynamic rules
|
|
7
|
+
*
|
|
8
|
+
* Returns one of four actions:
|
|
9
|
+
* - 'allow' → no issue, proceed normally
|
|
10
|
+
* - 'warn' → known risky pattern, show warning but allow
|
|
11
|
+
* - 'fix' → known error with proven fix, auto-correct params
|
|
12
|
+
* - 'block' → known dangerous pattern, refuse execution
|
|
13
|
+
*
|
|
14
|
+
* Priority: block > fix > warn > allow
|
|
15
|
+
* (most restrictive action wins when multiple sources match)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { ErrorSignatureDB, ErrorSignature } from './error-signature-db.js'
|
|
19
|
+
import type { ExperienceRuleEngine } from './rule-engine.js'
|
|
20
|
+
|
|
21
|
+
// ── Types ──
|
|
22
|
+
|
|
23
|
+
export interface PreFlightResult {
|
|
24
|
+
/** The action to take */
|
|
25
|
+
action: 'allow' | 'warn' | 'fix' | 'block'
|
|
26
|
+
/** Warning message (for 'warn' and 'block' actions) */
|
|
27
|
+
warning?: string
|
|
28
|
+
/** Modified parameters (for 'fix' action) */
|
|
29
|
+
modifiedParams?: Record<string, unknown>
|
|
30
|
+
/** Matched error signature ID (for tracking) */
|
|
31
|
+
matchedSignature?: string
|
|
32
|
+
/** Human-readable explanation of the fix */
|
|
33
|
+
explanation?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ── Action Priority ──
|
|
37
|
+
|
|
38
|
+
const ACTION_PRIORITY: Record<PreFlightResult['action'], number> = {
|
|
39
|
+
allow: 0,
|
|
40
|
+
warn: 1,
|
|
41
|
+
fix: 2,
|
|
42
|
+
block: 3,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ── Checker ──
|
|
46
|
+
|
|
47
|
+
export class PreFlightChecker {
|
|
48
|
+
private errorDB: ErrorSignatureDB
|
|
49
|
+
private ruleEngine?: ExperienceRuleEngine
|
|
50
|
+
|
|
51
|
+
constructor(errorDB: ErrorSignatureDB, ruleEngine?: ExperienceRuleEngine) {
|
|
52
|
+
this.errorDB = errorDB
|
|
53
|
+
this.ruleEngine = ruleEngine
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Check a tool call before execution.
|
|
58
|
+
*
|
|
59
|
+
* @param toolName — e.g. 'Bash', 'Write', 'Grep'
|
|
60
|
+
* @param params — tool input parameters
|
|
61
|
+
* @returns PreFlightResult with the strictest applicable action
|
|
62
|
+
*/
|
|
63
|
+
check(toolName: string, params: Record<string, unknown>): PreFlightResult {
|
|
64
|
+
const results: PreFlightResult[] = []
|
|
65
|
+
|
|
66
|
+
// ── Layer 1: ErrorSignatureDB ──
|
|
67
|
+
const sig = this.errorDB.match(toolName, params)
|
|
68
|
+
if (sig) {
|
|
69
|
+
results.push(this.signatureToResult(sig, params))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ── Layer 2: ExperienceRuleEngine ──
|
|
73
|
+
if (this.ruleEngine) {
|
|
74
|
+
const ruleResult = this.checkRuleEngine(toolName, params)
|
|
75
|
+
if (ruleResult) {
|
|
76
|
+
results.push(ruleResult)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ── Merge: pick the most restrictive result ──
|
|
81
|
+
if (results.length === 0) {
|
|
82
|
+
return { action: 'allow' }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return results.reduce((best, curr) =>
|
|
86
|
+
ACTION_PRIORITY[curr.action] > ACTION_PRIORITY[best.action] ? curr : best,
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Set/update the rule engine reference.
|
|
92
|
+
* Useful when the rule engine is wired after construction.
|
|
93
|
+
*/
|
|
94
|
+
setRuleEngine(ruleEngine: ExperienceRuleEngine): void {
|
|
95
|
+
this.ruleEngine = ruleEngine
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ── Private: Signature Conversion ──
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Convert an ErrorSignature to a PreFlightResult based on its fixStrategy.
|
|
102
|
+
*/
|
|
103
|
+
private signatureToResult(sig: ErrorSignature, params: Record<string, unknown>): PreFlightResult {
|
|
104
|
+
const base = {
|
|
105
|
+
matchedSignature: sig.id,
|
|
106
|
+
explanation: sig.explanation,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
switch (sig.fixStrategy) {
|
|
110
|
+
case 'block':
|
|
111
|
+
return {
|
|
112
|
+
...base,
|
|
113
|
+
action: 'block',
|
|
114
|
+
warning: `⛔ SIS 免疫拦截: ${sig.explanation} (${sig.occurrences} 次历史发生,成功率 ${Math.round(sig.successRate * 100)}%)`,
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
case 'warn':
|
|
118
|
+
return {
|
|
119
|
+
...base,
|
|
120
|
+
action: 'warn',
|
|
121
|
+
warning: `⚠️ SIS 预警: ${sig.explanation} (${sig.occurrences} 次历史发生)`,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
case 'replace':
|
|
125
|
+
return {
|
|
126
|
+
...base,
|
|
127
|
+
action: 'fix',
|
|
128
|
+
warning: `🔧 SIS 自动修复: ${sig.explanation}`,
|
|
129
|
+
modifiedParams: this.applyReplace(sig),
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
case 'prepend':
|
|
133
|
+
return {
|
|
134
|
+
...base,
|
|
135
|
+
action: 'fix',
|
|
136
|
+
warning: `🔧 SIS 自动修复: ${sig.explanation}`,
|
|
137
|
+
modifiedParams: this.applyPrepend(params, sig),
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
case 'append':
|
|
141
|
+
return {
|
|
142
|
+
...base,
|
|
143
|
+
action: 'fix',
|
|
144
|
+
warning: `🔧 SIS 自动修复: ${sig.explanation}`,
|
|
145
|
+
modifiedParams: this.applyAppend(params, sig),
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
default:
|
|
149
|
+
return { ...base, action: 'warn', warning: sig.explanation }
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ── Private: Rule Engine Check ──
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Check against the ExperienceRuleEngine.
|
|
157
|
+
* Converts the rule engine's {modified, warnings} output to a PreFlightResult.
|
|
158
|
+
*/
|
|
159
|
+
private checkRuleEngine(
|
|
160
|
+
toolName: string,
|
|
161
|
+
params: Record<string, unknown>,
|
|
162
|
+
): PreFlightResult | null {
|
|
163
|
+
if (!this.ruleEngine) return null
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const { modified, warnings } = this.ruleEngine.intercept(toolName, params)
|
|
167
|
+
const hasWarnings = warnings.length > 0
|
|
168
|
+
const hasModifications = JSON.stringify(modified) !== JSON.stringify(params)
|
|
169
|
+
|
|
170
|
+
if (!hasWarnings && !hasModifications) return null
|
|
171
|
+
|
|
172
|
+
if (hasModifications) {
|
|
173
|
+
return {
|
|
174
|
+
action: 'fix',
|
|
175
|
+
warning: warnings.join('; '),
|
|
176
|
+
modifiedParams: modified,
|
|
177
|
+
explanation: 'CRSI 规则引擎自动修正',
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (hasWarnings) {
|
|
182
|
+
return {
|
|
183
|
+
action: 'warn',
|
|
184
|
+
warning: warnings.join('; '),
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
} catch {
|
|
188
|
+
// Rule engine errors are non-fatal
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return null
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ── Private: Fix Application Helpers ──
|
|
195
|
+
|
|
196
|
+
/** 'replace' strategy: replace the entire command string. */
|
|
197
|
+
private applyReplace(sig: ErrorSignature): Record<string, unknown> {
|
|
198
|
+
return { command: sig.fixAction }
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** 'prepend' strategy: prepend text to the command. */
|
|
202
|
+
private applyPrepend(
|
|
203
|
+
params: Record<string, unknown>,
|
|
204
|
+
sig: ErrorSignature,
|
|
205
|
+
): Record<string, unknown> {
|
|
206
|
+
const cmd = String(params.command ?? '')
|
|
207
|
+
return { ...params, command: `${sig.fixAction} ${cmd}` }
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** 'append' strategy: append text to the command. */
|
|
211
|
+
private applyAppend(
|
|
212
|
+
params: Record<string, unknown>,
|
|
213
|
+
sig: ErrorSignature,
|
|
214
|
+
): Record<string, unknown> {
|
|
215
|
+
const cmd = String(params.command ?? '')
|
|
216
|
+
return { ...params, command: `${cmd} ${sig.fixAction}` }
|
|
217
|
+
}
|
|
218
|
+
}
|
package/src/ui/commands.ts
CHANGED
|
@@ -656,6 +656,257 @@ const crsiStatsCmd: CommandHandler = async (ctx) => {
|
|
|
656
656
|
return { content: lines.join('\n') }
|
|
657
657
|
}
|
|
658
658
|
|
|
659
|
+
const crsiHealthCmd: CommandHandler = async (ctx) => {
|
|
660
|
+
const engine = ctx.engine.getRuleEngine()
|
|
661
|
+
const tracker = ctx.engine.getEffectivenessTracker()
|
|
662
|
+
const db = ctx.engine.getErrorSignatureDB?.()
|
|
663
|
+
const patternAnalyzer = ctx.engine.getPatternAnalyzer?.()
|
|
664
|
+
|
|
665
|
+
const lines: string[] = ['## 🏥 CRSI 系统健康仪表盘', '']
|
|
666
|
+
|
|
667
|
+
// ── CRSI Section ──
|
|
668
|
+
lines.push('### 🧠 CRSI 学习子系统', '')
|
|
669
|
+
if (engine) {
|
|
670
|
+
const rules = engine.getActiveRules()
|
|
671
|
+
const builtin = rules.filter((r) => r.source === 'builtin').length
|
|
672
|
+
const auto = rules.filter((r) => r.source === 'pattern-analyzer').length
|
|
673
|
+
const manual = rules.filter((r) => r.source === 'manual').length
|
|
674
|
+
|
|
675
|
+
lines.push(`| 指标 | 值 |`)
|
|
676
|
+
lines.push(`|------|----|`)
|
|
677
|
+
lines.push(`| 活跃规则 | ${rules.length} (内置 ${builtin} · 自动 ${auto} · 手动 ${manual}) |`)
|
|
678
|
+
|
|
679
|
+
if (tracker) {
|
|
680
|
+
let interceptions = 0
|
|
681
|
+
let successes = 0
|
|
682
|
+
for (const r of rules) {
|
|
683
|
+
const eff = tracker.getEffectiveness(r.id)
|
|
684
|
+
if (eff) {
|
|
685
|
+
interceptions += eff.appliedCount
|
|
686
|
+
successes += eff.successAfterCount
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
const crsiRate = interceptions > 0 ? Math.round((successes / interceptions) * 100) : 100
|
|
690
|
+
lines.push(`| 总拦截次数 | ${interceptions} |`)
|
|
691
|
+
lines.push(`| 拦截成功率 | ${crsiRate}% |`)
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// Pattern analysis depth
|
|
695
|
+
if (patternAnalyzer) {
|
|
696
|
+
const patterns = patternAnalyzer.analyzeAllAgents()
|
|
697
|
+
lines.push(`| 已检测模式 | ${patterns.length} |`)
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
lines.push('')
|
|
701
|
+
lines.push('CRSI 命令: `/crsi rules` `/crsi stats` `/crsi analyze`')
|
|
702
|
+
} else {
|
|
703
|
+
lines.push('CRSI 规则引擎未初始化')
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// ── SIS Section ──
|
|
707
|
+
lines.push('', '### 🛡️ SIS 自免疫子系统', '')
|
|
708
|
+
if (db) {
|
|
709
|
+
const stats = db.getStats()
|
|
710
|
+
const healthEmoji =
|
|
711
|
+
stats.avgSuccessRate >= 0.8 ? '🟢' : stats.avgSuccessRate >= 0.5 ? '🟡' : '🔴'
|
|
712
|
+
|
|
713
|
+
lines.push(`| 指标 | 值 |`)
|
|
714
|
+
lines.push(`|------|----|`)
|
|
715
|
+
lines.push(
|
|
716
|
+
`| 免疫记忆 | ${stats.total} 条 (🟢${stats.active} · 🟡${stats.degraded} · ⚫${stats.retired}) |`,
|
|
717
|
+
)
|
|
718
|
+
lines.push(`| 平均成功率 | ${Math.round(stats.avgSuccessRate * 100)}% |`)
|
|
719
|
+
lines.push(`| 总拦截 | ${stats.totalInterceptions} 次 |`)
|
|
720
|
+
|
|
721
|
+
lines.push('')
|
|
722
|
+
lines.push('SIS 命令: `/sis errors` `/sis stats` `/sis clear <id>`')
|
|
723
|
+
} else {
|
|
724
|
+
lines.push('SIS 自免疫系统未初始化')
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
// ── Overall Health Score ──
|
|
728
|
+
lines.push('', '### 📊 综合健康评分', '')
|
|
729
|
+
const crsiScore = engine ? 50 : 0
|
|
730
|
+
const sisScore = db ? (db.getStats().avgSuccessRate >= 0.8 ? 50 : 25) : 0
|
|
731
|
+
const totalScore = crsiScore + sisScore
|
|
732
|
+
|
|
733
|
+
const grade =
|
|
734
|
+
totalScore >= 80
|
|
735
|
+
? '🟢 A — 优秀'
|
|
736
|
+
: totalScore >= 50
|
|
737
|
+
? '🟡 B — 良好'
|
|
738
|
+
: totalScore >= 25
|
|
739
|
+
? '🟠 C — 需关注'
|
|
740
|
+
: '🔴 D — 待初始化'
|
|
741
|
+
|
|
742
|
+
lines.push(`| 子系统 | 状态 | 得分 |`)
|
|
743
|
+
lines.push(`|--------|------|------|`)
|
|
744
|
+
lines.push(`| CRSI 学习 | ${engine ? '✅ 在线' : '❌ 离线'} | ${crsiScore}/50 |`)
|
|
745
|
+
lines.push(`| SIS 免疫 | ${db ? '✅ 在线' : '❌ 离线'} | ${sisScore}/50 |`)
|
|
746
|
+
lines.push(`| **综合** | **${grade}** | **${totalScore}/100** |`)
|
|
747
|
+
|
|
748
|
+
return { content: lines.join('\n') }
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
const crsiMetaCmd: CommandHandler = async (ctx) => {
|
|
752
|
+
const metaEngine = ctx.engine.getMetaRuleEngine?.()
|
|
753
|
+
if (!metaEngine) {
|
|
754
|
+
return { content: 'MetaRuleEngine 未初始化。请先运行 `/crsi health` 初始化 CRSI 系统。' }
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
const result = metaEngine.analyze()
|
|
758
|
+
const lines: string[] = ['## 🔮 CRSI 元规则分析 (RSI Level 3)', '']
|
|
759
|
+
|
|
760
|
+
// ── System Health ──
|
|
761
|
+
lines.push('### 📊 系统健康评分', '')
|
|
762
|
+
const h = result.systemHealth
|
|
763
|
+
lines.push(`| 组件 | 得分 |`)
|
|
764
|
+
lines.push(`|------|------|`)
|
|
765
|
+
lines.push(`| 错误签名 | ${h.components.errorSignatures}/100 |`)
|
|
766
|
+
lines.push(`| 预防拦截 | ${h.components.preflightPrevention}/100 |`)
|
|
767
|
+
lines.push(`| 自动修复 | ${h.components.autoCorrection}/100 |`)
|
|
768
|
+
lines.push(`| 免疫记忆 | ${h.components.immuneMemory}/100 |`)
|
|
769
|
+
lines.push(`| 规则有效性 | ${h.components.ruleEffectiveness}/100 |`)
|
|
770
|
+
lines.push(`| **综合** | **${h.score}/100** |`)
|
|
771
|
+
lines.push('')
|
|
772
|
+
lines.push(h.assessment)
|
|
773
|
+
lines.push('')
|
|
774
|
+
|
|
775
|
+
// ── Recommendations ──
|
|
776
|
+
lines.push('### 💡 优化建议', '')
|
|
777
|
+
for (const rec of h.recommendations) {
|
|
778
|
+
lines.push(`- ${rec}`)
|
|
779
|
+
}
|
|
780
|
+
lines.push('')
|
|
781
|
+
|
|
782
|
+
// ── Meta-Rules ──
|
|
783
|
+
if (result.metaRules.length > 0) {
|
|
784
|
+
lines.push(`### 🧬 发现 ${result.metaRules.length} 条元规则`, '')
|
|
785
|
+
|
|
786
|
+
for (const mr of result.metaRules) {
|
|
787
|
+
const confIcon = mr.confidence === 'high' ? '🔴' : mr.confidence === 'medium' ? '🟡' : '🟢'
|
|
788
|
+
const autoLabel = mr.autoApplicable ? ' [可自动应用]' : ''
|
|
789
|
+
lines.push(`#### ${confIcon} ${mr.title}${autoLabel}`)
|
|
790
|
+
lines.push('')
|
|
791
|
+
lines.push(mr.description)
|
|
792
|
+
lines.push('')
|
|
793
|
+
lines.push(`> **建议**: ${mr.recommendation}`)
|
|
794
|
+
lines.push('')
|
|
795
|
+
lines.push(
|
|
796
|
+
`置信度: ${mr.confidence} | 样本量: ${mr.evidence.sampleSize} | 生成时间: ${mr.generatedAt}`,
|
|
797
|
+
)
|
|
798
|
+
lines.push('')
|
|
799
|
+
}
|
|
800
|
+
} else {
|
|
801
|
+
lines.push('### 🧬 元规则', '')
|
|
802
|
+
lines.push(
|
|
803
|
+
'暂无元规则生成。当系统积累足够的错误签名和规则数据后,元规则引擎将自动发现跨规则模式。',
|
|
804
|
+
)
|
|
805
|
+
lines.push('')
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// ── Auto-applicable summary ──
|
|
809
|
+
const autoApplicable = metaEngine.getAutoApplicable(result.metaRules)
|
|
810
|
+
if (autoApplicable.length > 0) {
|
|
811
|
+
lines.push('### ⚡ 可自动应用', '')
|
|
812
|
+
lines.push(`${autoApplicable.length} 条元规则可安全自动应用:`)
|
|
813
|
+
for (const mr of autoApplicable) {
|
|
814
|
+
lines.push(`- \`${mr.id}\`: ${mr.recommendation}`)
|
|
815
|
+
}
|
|
816
|
+
lines.push('')
|
|
817
|
+
lines.push('使用 `/crsi meta --apply` 自动应用高置信度元规则。')
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
return { content: lines.join('\n') }
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// ═══════════════════════════════════════════════════════════════
|
|
824
|
+
// SIS (Self-Immune System)
|
|
825
|
+
// ═══════════════════════════════════════════════════════════════
|
|
826
|
+
|
|
827
|
+
const sisErrorsCmd: CommandHandler = (ctx) => {
|
|
828
|
+
const db = ctx.engine.getErrorSignatureDB?.()
|
|
829
|
+
if (!db) {
|
|
830
|
+
return { content: 'SIS 自免疫系统未初始化。' }
|
|
831
|
+
}
|
|
832
|
+
const sigs = db.getActive()
|
|
833
|
+
if (sigs.length === 0) {
|
|
834
|
+
return { content: '🛡️ SIS 免疫记忆为空 — 尚未记录任何错误签名。' }
|
|
835
|
+
}
|
|
836
|
+
const lines: string[] = ['## 🛡️ SIS 免疫记忆', '']
|
|
837
|
+
for (const sig of sigs) {
|
|
838
|
+
const statusIcon = sig.status === 'active' ? '🟢' : '🟡'
|
|
839
|
+
lines.push(`- ${statusIcon} \`${sig.id}\` [${sig.category}] ${sig.toolName}`)
|
|
840
|
+
lines.push(` 模式: \`${sig.pattern.slice(0, 80)}${sig.pattern.length > 80 ? '...' : ''}\``)
|
|
841
|
+
lines.push(
|
|
842
|
+
` 修复: ${sig.fixStrategy} → ${sig.fixAction.slice(0, 60)} | 发生 ${sig.occurrences} 次 | 成功率 ${Math.round(sig.successRate * 100)}%`,
|
|
843
|
+
)
|
|
844
|
+
lines.push('')
|
|
845
|
+
}
|
|
846
|
+
lines.push(`共 ${sigs.length} 条活跃免疫记忆`)
|
|
847
|
+
lines.push('', '使用 `/sis stats` 查看汇总统计,`/sis clear <id>` 清除指定签名')
|
|
848
|
+
return { content: lines.join('\n') }
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
const sisStatsCmd: CommandHandler = (ctx) => {
|
|
852
|
+
const db = ctx.engine.getErrorSignatureDB?.()
|
|
853
|
+
if (!db) {
|
|
854
|
+
return { content: 'SIS 自免疫系统未初始化。' }
|
|
855
|
+
}
|
|
856
|
+
const stats = db.getStats()
|
|
857
|
+
const lines: string[] = ['## 🛡️ SIS 自免疫统计', '']
|
|
858
|
+
lines.push(`总签名数: ${stats.total}`)
|
|
859
|
+
lines.push(
|
|
860
|
+
`🟢 活跃: ${stats.active} | 🟡 降级: ${stats.degraded} | ⚫ 已退役: ${stats.retired}`,
|
|
861
|
+
)
|
|
862
|
+
lines.push(`平均成功率: ${Math.round(stats.avgSuccessRate * 100)}%`)
|
|
863
|
+
lines.push(`总拦截次数: ${stats.totalInterceptions}`)
|
|
864
|
+
return { content: lines.join('\n') }
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
const sisClearCmd: CommandHandler = (ctx, args) => {
|
|
868
|
+
const db = ctx.engine.getErrorSignatureDB?.()
|
|
869
|
+
if (!db) {
|
|
870
|
+
return { content: 'SIS 自免疫系统未初始化。' }
|
|
871
|
+
}
|
|
872
|
+
const sigId = args[0]?.trim()
|
|
873
|
+
if (!sigId) {
|
|
874
|
+
return { content: 'Usage: /sis clear <signature-id>\n\n使用 `/sis errors` 查看所有签名 ID。' }
|
|
875
|
+
}
|
|
876
|
+
const sig = db.get(sigId)
|
|
877
|
+
if (!sig) {
|
|
878
|
+
return { content: `签名 \`${sigId}\` 未找到。` }
|
|
879
|
+
}
|
|
880
|
+
db.retire(sigId)
|
|
881
|
+
return { content: `已退役签名 \`${sigId}\` (${sig.pattern.slice(0, 50)}...)` }
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
const sisCleanupCmd: CommandHandler = async (ctx) => {
|
|
885
|
+
const db = ctx.engine.getErrorSignatureDB?.()
|
|
886
|
+
if (!db) {
|
|
887
|
+
return { content: 'SIS 自免疫系统未初始化。' }
|
|
888
|
+
}
|
|
889
|
+
// Use dynamic import for ESM compatibility
|
|
890
|
+
const { ImmuneMemoryGC } = await import('../../src/core/immune-memory-gc.js')
|
|
891
|
+
const gc = new ImmuneMemoryGC(db)
|
|
892
|
+
const report = gc.collect()
|
|
893
|
+
const lines: string[] = ['## 🧹 SIS 免疫记忆清理完成', '']
|
|
894
|
+
lines.push(`清理前: ${report.before} 条签名`)
|
|
895
|
+
lines.push(`清理后: ${report.after} 条签名`)
|
|
896
|
+
lines.push('')
|
|
897
|
+
if (report.retiredRemoved > 0) lines.push(`🗑️ 移除过期退役: ${report.retiredRemoved} 条`)
|
|
898
|
+
if (report.zeroSuccessRetired > 0) lines.push(`⚠️ 退役零成功率: ${report.zeroSuccessRetired} 条`)
|
|
899
|
+
if (report.duplicatesMerged > 0) lines.push(`🔗 合并重复签名: ${report.duplicatesMerged} 条`)
|
|
900
|
+
if (
|
|
901
|
+
report.retiredRemoved === 0 &&
|
|
902
|
+
report.zeroSuccessRetired === 0 &&
|
|
903
|
+
report.duplicatesMerged === 0
|
|
904
|
+
) {
|
|
905
|
+
lines.push('✅ 免疫记忆干净,无需清理')
|
|
906
|
+
}
|
|
907
|
+
return { content: lines.join('\n') }
|
|
908
|
+
}
|
|
909
|
+
|
|
659
910
|
// ═══════════════════════════════════════════════════════════════
|
|
660
911
|
// Workflow
|
|
661
912
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -3288,6 +3539,11 @@ const commandsListCmd: CommandHandler = () => {
|
|
|
3288
3539
|
'/crsi analyze': 'Tools & Skills',
|
|
3289
3540
|
'/crsi restore': 'Tools & Skills',
|
|
3290
3541
|
'/crsi stats': 'Tools & Skills',
|
|
3542
|
+
'/crsi health': 'Tools & Skills',
|
|
3543
|
+
'/crsi meta': 'Tools & Skills',
|
|
3544
|
+
'/sis errors': 'Tools & Skills',
|
|
3545
|
+
'/sis stats': 'Tools & Skills',
|
|
3546
|
+
'/sis clear': 'Tools & Skills',
|
|
3291
3547
|
'/plan': 'Workflow',
|
|
3292
3548
|
'/no-plan': 'Workflow',
|
|
3293
3549
|
'/tdd': 'Workflow',
|
|
@@ -3432,6 +3688,12 @@ registry.set('/crsi disable', crsiDisableCmd)
|
|
|
3432
3688
|
registry.set('/crsi analyze', crsiAnalyzeCmd)
|
|
3433
3689
|
registry.set('/crsi restore', crsiRestoreCmd)
|
|
3434
3690
|
registry.set('/crsi stats', crsiStatsCmd)
|
|
3691
|
+
registry.set('/crsi health', crsiHealthCmd)
|
|
3692
|
+
registry.set('/crsi meta', crsiMetaCmd)
|
|
3693
|
+
registry.set('/sis errors', sisErrorsCmd)
|
|
3694
|
+
registry.set('/sis stats', sisStatsCmd)
|
|
3695
|
+
registry.set('/sis clear', sisClearCmd)
|
|
3696
|
+
registry.set('/sis cleanup', sisCleanupCmd)
|
|
3435
3697
|
|
|
3436
3698
|
// Workflow
|
|
3437
3699
|
registry.set('/plan', planCmd)
|
|
@@ -3588,6 +3850,12 @@ const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
|
3588
3850
|
'/crsi analyze': 'Manually trigger CRSI pattern analysis across all agents',
|
|
3589
3851
|
'/crsi restore': 'Restore a disabled or degraded CRSI rule',
|
|
3590
3852
|
'/crsi stats': 'Show CRSI overall effectiveness statistics',
|
|
3853
|
+
'/crsi health': 'CRSI + SIS unified health dashboard with scoring',
|
|
3854
|
+
'/crsi meta': 'RSI Level 3 meta-rule analysis — rules that improve the rules',
|
|
3855
|
+
'/sis errors': 'List all active SIS immune memory signatures',
|
|
3856
|
+
'/sis stats': 'Show SIS self-immune system aggregate statistics',
|
|
3857
|
+
'/sis clear': 'Retire an immune memory signature by ID',
|
|
3858
|
+
'/sis cleanup': 'Run immune memory garbage collection (dedup + cleanup)',
|
|
3591
3859
|
'/plan': 'Enter plan mode',
|
|
3592
3860
|
'/no-plan': 'Exit plan mode',
|
|
3593
3861
|
'/tdd': 'Test-Driven Development workflow (RED → GREEN → REFACTOR)',
|