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.
Files changed (101) hide show
  1. package/openclaw.plugin.json +4 -4
  2. package/package.json +1 -1
  3. package/src/commands/archive-impl.ts +3 -0
  4. package/src/commands/context.ts +4 -0
  5. package/src/commands/disable-impl.ts +2 -0
  6. package/src/commands/evolution-status.ts +2 -0
  7. package/src/commands/focus.ts +4 -0
  8. package/src/commands/nocturnal-train.ts +9 -1
  9. package/src/commands/pain.ts +3 -0
  10. package/src/commands/pd-reflect.ts +2 -0
  11. package/src/commands/principle-rollback.ts +1 -0
  12. package/src/commands/rollback-impl.ts +5 -0
  13. package/src/commands/rollback.ts +2 -1
  14. package/src/commands/samples.ts +1 -0
  15. package/src/commands/workflow-debug.ts +1 -0
  16. package/src/core/adaptive-thresholds.ts +2 -0
  17. package/src/core/code-implementation-storage.ts +2 -0
  18. package/src/core/config.ts +1 -0
  19. package/src/core/diagnostician-task-store.ts +2 -0
  20. package/src/core/dictionary.ts +1 -0
  21. package/src/core/empathy-keyword-matcher.ts +4 -0
  22. package/src/core/event-log.ts +6 -1
  23. package/src/core/evolution-engine.ts +4 -0
  24. package/src/core/evolution-logger.ts +1 -0
  25. package/src/core/external-training-contract.ts +2 -0
  26. package/src/core/focus-history.ts +15 -0
  27. package/src/core/init.ts +3 -0
  28. package/src/core/merge-gate-audit.ts +3 -0
  29. package/src/core/model-deployment-registry.ts +1 -0
  30. package/src/core/model-training-registry.ts +1 -0
  31. package/src/core/nocturnal-arbiter.ts +4 -0
  32. package/src/core/nocturnal-candidate-scoring.ts +5 -0
  33. package/src/core/nocturnal-compliance.ts +22 -0
  34. package/src/core/nocturnal-dataset.ts +3 -0
  35. package/src/core/nocturnal-executability.ts +1 -0
  36. package/src/core/nocturnal-export.ts +5 -0
  37. package/src/core/nocturnal-reasoning-deriver.ts +6 -0
  38. package/src/core/nocturnal-rule-implementation-validator.ts +1 -0
  39. package/src/core/nocturnal-snapshot-contract.ts +1 -0
  40. package/src/core/nocturnal-trinity.ts +24 -0
  41. package/src/core/pain-context-extractor.ts +3 -0
  42. package/src/core/pain.ts +3 -0
  43. package/src/core/pd-task-reconciler.ts +3 -0
  44. package/src/core/pd-task-service.ts +1 -0
  45. package/src/core/pd-task-store.ts +1 -0
  46. package/src/core/principle-internalization/deprecated-readiness.ts +2 -0
  47. package/src/core/principle-internalization/principle-lifecycle-service.ts +1 -0
  48. package/src/core/principle-training-state.ts +2 -0
  49. package/src/core/principle-tree-ledger.ts +4 -0
  50. package/src/core/principle-tree-migration.ts +2 -0
  51. package/src/core/promotion-gate.ts +7 -1
  52. package/src/core/replay-engine.ts +10 -0
  53. package/src/core/risk-calculator.ts +2 -0
  54. package/src/core/rule-host.ts +3 -0
  55. package/src/core/session-tracker.ts +5 -0
  56. package/src/core/shadow-observation-registry.ts +1 -0
  57. package/src/core/thinking-models.ts +1 -0
  58. package/src/core/thinking-os-parser.ts +1 -0
  59. package/src/core/trajectory.ts +9 -1
  60. package/src/hooks/bash-risk.ts +2 -0
  61. package/src/hooks/edit-verification.ts +3 -0
  62. package/src/hooks/gate-block-helper.ts +3 -0
  63. package/src/hooks/gate.ts +8 -0
  64. package/src/hooks/gfi-gate.ts +2 -0
  65. package/src/hooks/lifecycle-routing.ts +1 -0
  66. package/src/hooks/lifecycle.ts +1 -0
  67. package/src/hooks/llm.ts +1 -0
  68. package/src/hooks/pain.ts +3 -0
  69. package/src/hooks/progressive-trust-gate.ts +3 -0
  70. package/src/hooks/prompt.ts +5 -1
  71. package/src/hooks/subagent.ts +1 -0
  72. package/src/hooks/thinking-checkpoint.ts +1 -0
  73. package/src/hooks/trajectory-collector.ts +2 -0
  74. package/src/http/principles-console-route.ts +5 -0
  75. package/src/index.ts +7 -0
  76. package/src/service/central-database.ts +2 -0
  77. package/src/service/central-health-service.ts +1 -0
  78. package/src/service/central-overview-service.ts +2 -0
  79. package/src/service/central-sync-service.ts +1 -0
  80. package/src/service/control-ui-query-service.ts +2 -0
  81. package/src/service/event-log-auditor.ts +2 -0
  82. package/src/service/evolution-query-service.ts +1 -0
  83. package/src/service/evolution-worker.ts +31 -0
  84. package/src/service/health-query-service.ts +6 -1
  85. package/src/service/monitoring-query-service.ts +4 -0
  86. package/src/service/nocturnal-runtime.ts +7 -1
  87. package/src/service/nocturnal-service.ts +21 -0
  88. package/src/service/nocturnal-target-selector.ts +2 -0
  89. package/src/service/runtime-summary-service.ts +6 -0
  90. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +2 -0
  91. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +2 -0
  92. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +3 -0
  93. package/src/service/subagent-workflow/subagent-error-utils.ts +1 -0
  94. package/src/service/subagent-workflow/workflow-manager-base.ts +6 -0
  95. package/src/service/subagent-workflow/workflow-store.ts +2 -0
  96. package/src/tools/critique-prompt.ts +1 -0
  97. package/src/tools/deep-reflect.ts +9 -0
  98. package/src/tools/model-index.ts +1 -0
  99. package/src/tools/write-pain-flag.ts +1 -0
  100. package/src/utils/file-lock.ts +1 -0
  101. package/src/utils/io.ts +2 -0
