principles-disciple 1.28.1 → 1.28.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/openclaw.plugin.json +4 -4
- package/package.json +1 -1
- package/src/commands/archive-impl.ts +3 -0
- package/src/commands/context.ts +4 -0
- package/src/commands/disable-impl.ts +2 -0
- package/src/commands/evolution-status.ts +2 -0
- package/src/commands/focus.ts +4 -0
- package/src/commands/nocturnal-train.ts +9 -1
- package/src/commands/pain.ts +3 -0
- package/src/commands/pd-reflect.ts +2 -0
- package/src/commands/principle-rollback.ts +1 -0
- package/src/commands/rollback-impl.ts +5 -0
- package/src/commands/rollback.ts +2 -1
- package/src/commands/samples.ts +1 -0
- package/src/commands/workflow-debug.ts +1 -0
- package/src/core/adaptive-thresholds.ts +2 -0
- package/src/core/code-implementation-storage.ts +2 -0
- package/src/core/config.ts +1 -0
- package/src/core/diagnostician-task-store.ts +2 -0
- package/src/core/dictionary.ts +1 -0
- package/src/core/empathy-keyword-matcher.ts +4 -0
- package/src/core/event-log.ts +6 -1
- package/src/core/evolution-engine.ts +4 -0
- package/src/core/evolution-logger.ts +1 -0
- package/src/core/external-training-contract.ts +2 -0
- package/src/core/focus-history.ts +15 -0
- package/src/core/init.ts +3 -0
- package/src/core/merge-gate-audit.ts +3 -0
- package/src/core/model-deployment-registry.ts +1 -0
- package/src/core/model-training-registry.ts +1 -0
- package/src/core/nocturnal-arbiter.ts +4 -0
- package/src/core/nocturnal-candidate-scoring.ts +5 -0
- package/src/core/nocturnal-compliance.ts +22 -0
- package/src/core/nocturnal-dataset.ts +3 -0
- package/src/core/nocturnal-executability.ts +1 -0
- package/src/core/nocturnal-export.ts +5 -0
- package/src/core/nocturnal-reasoning-deriver.ts +6 -0
- package/src/core/nocturnal-rule-implementation-validator.ts +1 -0
- package/src/core/nocturnal-snapshot-contract.ts +1 -0
- package/src/core/nocturnal-trinity.ts +24 -0
- package/src/core/pain-context-extractor.ts +3 -0
- package/src/core/pain.ts +3 -0
- package/src/core/pd-task-reconciler.ts +3 -0
- package/src/core/pd-task-service.ts +1 -0
- package/src/core/pd-task-store.ts +1 -0
- package/src/core/principle-internalization/deprecated-readiness.ts +2 -0
- package/src/core/principle-internalization/principle-lifecycle-service.ts +1 -0
- package/src/core/principle-training-state.ts +2 -0
- package/src/core/principle-tree-ledger.ts +4 -0
- package/src/core/principle-tree-migration.ts +2 -0
- package/src/core/promotion-gate.ts +7 -1
- package/src/core/replay-engine.ts +10 -0
- package/src/core/risk-calculator.ts +2 -0
- package/src/core/rule-host.ts +3 -0
- package/src/core/session-tracker.ts +5 -0
- package/src/core/shadow-observation-registry.ts +1 -0
- package/src/core/thinking-models.ts +1 -0
- package/src/core/thinking-os-parser.ts +1 -0
- package/src/core/trajectory.ts +9 -1
- package/src/hooks/bash-risk.ts +2 -0
- package/src/hooks/edit-verification.ts +3 -0
- package/src/hooks/gate-block-helper.ts +3 -0
- package/src/hooks/gate.ts +8 -0
- package/src/hooks/gfi-gate.ts +2 -0
- package/src/hooks/lifecycle-routing.ts +1 -0
- package/src/hooks/lifecycle.ts +1 -0
- package/src/hooks/llm.ts +1 -0
- package/src/hooks/pain.ts +3 -0
- package/src/hooks/progressive-trust-gate.ts +3 -0
- package/src/hooks/prompt.ts +5 -1
- package/src/hooks/subagent.ts +1 -0
- package/src/hooks/thinking-checkpoint.ts +1 -0
- package/src/hooks/trajectory-collector.ts +2 -0
- package/src/http/principles-console-route.ts +5 -0
- package/src/index.ts +7 -0
- package/src/service/central-database.ts +2 -0
- package/src/service/central-health-service.ts +1 -0
- package/src/service/central-overview-service.ts +2 -0
- package/src/service/central-sync-service.ts +1 -0
- package/src/service/control-ui-query-service.ts +2 -0
- package/src/service/event-log-auditor.ts +2 -0
- package/src/service/evolution-query-service.ts +1 -0
- package/src/service/evolution-worker.ts +31 -0
- package/src/service/health-query-service.ts +6 -1
- package/src/service/monitoring-query-service.ts +4 -0
- package/src/service/nocturnal-runtime.ts +7 -1
- package/src/service/nocturnal-service.ts +21 -0
- package/src/service/nocturnal-target-selector.ts +2 -0
- package/src/service/runtime-summary-service.ts +6 -0
- package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +2 -0
- package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +2 -0
- package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +3 -0
- package/src/service/subagent-workflow/subagent-error-utils.ts +1 -0
- package/src/service/subagent-workflow/workflow-manager-base.ts +6 -0
- package/src/service/subagent-workflow/workflow-store.ts +2 -0
- package/src/tools/critique-prompt.ts +1 -0
- package/src/tools/deep-reflect.ts +9 -0
- package/src/tools/model-index.ts +1 -0
- package/src/tools/write-pain-flag.ts +1 -0
- package/src/utils/file-lock.ts +1 -0
- package/src/utils/io.ts +2 -0
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "principles-disciple",
|
|
3
3
|
"name": "Principles Disciple",
|
|
4
4
|
"description": "Evolutionary programming agent framework with strategic guardrails and reflection loops.",
|
|
5
|
-
"version": "1.28.
|
|
5
|
+
"version": "1.28.3",
|
|
6
6
|
"skills": [
|
|
7
7
|
"./skills"
|
|
8
8
|
],
|
|
@@ -76,8 +76,8 @@
|
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
78
|
"buildFingerprint": {
|
|
79
|
-
"gitSha": "
|
|
80
|
-
"bundleMd5": "
|
|
81
|
-
"builtAt": "2026-04-
|
|
79
|
+
"gitSha": "25bfc2bb209f",
|
|
80
|
+
"bundleMd5": "b735aa483374dd2c7071295b11161676",
|
|
81
|
+
"builtAt": "2026-04-13T14:25:24.799Z"
|
|
82
82
|
}
|
|
83
83
|
}
|
package/package.json
CHANGED
|
@@ -52,12 +52,14 @@ export function handleArchiveImplCommand(ctx: PluginCommandContext): PluginComma
|
|
|
52
52
|
// Subcommand: list
|
|
53
53
|
if (subcommand === 'list') {
|
|
54
54
|
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
55
56
|
return _handleListArchivable(stateDir, isZh);
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
// Archive by ID
|
|
59
60
|
const targetId = subcommand;
|
|
60
61
|
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
61
63
|
return _handleArchiveImpl(workspaceDir, stateDir, targetId, isZh);
|
|
62
64
|
}
|
|
63
65
|
|
|
@@ -95,6 +97,7 @@ function _handleListArchivable(
|
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
98
101
|
function _handleArchiveImpl(
|
|
99
102
|
workspaceDir: string,
|
|
100
103
|
stateDir: string,
|
package/src/commands/context.ts
CHANGED
|
@@ -99,6 +99,7 @@ function showStatus(workspaceDir: string, isZh: boolean): string {
|
|
|
99
99
|
* Toggle a boolean setting
|
|
100
100
|
*/
|
|
101
101
|
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
102
103
|
function toggleSetting(
|
|
103
104
|
workspaceDir: string,
|
|
104
105
|
key: 'thinkingOs' | 'reflectionLog',
|
|
@@ -214,6 +215,7 @@ function applyPreset(
|
|
|
214
215
|
isZh: boolean
|
|
215
216
|
): string {
|
|
216
217
|
|
|
218
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
217
219
|
let config: ContextInjectionConfig;
|
|
218
220
|
|
|
219
221
|
switch (preset) {
|
|
@@ -305,6 +307,7 @@ function showHelp(isZh: boolean): string {
|
|
|
305
307
|
/**
|
|
306
308
|
* Main command handler
|
|
307
309
|
*/
|
|
310
|
+
|
|
308
311
|
export function handleContextCommand(ctx: PluginCommandContext): PluginCommandResult {
|
|
309
312
|
const workspaceDir = getWorkspaceDir(ctx);
|
|
310
313
|
const args = (ctx.args || '').trim().split(/\s+/);
|
|
@@ -315,6 +318,7 @@ export function handleContextCommand(ctx: PluginCommandContext): PluginCommandRe
|
|
|
315
318
|
const isZh = (ctx.config?.language as string) === 'zh';
|
|
316
319
|
|
|
317
320
|
|
|
321
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
318
322
|
let result: string;
|
|
319
323
|
|
|
320
324
|
switch (subCommand) {
|
|
@@ -70,6 +70,7 @@ function _handleListActive(
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/max-params -- complexity 15, refactor candidate
|
|
73
74
|
function _handleDisableImpl(
|
|
74
75
|
workspaceDir: string,
|
|
75
76
|
stateDir: string,
|
|
@@ -130,6 +131,7 @@ function _handleDisableImpl(
|
|
|
130
131
|
* /pd-disable-impl <implId> - Disable an implementation
|
|
131
132
|
* /pd-disable-impl <implId> --reason "<reason>" - Disable with reason
|
|
132
133
|
*/
|
|
134
|
+
|
|
133
135
|
export function handleDisableImplCommand(ctx: PluginCommandContext): PluginCommandResult {
|
|
134
136
|
const workspaceDir = (ctx.config?.workspaceDir as string) || process.cwd();
|
|
135
137
|
const {stateDir} = WorkspaceContext.fromHookContext({ ...ctx, workspaceDir });
|
|
@@ -46,6 +46,7 @@ function formatRouteRecommendations(
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/max-params -- complexity 15, refactor candidate
|
|
49
50
|
function buildEnglishOutput(
|
|
50
51
|
workspaceDir: string,
|
|
51
52
|
sessionId: string | null,
|
|
@@ -98,6 +99,7 @@ function buildEnglishOutput(
|
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/max-params -- complexity 15, refactor candidate
|
|
101
103
|
function buildChineseOutput(
|
|
102
104
|
workspaceDir: string,
|
|
103
105
|
sessionId: string | null,
|
package/src/commands/focus.ts
CHANGED
|
@@ -47,6 +47,7 @@ function getWorkspaceDir(ctx: PluginCommandContext): string {
|
|
|
47
47
|
* - 清理:Working Memory 超过 10 条记录时保留最近 10 条
|
|
48
48
|
* - 验证:文件引用指向不存在的文件时移除
|
|
49
49
|
*/
|
|
50
|
+
|
|
50
51
|
function compressFocusContent(content: string, workspaceDir?: string): string {
|
|
51
52
|
// 首先使用 cleanupStaleInfo 进行基础清理
|
|
52
53
|
let result = cleanupStaleInfo(content, workspaceDir);
|
|
@@ -282,6 +283,7 @@ async function compressFocus(
|
|
|
282
283
|
|
|
283
284
|
// 5. 压缩内容
|
|
284
285
|
|
|
286
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
285
287
|
let compressedContent: string;
|
|
286
288
|
try {
|
|
287
289
|
compressedContent = compressFocusContent(oldContent, workspaceDir);
|
|
@@ -346,6 +348,7 @@ ${milestoneNote ? `${milestoneNote}\n` : ''}
|
|
|
346
348
|
/**
|
|
347
349
|
* 回滚到历史版本
|
|
348
350
|
*/
|
|
351
|
+
|
|
349
352
|
function rollbackFocus(workspaceDir: string, index: number, isZh: boolean): string {
|
|
350
353
|
const wctx = WorkspaceContext.fromHookContext({ workspaceDir });
|
|
351
354
|
const focusPath = wctx.resolve('CURRENT_FOCUS');
|
|
@@ -478,6 +481,7 @@ export async function handleFocusCommand(
|
|
|
478
481
|
const isZh = (ctx.config?.language as string) === 'zh';
|
|
479
482
|
|
|
480
483
|
|
|
484
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
481
485
|
let result: string;
|
|
482
486
|
|
|
483
487
|
switch (subCommand) {
|
|
@@ -285,6 +285,7 @@ Hardware tiers:
|
|
|
285
285
|
fs.writeFileSync(specPath, JSON.stringify(spec, null, 2), 'utf-8');
|
|
286
286
|
|
|
287
287
|
|
|
288
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
288
289
|
let trainerResult!: TrainingExperimentResult;
|
|
289
290
|
|
|
290
291
|
try {
|
|
@@ -393,6 +394,7 @@ Hardware tiers:
|
|
|
393
394
|
// Process trainer result (register checkpoint)
|
|
394
395
|
// dry_run returns null (no checkpoint); other statuses throw on error
|
|
395
396
|
|
|
397
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
396
398
|
let processed: { checkpointId: string; checkpointRef: string } | null;
|
|
397
399
|
try {
|
|
398
400
|
processed = program.processResult({
|
|
@@ -534,7 +536,7 @@ Next steps:
|
|
|
534
536
|
}
|
|
535
537
|
}
|
|
536
538
|
|
|
537
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Reason: JSON.parse returns dynamic JSON - type unknown at parse time, narrowed via type narrowing below
|
|
539
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/init-declarations -- Reason: JSON.parse returns dynamic JSON - type unknown at parse time, narrowed via type narrowing below
|
|
538
540
|
let result: any;
|
|
539
541
|
try {
|
|
540
542
|
result = JSON.parse(resultJson);
|
|
@@ -566,6 +568,7 @@ Next steps:
|
|
|
566
568
|
// Process the result
|
|
567
569
|
const program = new TrainingProgram(workspaceDir);
|
|
568
570
|
|
|
571
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
569
572
|
let processed: { checkpointId: string; checkpointRef: string } | null;
|
|
570
573
|
try {
|
|
571
574
|
processed = program.processResult({
|
|
@@ -753,10 +756,15 @@ Next steps:
|
|
|
753
756
|
}
|
|
754
757
|
|
|
755
758
|
// Destructure benchmark result - delta property contains the actual delta value
|
|
759
|
+
// eslint-disable-next-line @typescript-eslint/prefer-destructuring
|
|
756
760
|
delta = benchmarkResult.delta.delta;
|
|
761
|
+
// eslint-disable-next-line @typescript-eslint/prefer-destructuring
|
|
757
762
|
baselineScore = benchmarkResult.delta.baselineScore;
|
|
763
|
+
// eslint-disable-next-line @typescript-eslint/prefer-destructuring
|
|
758
764
|
candidateScore = benchmarkResult.delta.candidateScore;
|
|
765
|
+
// eslint-disable-next-line @typescript-eslint/prefer-destructuring
|
|
759
766
|
benchmarkId = benchmarkResult.benchmarkId;
|
|
767
|
+
// eslint-disable-next-line @typescript-eslint/prefer-destructuring
|
|
760
768
|
verdict = benchmarkResult.verdict;
|
|
761
769
|
} else {
|
|
762
770
|
// Manual mode: require explicit delta and verdict
|
package/src/commands/pain.ts
CHANGED
|
@@ -97,6 +97,7 @@ export function handlePainCommand(ctx: PluginCommandContext): PluginCommandResul
|
|
|
97
97
|
// Handle empathy subcommand
|
|
98
98
|
if (args.startsWith('empathy')) {
|
|
99
99
|
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
100
101
|
return handleEmpathySubcommand(wctx, args, sessionId, isZh);
|
|
101
102
|
}
|
|
102
103
|
|
|
@@ -137,6 +138,7 @@ export function handlePainCommand(ctx: PluginCommandContext): PluginCommandResul
|
|
|
137
138
|
|
|
138
139
|
// Determine health status based on GFI
|
|
139
140
|
|
|
141
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
140
142
|
let healthLabel: string;
|
|
141
143
|
let suggestionText = '';
|
|
142
144
|
|
|
@@ -216,6 +218,7 @@ export function handlePainCommand(ctx: PluginCommandContext): PluginCommandResul
|
|
|
216
218
|
* Handle /pd-status empathy subcommand
|
|
217
219
|
*/
|
|
218
220
|
|
|
221
|
+
// eslint-disable-next-line @typescript-eslint/max-params -- complexity 13, refactor candidate
|
|
219
222
|
function handleEmpathySubcommand(
|
|
220
223
|
wctx: WorkspaceContext,
|
|
221
224
|
args: string,
|
|
@@ -22,6 +22,7 @@ export const handlePdReflect: PluginCommandDefinition = {
|
|
|
22
22
|
requireAuth: false,
|
|
23
23
|
handler: async (ctx: PdReflectContext): Promise<PluginCommandResult> => {
|
|
24
24
|
try {
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/prefer-destructuring
|
|
25
26
|
const workspaceDir = ctx.workspaceDir;
|
|
26
27
|
if (!workspaceDir) {
|
|
27
28
|
return { text: 'Cannot determine workspace directory. Ensure you are in an active workspace.', isError: true };
|
|
@@ -32,6 +33,7 @@ export const handlePdReflect: PluginCommandDefinition = {
|
|
|
32
33
|
|
|
33
34
|
// Acquire lock before modifying queue
|
|
34
35
|
const releaseLock = await acquireQueueLock(queuePath, ctx.api?.logger, EVOLUTION_QUEUE_LOCK_SUFFIX);
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
35
37
|
let taskId: string | undefined;
|
|
36
38
|
try {
|
|
37
39
|
let rawQueue: unknown[] = [];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { WorkspaceContext } from '../core/workspace-context.js';
|
|
2
2
|
import type { PluginCommandContext } from '../openclaw-sdk.js';
|
|
3
3
|
|
|
4
|
+
// eslint-disable-next-line complexity -- complexity 13, refactor candidate
|
|
4
5
|
export function handlePrincipleRollbackCommand(ctx: PluginCommandContext): { text: string } {
|
|
5
6
|
const workspaceDir = (ctx.config?.workspaceDir as string) || process.cwd();
|
|
6
7
|
const argText = (ctx.args || '').trim();
|
|
@@ -41,6 +41,7 @@ function getAllImplementations(stateDir: string): Implementation[] {
|
|
|
41
41
|
* /pd-rollback-impl <implId> - Rollback current active
|
|
42
42
|
* /pd-rollback-impl <implId> --reason "<reason>" - Rollback with reason
|
|
43
43
|
*/
|
|
44
|
+
|
|
44
45
|
export function handleRollbackImplCommand(ctx: PluginCommandContext): PluginCommandResult {
|
|
45
46
|
const workspaceDir = (ctx.config?.workspaceDir as string) || process.cwd();
|
|
46
47
|
const {stateDir} = WorkspaceContext.fromHookContext({ ...ctx, workspaceDir });
|
|
@@ -58,10 +59,12 @@ export function handleRollbackImplCommand(ctx: PluginCommandContext): PluginComm
|
|
|
58
59
|
// List active
|
|
59
60
|
if (subcommand === 'list' || subcommand === '') {
|
|
60
61
|
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
61
63
|
return _handleListActiveRollback(stateDir, isZh);
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
65
68
|
return _handleRollbackImpl(workspaceDir, stateDir, implId, reason, isZh, ctx.sessionId);
|
|
66
69
|
}
|
|
67
70
|
|
|
@@ -104,6 +107,7 @@ function _handleListActiveRollback(
|
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
107
111
|
function _handleRollbackImpl(
|
|
108
112
|
workspaceDir: string,
|
|
109
113
|
stateDir: string,
|
|
@@ -139,6 +143,7 @@ function _handleRollbackImpl(
|
|
|
139
143
|
transitionImplementationState(stateDir, implId, 'disabled');
|
|
140
144
|
|
|
141
145
|
|
|
146
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
142
147
|
let restoredMessage: string;
|
|
143
148
|
|
|
144
149
|
if (previousActiveId && allImpls.some((i) => i.id === previousActiveId)) {
|
package/src/commands/rollback.ts
CHANGED
|
@@ -45,8 +45,9 @@ Usage:
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
48
49
|
let eventId: string | null;
|
|
49
|
-
|
|
50
|
+
|
|
50
51
|
const _triggerMethod = 'user_command' as const;
|
|
51
52
|
|
|
52
53
|
if (args === 'last') {
|
package/src/commands/samples.ts
CHANGED
|
@@ -30,6 +30,7 @@ export function handleSamplesCommand(ctx: PluginCommandContext): PluginCommandRe
|
|
|
30
30
|
const normalizedDecision = decision === 'approve' ? 'approved' : 'rejected';
|
|
31
31
|
const note = noteParts.join(' ').trim();
|
|
32
32
|
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
33
34
|
let record;
|
|
34
35
|
try {
|
|
35
36
|
record = wctx.trajectory.reviewCorrectionSample(sampleId, normalizedDecision, note);
|
|
@@ -301,6 +301,7 @@ export function getEffectiveThresholds(stateDir: string): ThresholdValues {
|
|
|
301
301
|
* @returns UpdateThresholdResult
|
|
302
302
|
*/
|
|
303
303
|
|
|
304
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
304
305
|
export function updateThresholdState(
|
|
305
306
|
stateDir: string,
|
|
306
307
|
thresholdName: ThresholdName,
|
|
@@ -407,6 +408,7 @@ export function getDetailedThresholdState(
|
|
|
407
408
|
* @param signals - Observable signals
|
|
408
409
|
* @returns UpdateThresholdResult describing the most significant change
|
|
409
410
|
*/
|
|
411
|
+
|
|
410
412
|
export function adjustThresholdsFromSignals(
|
|
411
413
|
stateDir: string,
|
|
412
414
|
signals: ThresholdSignals
|
|
@@ -135,6 +135,7 @@ export function writeManifest(
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
138
139
|
export function writeEntrySource(
|
|
139
140
|
stateDir: string,
|
|
140
141
|
implId: string,
|
|
@@ -190,6 +191,7 @@ export function loadEntrySource(stateDir: string, implId: string): string | null
|
|
|
190
191
|
* Idempotent: calling again with the same implId will NOT overwrite an existing entry.js.
|
|
191
192
|
*/
|
|
192
193
|
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
193
195
|
export function createImplementationAssetDir(
|
|
194
196
|
stateDir: string,
|
|
195
197
|
implId: string,
|
package/src/core/config.ts
CHANGED
|
@@ -291,6 +291,7 @@ export class PainConfig {
|
|
|
291
291
|
* Basic validation for critical settings
|
|
292
292
|
*/
|
|
293
293
|
|
|
294
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
294
295
|
private validate(settings: PainSettings): void {
|
|
295
296
|
// Ensure intervals are positive
|
|
296
297
|
if (settings.intervals.worker_poll_ms < 1000) settings.intervals.worker_poll_ms = 15 * 60 * 1000;
|
|
@@ -83,6 +83,7 @@ export async function addDiagnosticianTask(
|
|
|
83
83
|
const filePath = resolveTasksPath(stateDir);
|
|
84
84
|
await withLockAsync(filePath, async () => {
|
|
85
85
|
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
86
87
|
const store = readTaskStoreSync(filePath);
|
|
87
88
|
store.tasks[taskId] = {
|
|
88
89
|
prompt,
|
|
@@ -106,6 +107,7 @@ export async function completeDiagnosticianTask(
|
|
|
106
107
|
const filePath = resolveTasksPath(stateDir);
|
|
107
108
|
await withLockAsync(filePath, async () => {
|
|
108
109
|
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
109
111
|
const store = readTaskStoreSync(filePath);
|
|
110
112
|
delete store.tasks[taskId];
|
|
111
113
|
const tmpPath = filePath + '.tmp';
|
package/src/core/dictionary.ts
CHANGED
|
@@ -116,6 +116,7 @@ export class PainDictionary {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// eslint-disable-next-line complexity -- complexity 13, refactor candidate
|
|
119
120
|
match(text: string): { ruleId: string; severity: number } | undefined {
|
|
120
121
|
if (shouldIgnorePainProtocolText(text)) return undefined;
|
|
121
122
|
|
|
@@ -81,6 +81,7 @@ export function loadKeywordStore(stateDir: string, language?: 'zh' | 'en'): Empa
|
|
|
81
81
|
if (!fs.existsSync(filePath)) {
|
|
82
82
|
const store = createDefaultKeywordStore(language);
|
|
83
83
|
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
84
85
|
saveKeywordStore(stateDir, store);
|
|
85
86
|
return store;
|
|
86
87
|
}
|
|
@@ -93,6 +94,7 @@ export function loadKeywordStore(stateDir: string, language?: 'zh' | 'en'): Empa
|
|
|
93
94
|
console.warn('[PD:Empathy] Invalid keyword store format, creating default');
|
|
94
95
|
const store = createDefaultKeywordStore(language);
|
|
95
96
|
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
96
98
|
saveKeywordStore(stateDir, store);
|
|
97
99
|
return store;
|
|
98
100
|
}
|
|
@@ -102,6 +104,7 @@ export function loadKeywordStore(stateDir: string, language?: 'zh' | 'en'): Empa
|
|
|
102
104
|
console.warn(`[PD:Empathy] Failed to load keyword store: ${e}`);
|
|
103
105
|
const store = createDefaultKeywordStore(language);
|
|
104
106
|
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
105
108
|
saveKeywordStore(stateDir, store);
|
|
106
109
|
return store;
|
|
107
110
|
}
|
|
@@ -207,6 +210,7 @@ export function matchEmpathyKeywords(
|
|
|
207
210
|
* This is called when the empathy optimizer subagent completes its analysis
|
|
208
211
|
* and returns suggested updates to the keyword store.
|
|
209
212
|
*/
|
|
213
|
+
|
|
210
214
|
export function applyKeywordUpdates(
|
|
211
215
|
store: EmpathyKeywordStore,
|
|
212
216
|
updates: Record<string, {
|
package/src/core/event-log.ts
CHANGED
|
@@ -108,6 +108,7 @@ export class EventLog {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
111
112
|
private record(
|
|
112
113
|
type: EventType,
|
|
113
114
|
category: EventCategory,
|
|
@@ -135,6 +136,7 @@ export class EventLog {
|
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
138
140
|
private formatDate(date: Date): string {
|
|
139
141
|
return date.toISOString().split('T')[0];
|
|
140
142
|
}
|
|
@@ -160,7 +162,7 @@ export class EventLog {
|
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
if (entry.type === 'tool_call') {
|
|
163
|
-
|
|
165
|
+
|
|
164
166
|
const _data = entry.data as unknown as ToolCallEventData;
|
|
165
167
|
stats.tools.total++;
|
|
166
168
|
if (entry.category === 'success') stats.tools.success++;
|
|
@@ -244,6 +246,7 @@ export class EventLog {
|
|
|
244
246
|
}
|
|
245
247
|
|
|
246
248
|
|
|
249
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this -- complexity 13, refactor candidate
|
|
247
250
|
private getEventDedupKey(entry: EventLogEntry): string {
|
|
248
251
|
const eventId = typeof (entry.data as { eventId?: unknown } | undefined)?.eventId === 'string'
|
|
249
252
|
? String((entry.data as { eventId?: string }).eventId)
|
|
@@ -340,6 +343,7 @@ export class EventLog {
|
|
|
340
343
|
* @param range 'today' | 'week' | 'session'
|
|
341
344
|
* @param sessionId Optional session ID for session-scoped stats
|
|
342
345
|
*/
|
|
346
|
+
|
|
343
347
|
getEmpathyStats(range: 'today' | 'week' | 'session', sessionId?: string): EmpathyEventStats {
|
|
344
348
|
const now = new Date();
|
|
345
349
|
const today = this.formatDate(now);
|
|
@@ -460,6 +464,7 @@ export class EventLog {
|
|
|
460
464
|
* Returns the rolled back score, or 0 if event not found.
|
|
461
465
|
*/
|
|
462
466
|
|
|
467
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
463
468
|
rollbackEmpathyEvent(eventId: string, sessionId: string | undefined, reason: string, triggeredBy: 'user_command' | 'natural_language' | 'system'): number {
|
|
464
469
|
const allEvents = this.getMergedEvents();
|
|
465
470
|
let foundEvent: { entry: EventLogEntry; data: PainSignalEventData } | null = null;
|
|
@@ -165,6 +165,7 @@ export class EvolutionEngine {
|
|
|
165
165
|
|
|
166
166
|
// ===== 记录失败 =====
|
|
167
167
|
|
|
168
|
+
|
|
168
169
|
public recordFailure(
|
|
169
170
|
toolName: string,
|
|
170
171
|
options?: {
|
|
@@ -324,6 +325,7 @@ export class EvolutionEngine {
|
|
|
324
325
|
// ===== 事件管理 =====
|
|
325
326
|
|
|
326
327
|
|
|
328
|
+
// eslint-disable-next-line @typescript-eslint/max-params
|
|
327
329
|
private createEvent(
|
|
328
330
|
type: 'success' | 'failure',
|
|
329
331
|
taskHash: string,
|
|
@@ -386,6 +388,7 @@ export class EvolutionEngine {
|
|
|
386
388
|
}
|
|
387
389
|
|
|
388
390
|
|
|
391
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
389
392
|
private createNewScorecard(): EvolutionScorecard {
|
|
390
393
|
const now = new Date().toISOString();
|
|
391
394
|
return {
|
|
@@ -528,6 +531,7 @@ export class EvolutionEngine {
|
|
|
528
531
|
// ===== 工具方法 =====
|
|
529
532
|
|
|
530
533
|
|
|
534
|
+
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
531
535
|
private generateId(): string {
|
|
532
536
|
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
533
537
|
}
|
|
@@ -265,6 +265,7 @@ export class EvolutionLogger {
|
|
|
265
265
|
principlesGenerated?: number;
|
|
266
266
|
}): void {
|
|
267
267
|
|
|
268
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
268
269
|
let summary: string;
|
|
269
270
|
if (params.resolution === 'marker_detected' || params.resolution === 'late_marker_principle_created') {
|
|
270
271
|
summary = `任务 ${params.taskId} 完成,已生成 ${params.principlesGenerated || 0} 条原则`;
|
|
@@ -285,6 +285,7 @@ export interface ValidationResult {
|
|
|
285
285
|
* @param result - The trainer result to validate
|
|
286
286
|
* @returns ValidationResult indicating pass/fail and any errors
|
|
287
287
|
*/
|
|
288
|
+
|
|
288
289
|
export function validateTrainerResult(
|
|
289
290
|
spec: TrainingExperimentSpec,
|
|
290
291
|
result: TrainingExperimentResult
|
|
@@ -404,6 +405,7 @@ export function computeConfigFingerprint(config: Partial<TrainingHyperparameters
|
|
|
404
405
|
*/
|
|
405
406
|
export function computeDatasetFingerprint(exportPath: string, sampleCount: number): string {
|
|
406
407
|
|
|
408
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
407
409
|
let contentHash: string;
|
|
408
410
|
try {
|
|
409
411
|
const content = fs.readFileSync(exportPath, 'utf-8');
|
|
@@ -265,6 +265,7 @@ export function compressFocus(focusPath: string, newContent: string): {
|
|
|
265
265
|
* @param content CURRENT_FOCUS.md 内容
|
|
266
266
|
* @param maxLines 最大行数
|
|
267
267
|
*/
|
|
268
|
+
|
|
268
269
|
export function extractSummary(content: string, maxLines = 30): string {
|
|
269
270
|
const lines = content.split('\n');
|
|
270
271
|
const sections: { [key: string]: string[] } = {
|
|
@@ -429,6 +430,7 @@ export function extractWorkingMemory(
|
|
|
429
430
|
|
|
430
431
|
// 尝试从文本中提取描述
|
|
431
432
|
|
|
433
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
432
434
|
const description = extractDescription(text, filePath);
|
|
433
435
|
|
|
434
436
|
snapshot.artifacts.push({
|
|
@@ -444,19 +446,23 @@ export function extractWorkingMemory(
|
|
|
444
446
|
|
|
445
447
|
// 从文本中提取文件操作(备用方式)
|
|
446
448
|
|
|
449
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
447
450
|
extractFileArtifacts(text, snapshot.artifacts, workspaceDir);
|
|
448
451
|
|
|
449
452
|
// 提取问题
|
|
450
453
|
|
|
454
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
451
455
|
extractProblems(text, snapshot.activeProblems);
|
|
452
456
|
|
|
453
457
|
// 提取下一步
|
|
454
458
|
|
|
459
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
455
460
|
extractNextActions(text, snapshot.nextActions);
|
|
456
461
|
}
|
|
457
462
|
|
|
458
463
|
// 去重和限制数量
|
|
459
464
|
|
|
465
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
460
466
|
snapshot.artifacts = deduplicateArtifacts(snapshot.artifacts).slice(-MAX_ARTIFACTS);
|
|
461
467
|
snapshot.activeProblems = snapshot.activeProblems.slice(-MAX_PROBLEMS);
|
|
462
468
|
snapshot.nextActions = snapshot.nextActions.slice(-MAX_NEXT_ACTIONS);
|
|
@@ -477,6 +483,7 @@ function extractFileArtifacts(
|
|
|
477
483
|
const filePathRegex = /(?:file_path|absolute_path)["']?\s*[:=]\s*["']([^"']+\.(ts|js|json|md|yaml|yml|py|sh|mjs|cjs))["']/gi;
|
|
478
484
|
|
|
479
485
|
|
|
486
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
480
487
|
let match;
|
|
481
488
|
while ((match = filePathRegex.exec(text)) !== null) {
|
|
482
489
|
const [, filePath] = match;
|
|
@@ -507,6 +514,7 @@ function extractFileArtifacts(
|
|
|
507
514
|
|
|
508
515
|
// 尝试提取描述(从附近的文本)
|
|
509
516
|
|
|
517
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
510
518
|
const description = extractDescription(text, filePath);
|
|
511
519
|
|
|
512
520
|
artifacts.push({
|
|
@@ -540,6 +548,7 @@ function extractFileArtifacts(
|
|
|
540
548
|
}
|
|
541
549
|
|
|
542
550
|
|
|
551
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
543
552
|
const description = extractDescription(text, filePath);
|
|
544
553
|
|
|
545
554
|
artifacts.push({
|
|
@@ -588,6 +597,7 @@ function extractProblems(
|
|
|
588
597
|
// 问题模式(匹配问题描述)
|
|
589
598
|
const problemPattern = /(?:问题|problem|error|错误|失败|failed)[::]\s*([^\n]{5,100})/gi;
|
|
590
599
|
|
|
600
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
591
601
|
let match;
|
|
592
602
|
while ((match = problemPattern.exec(text)) !== null) {
|
|
593
603
|
const content = match[1].trim();
|
|
@@ -631,6 +641,7 @@ function extractNextActions(text: string, actions: string[]): void {
|
|
|
631
641
|
|
|
632
642
|
for (const pattern of patterns) {
|
|
633
643
|
|
|
644
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
634
645
|
let match;
|
|
635
646
|
while ((match = pattern.exec(text)) !== null) {
|
|
636
647
|
const action = match[1].trim();
|
|
@@ -690,6 +701,7 @@ export function parseWorkingMemorySection(content: string): WorkingMemorySnapsho
|
|
|
690
701
|
// | 文件路径 | 操作 | 描述 |
|
|
691
702
|
const tableRegex = /\|\s*`?([^`|\n]+)`?\s*\|\s*(created|modified|deleted)\s*\|\s*([^|\n]*)\s*\|/gi;
|
|
692
703
|
|
|
704
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
693
705
|
let match;
|
|
694
706
|
while ((match = tableRegex.exec(wmContent)) !== null) {
|
|
695
707
|
snapshot.artifacts.push({
|
|
@@ -729,6 +741,7 @@ export function mergeWorkingMemory(content: string, snapshot: WorkingMemorySnaps
|
|
|
729
741
|
|
|
730
742
|
// 生成 Working Memory 章节
|
|
731
743
|
|
|
744
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
732
745
|
const wmSection = generateWorkingMemorySection(snapshot);
|
|
733
746
|
|
|
734
747
|
if (wmIndex === -1) {
|
|
@@ -805,6 +818,7 @@ function generateWorkingMemorySection(snapshot: WorkingMemorySnapshot): string {
|
|
|
805
818
|
/**
|
|
806
819
|
* 生成工作记忆注入字符串(用于 prompt 注入)
|
|
807
820
|
*/
|
|
821
|
+
|
|
808
822
|
export function workingMemoryToInjection(snapshot: WorkingMemorySnapshot | null): string {
|
|
809
823
|
if (!snapshot) return '';
|
|
810
824
|
|
|
@@ -884,6 +898,7 @@ interface CompressionConfig {
|
|
|
884
898
|
* @param stateDir state 目录路径
|
|
885
899
|
* @returns 压缩配置
|
|
886
900
|
*/
|
|
901
|
+
|
|
887
902
|
function loadCompressionConfig(stateDir?: string): CompressionConfig {
|
|
888
903
|
if (!stateDir) {
|
|
889
904
|
return DEFAULT_COMPRESSION_CONFIG;
|
package/src/core/init.ts
CHANGED
|
@@ -34,6 +34,7 @@ function hasOutdatedCoreGuidance(file: string, content: string): boolean {
|
|
|
34
34
|
* Ensures that the workspace has the necessary template files for Principles Disciple.
|
|
35
35
|
* This function flattens 'core' templates to the root so OpenClaw can find them.
|
|
36
36
|
*/
|
|
37
|
+
|
|
37
38
|
export function ensureWorkspaceTemplates(api: OpenClawPluginApi, workspaceDir: string, language = 'en') {
|
|
38
39
|
try {
|
|
39
40
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -44,6 +45,7 @@ export function ensureWorkspaceTemplates(api: OpenClawPluginApi, workspaceDir: s
|
|
|
44
45
|
if (fs.existsSync(commonTemplatesDir)) {
|
|
45
46
|
api.logger.info(`[PD] Syncing workspace templates: ${workspaceDir}...`);
|
|
46
47
|
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
47
49
|
copyRecursiveSync(commonTemplatesDir, workspaceDir, api);
|
|
48
50
|
}
|
|
49
51
|
|
|
@@ -86,6 +88,7 @@ export function ensureWorkspaceTemplates(api: OpenClawPluginApi, workspaceDir: s
|
|
|
86
88
|
fs.mkdirSync(painDestDir, { recursive: true });
|
|
87
89
|
}
|
|
88
90
|
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
89
92
|
copyRecursiveSync(painTemplatesDir, painDestDir, api);
|
|
90
93
|
}
|
|
91
94
|
|