@@ -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.1",
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": "27d380ef1db5",
80
- "bundleMd5": "e6f2b6946eddc217169568fc45c5569e",
81
- "builtAt": "2026-04-13T08:32:02.125Z"
79
+ "gitSha": "25bfc2bb209f",
80
+ "bundleMd5": "b735aa483374dd2c7071295b11161676",
81
+ "builtAt": "2026-04-13T14:25:24.799Z"
82
82
  }
83
83
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "principles-disciple",
3
- "version": "1.28.1",
3
+ "version": "1.28.3",
4
4
  "description": "Native OpenClaw plugin for Principles Disciple",
5
5
  "type": "module",
6
6
  "main": "./dist/bundle.js",
@@ -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,
@@ -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,
@@ -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
@@ -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)) {
@@ -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
- // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Reason: triggerMethod is reserved for future extension - tracking rollback trigger source
50
+
50
51
  const _triggerMethod = 'user_command' as const;
51
52
 
52
53
  if (args === 'last') {
@@ -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);
@@ -21,6 +21,7 @@ function formatState(state: string): string {
21
21
  }
22
22
 
23
23
 
24
+ // eslint-disable-next-line @typescript-eslint/max-params
24
25
  function buildOutput(
25
26
  workflowId: string,
26
27
  summary: ReturnType<InstanceType<typeof WorkflowStore>['getWorkflow']>,
@@ -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,
@@ -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';
@@ -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, {
@@ -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
- // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Reason: data used for type narrowing only, actual fields accessed via stats
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