principles-disciple 1.42.0 → 1.44.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.
Files changed (83) hide show
  1. package/openclaw.plugin.json +1 -1
  2. package/package.json +1 -1
  3. package/src/commands/archive-impl.ts +5 -3
  4. package/src/commands/capabilities.ts +1 -1
  5. package/src/commands/context.ts +1 -0
  6. package/src/commands/disable-impl.ts +1 -1
  7. package/src/commands/evolution-status.ts +2 -2
  8. package/src/commands/export.ts +6 -6
  9. package/src/commands/nocturnal-train.ts +1 -1
  10. package/src/commands/principle-rollback.ts +1 -1
  11. package/src/commands/rollback.ts +0 -1
  12. package/src/commands/samples.ts +1 -1
  13. package/src/commands/thinking-os.ts +1 -0
  14. package/src/commands/workflow-debug.ts +1 -1
  15. package/src/core/adaptive-thresholds.ts +3 -3
  16. package/src/core/config.ts +2 -1
  17. package/src/core/dictionary.ts +1 -0
  18. package/src/core/event-log.ts +3 -3
  19. package/src/core/evolution-engine.ts +1 -1
  20. package/src/core/external-training-contract.ts +1 -1
  21. package/src/core/merge-gate-audit.ts +3 -3
  22. package/src/core/nocturnal-arbiter.ts +1 -1
  23. package/src/core/nocturnal-compliance.ts +28 -28
  24. package/src/core/nocturnal-executability.ts +1 -1
  25. package/src/core/nocturnal-reasoning-deriver.ts +4 -4
  26. package/src/core/nocturnal-rule-implementation-validator.ts +1 -1
  27. package/src/core/nocturnal-snapshot-contract.ts +1 -1
  28. package/src/core/pain-context-extractor.ts +2 -2
  29. package/src/core/path-resolver.ts +1 -0
  30. package/src/core/pd-task-reconciler.ts +1 -0
  31. package/src/core/pd-task-service.ts +1 -1
  32. package/src/core/pd-task-store.ts +1 -0
  33. package/src/core/principle-internalization/deprecated-readiness.ts +1 -1
  34. package/src/core/principle-internalization/principle-lifecycle-service.ts +1 -1
  35. package/src/core/principle-training-state.ts +2 -2
  36. package/src/core/principle-tree-migration.ts +1 -1
  37. package/src/core/profile.ts +1 -1
  38. package/src/core/promotion-gate.ts +0 -2
  39. package/src/core/replay-engine.ts +1 -0
  40. package/src/core/risk-calculator.ts +2 -1
  41. package/src/core/rule-host.ts +1 -1
  42. package/src/core/session-tracker.ts +1 -0
  43. package/src/core/shadow-observation-registry.ts +1 -1
  44. package/src/core/thinking-models.ts +1 -1
  45. package/src/core/thinking-os-parser.ts +1 -1
  46. package/src/core/trajectory.ts +2 -4
  47. package/src/core/workspace-context.ts +1 -1
  48. package/src/hooks/bash-risk.ts +2 -2
  49. package/src/hooks/edit-verification.ts +4 -4
  50. package/src/hooks/gate.ts +8 -8
  51. package/src/hooks/gfi-gate.ts +2 -2
  52. package/src/hooks/lifecycle-routing.ts +1 -1
  53. package/src/hooks/pain.ts +2 -2
  54. package/src/hooks/progressive-trust-gate.ts +3 -3
  55. package/src/hooks/prompt.ts +3 -5
  56. package/src/hooks/thinking-checkpoint.ts +1 -1
  57. package/src/index.ts +8 -8
  58. package/src/service/central-database.ts +3 -2
  59. package/src/service/central-health-service.ts +2 -1
  60. package/src/service/central-overview-service.ts +3 -2
  61. package/src/service/control-ui-query-service.ts +2 -2
  62. package/src/service/event-log-auditor.ts +2 -2
  63. package/src/service/evolution-query-service.ts +3 -3
  64. package/src/service/evolution-worker.ts +11 -18
  65. package/src/service/health-query-service.ts +11 -10
  66. package/src/service/monitoring-query-service.ts +4 -4
  67. package/src/service/nocturnal-runtime.ts +0 -3
  68. package/src/service/nocturnal-service.ts +8 -8
  69. package/src/service/nocturnal-target-selector.ts +2 -2
  70. package/src/service/queue-io.ts +5 -5
  71. package/src/service/runtime-summary-service.ts +1 -1
  72. package/src/service/sleep-cycle.ts +1 -1
  73. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +1 -1
  74. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +1 -0
  75. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +1 -1
  76. package/src/service/subagent-workflow/subagent-error-utils.ts +1 -1
  77. package/src/service/subagent-workflow/workflow-store.ts +3 -2
  78. package/src/service/workflow-watchdog.ts +1 -1
  79. package/src/tools/critique-prompt.ts +1 -1
  80. package/src/tools/model-index.ts +1 -1
  81. package/src/utils/file-lock.ts +1 -1
  82. package/src/utils/io.ts +1 -1
  83. package/src/utils/retry.ts +2 -2
@@ -323,8 +323,6 @@ export function evaluatePromotionGate(
323
323
  ): PromotionGateResult {
324
324
  const {
325
325
  checkpointId,
326
-
327
- targetProfile: _targetProfile,
328
326
  baselineMetrics,
329
327
  minDelta = DEFAULT_MIN_DELTA,
330
328
  allowedMargin = DEFAULT_ALLOWED_MARGIN,
@@ -1,3 +1,4 @@
1
+
1
2
  import * as fs from 'fs';
2
3
  import * as path from 'path';
3
4
  import { withLock } from '../utils/file-lock.js';
@@ -1,3 +1,4 @@
1
+
1
2
  /* global NodeJS */
2
3
  import * as fs from 'fs';
3
4
  import { isRisky } from '../utils/io.js';
@@ -95,7 +96,7 @@ export function getTargetFileLineCount(absoluteFilePath: string): number | null
95
96
  * @returns Maximum allowed lines (at least minLines, at most maxLines if provided)
96
97
  */
97
98
 
98
- // eslint-disable-next-line @typescript-eslint/max-params
99
+
99
100
  export function calculatePercentageThreshold(
100
101
  targetLineCount: number,
101
102
  percentage: number,
@@ -71,7 +71,7 @@ export class RuleHost {
71
71
 
72
72
  // Merge decisions from all active implementations
73
73
 
74
- // eslint-disable-next-line @typescript-eslint/init-declarations
74
+
75
75
  let blocked: RuleHostResult | undefined;
76
76
  const approvals: RuleHostResult[] = [];
77
77
 
@@ -1,3 +1,4 @@
1
+
1
2
  import * as path from 'path';
2
3
  import * as fs from 'fs';
3
4
  import { atomicWriteFileSync } from '../utils/io.js';
@@ -534,4 +534,4 @@ export function cleanupExpiredObservations(
534
534
  });
535
535
 
536
536
  return removed;
537
- }
537
+ }
@@ -202,7 +202,7 @@ let _cachedWorkspace: string | null = null;
202
202
  *
203
203
  * @param workspaceDir Optional. If provided, loads from that workspace's THINKING_OS.md.
204
204
  */
205
- // eslint-disable-next-line complexity -- complexity 14, refactor candidate
205
+
206
206
  export function listThinkingModels(workspaceDir?: string): ThinkingModelDefinition[] {
207
207
  const cacheKey = workspaceDir ?? '__global__';
208
208
  if (_cachedDefinitions && _cachedWorkspace === cacheKey) {
@@ -45,7 +45,7 @@ export function parseThinkingOsMd(content: string): ThinkingOsDirective[] {
45
45
  // Match all <directive ...> ... </directive> blocks
46
46
  const directiveRegex = /<directive\s+([^>]*)>([\s\S]*?)<\/directive>/gi;
47
47
 
48
- // eslint-disable-next-line no-useless-assignment
48
+
49
49
  let _match: RegExpExecArray | null = null;
50
50
 
51
51
  while ((_match = directiveRegex.exec(content)) !== null) {
@@ -1,3 +1,5 @@
1
+
2
+
1
3
  import Database from 'better-sqlite3';
2
4
  import fs from 'fs';
3
5
  import path from 'path';
@@ -207,10 +209,6 @@ export class TrajectoryDatabase {
207
209
  recordToolCall(input: TrajectoryToolCallInput): number {
208
210
  this.recordSession({ sessionId: input.sessionId, startedAt: input.createdAt });
209
211
  const createdAt = input.createdAt ?? nowIso();
210
- // Extract filePath from paramsJson if provided and is an object with filePath
211
- const paramsObj = input.paramsJson as Record<string, unknown> | undefined;
212
-
213
- const _filePath = paramsObj && typeof paramsObj.filePath === 'string' ? paramsObj.filePath : null;
214
212
  const rowId = this.withWrite(() => {
215
213
  const result = this.db.prepare(`
216
214
  INSERT INTO tool_calls (
@@ -173,7 +173,7 @@ export class WorkspaceContext {
173
173
  * Uses PathResolver to handle path normalization and fallback logic.
174
174
  * @throws Error if workspaceDir is missing and no fallback available.
175
175
  */
176
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Reason: OpenClaw plugin framework hook context has dynamic shape - type not available
176
+
177
177
  static fromHookContext(ctx: any): WorkspaceContext {
178
178
  const {logger} = ctx;
179
179
  const log = (msg: string) => logger?.info?.(msg);
@@ -39,7 +39,7 @@ export type BashRiskLevel = 'safe' | 'dangerous' | 'normal';
39
39
  * @returns The risk level: 'safe', 'dangerous', or 'normal'
40
40
  */
41
41
 
42
- // eslint-disable-next-line @typescript-eslint/max-params
42
+
43
43
  export function analyzeBashCommand(
44
44
  command: string,
45
45
  safePatterns: string[],
@@ -154,7 +154,7 @@ export interface DynamicThresholdConfig {
154
154
  * @param config - Configuration with large_change_lines and ep_tier_multipliers
155
155
  * @returns The adjusted threshold (minimum 0)
156
156
  */
157
- // eslint-disable-next-line @typescript-eslint/max-params
157
+
158
158
  export function calculateDynamicThreshold(
159
159
  baseThreshold: number,
160
160
  epTier: number,
@@ -127,11 +127,11 @@ This is enforced by P-03 (精确匹配前验证原则).`;
127
127
  * This enforces P-03 at the tool layer
128
128
  */
129
129
 
130
- // eslint-disable-next-line @typescript-eslint/max-params
130
+
131
131
  export function handleEditVerification(
132
132
  event: PluginHookBeforeToolCallEvent,
133
133
  wctx: WorkspaceContext,
134
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Reason: logger is typed as any by plugin framework - type not available
134
+
135
135
  ctx: { logger?: any; sessionId?: string },
136
136
  config: EditVerificationConfig = {}
137
137
  ): PluginHookBeforeToolCallResult | void {
@@ -157,7 +157,7 @@ export function handleEditVerification(
157
157
 
158
158
  // 2. Resolve and read file
159
159
 
160
- // eslint-disable-next-line @typescript-eslint/init-declarations
160
+
161
161
  let absolutePath: string;
162
162
  try {
163
163
  absolutePath = wctx.resolve(filePath);
@@ -225,7 +225,7 @@ export function handleEditVerification(
225
225
 
226
226
  // 3. Read current file content with improved error handling
227
227
 
228
- // eslint-disable-next-line @typescript-eslint/init-declarations
228
+
229
229
  let currentContent: string;
230
230
  try {
231
231
  currentContent = fs.readFileSync(absolutePath, 'utf-8');
package/src/hooks/gate.ts CHANGED
@@ -135,7 +135,7 @@ export function handleBeforeToolCall(
135
135
 
136
136
  if (mutationMatch) {
137
137
 
138
- // eslint-disable-next-line @typescript-eslint/prefer-destructuring
138
+
139
139
  filePath = mutationMatch[1];
140
140
  } else {
141
141
  const hasRiskPath = profile.risk_paths.some(rp => command.includes(rp));
@@ -169,36 +169,36 @@ export function handleBeforeToolCall(
169
169
  toolName: event.toolName,
170
170
  normalizedPath: relPath,
171
171
 
172
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
172
+
173
173
  paramsSummary: _extractParamsSummary(event.params),
174
174
  },
175
175
  workspace: {
176
176
  isRiskPath: risky,
177
177
 
178
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
178
+
179
179
  planStatus: _getPlanStatus(ctx.workspaceDir),
180
180
 
181
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
181
+
182
182
  hasPlanFile: _hasPlanFile(ctx.workspaceDir),
183
183
  },
184
184
  session: {
185
185
  sessionId: ctx.sessionId,
186
186
 
187
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
187
+
188
188
  currentGfi: _getCurrentGfi(ctx.sessionId),
189
189
 
190
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
190
+
191
191
  recentThinking: _hasRecentThinking(ctx.sessionId),
192
192
  },
193
193
  evolution: {
194
194
 
195
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
195
+
196
196
  epTier: _getEpTier(wctx.workspaceDir),
197
197
  },
198
198
  derived: {
199
199
  estimatedLineChanges: estimateLineChanges({ toolName: event.toolName, params: event.params }),
200
200
 
201
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
201
+
202
202
  bashRisk: _getBashRisk(event, profile),
203
203
  },
204
204
  };
@@ -48,7 +48,7 @@ export interface GfiGateConfig {
48
48
  * Internal helper to call the shared block helper with gfi-gate source tag.
49
49
  */
50
50
 
51
- // eslint-disable-next-line @typescript-eslint/max-params
51
+
52
52
  function block(
53
53
  wctx: WorkspaceContext,
54
54
  filePath: string,
@@ -70,7 +70,7 @@ function block(
70
70
  }
71
71
 
72
72
 
73
- // eslint-disable-next-line @typescript-eslint/max-params
73
+
74
74
  export function checkGfiGate(
75
75
  event: PluginHookBeforeToolCallEvent,
76
76
  wctx: WorkspaceContext,
@@ -66,7 +66,7 @@ export type LifecycleIntent = 'promote' | 'disable' | 'rollback' | null;
66
66
  * Detect implementation lifecycle intent from user message.
67
67
  * Returns the detected intent type or null.
68
68
  */
69
- // eslint-disable-next-line complexity -- complexity 13, refactor candidate
69
+
70
70
  export function detectLifecycleIntent(message: string): LifecycleIntent {
71
71
  // Check promote patterns
72
72
  for (const p of PROMOTE_PATTERNS_EN) {
package/src/hooks/pain.ts CHANGED
@@ -131,7 +131,7 @@ export function handleAfterToolCall(
131
131
 
132
132
  // ── Trust Engine: Record failure ──
133
133
 
134
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
134
+
135
135
  const errorType = extractErrorType(event.error || errorText);
136
136
  const filePath = params.file_path || params.path || params.file;
137
137
  const relPath = typeof filePath === 'string' ? normalizePath(filePath, effectiveWorkspaceDir) : 'unknown';
@@ -194,7 +194,7 @@ export function handleAfterToolCall(
194
194
  const session = getSession(sessionId);
195
195
  const toolFailureGfi = session?.gfiBySource?.tool_failure || 0;
196
196
 
197
- // eslint-disable-next-line @typescript-eslint/init-declarations
197
+
198
198
  let resetState: SessionState;
199
199
  if (toolFailureGfi > 0) {
200
200
  // Reduce tool_failure source by 50% (relief from successful tool execution)
@@ -87,7 +87,7 @@ export function buildEvolutionGateReason(
87
87
  * Internal helper to call the shared block helper with progressive-trust-gate source tag.
88
88
  */
89
89
 
90
- // eslint-disable-next-line @typescript-eslint/max-params
90
+
91
91
  function block(
92
92
  filePath: string,
93
93
  reason: string,
@@ -121,7 +121,7 @@ function block(
121
121
  * @returns PluginHookBeforeToolCallResult to block, or undefined to allow
122
122
  */
123
123
 
124
- // eslint-disable-next-line @typescript-eslint/max-params
124
+
125
125
  export function checkProgressiveTrustGate(
126
126
  event: PluginHookBeforeToolCallEvent,
127
127
  wctx: WorkspaceContext,
@@ -154,7 +154,7 @@ export function checkProgressiveTrustGate(
154
154
 
155
155
  const currentTier = epDecision.currentTier ?? 1;
156
156
 
157
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
157
+
158
158
  const tierName = getTierName(currentTier);
159
159
 
160
160
  logger.info?.(`[PD_GATE] EP Gate: Tier ${currentTier} (${tierName}), Tool: ${event.toolName}, Risk: ${risky}, Allowed: ${epDecision.allowed}`);
@@ -1,3 +1,5 @@
1
+
2
+
1
3
  import * as fs from 'fs';
2
4
  import * as path from 'path';
3
5
  import type { PluginHookBeforePromptBuildEvent, PluginHookAgentContext, PluginHookBeforePromptBuildResult, PluginLogger, OpenClawPluginApi } from '../openclaw-sdk.js';
@@ -979,12 +981,8 @@ ${taskBlocks}${processingNote}
979
981
  const filePattern = /\b([a-zA-Z]:\\?[^\s,]+\.[a-z]{2,10}|[./][^\s,]+\.[a-z]{2,10})\b/gi;
980
982
  const toolMatches = toolPatterns.flatMap(({ pattern, tool }) => {
981
983
  const matches: string[] = [];
982
-
983
-
984
- let _m;
985
984
  const r = new RegExp(pattern.source, pattern.flags);
986
-
987
- while ((_m = r.exec(latestUserText)) !== null) matches.push(tool);
985
+ while (r.exec(latestUserText) !== null) matches.push(tool);
988
986
  return matches;
989
987
  });
990
988
  const fileMatches = latestUserText.match(filePattern) ?? [];
@@ -41,7 +41,7 @@ export interface ThinkingCheckpointConfig {
41
41
  * @returns Block result if thinking required, undefined otherwise
42
42
  */
43
43
 
44
- // eslint-disable-next-line @typescript-eslint/max-params
44
+
45
45
  export function checkThinkingCheckpoint(
46
46
  event: PluginHookBeforeToolCallEvent,
47
47
  config: ThinkingCheckpointConfig,
package/src/index.ts CHANGED
@@ -283,7 +283,7 @@ const plugin = {
283
283
 
284
284
  if (shouldRecordShadow) {
285
285
  const observation = recordShadowRouting(workspaceDir, {
286
- checkpointId: decision.activeCheckpointId!, // eslint-disable-line @typescript-eslint/no-non-null-assertion -- Reason: !!decision.activeCheckpointId guard above ensures truthiness
286
+ checkpointId: decision.activeCheckpointId!,
287
287
  workerProfile: agentId as WorkerProfile,
288
288
  taskFingerprint: computeRuntimeShadowTaskFingerprint(event),
289
289
  });
@@ -362,7 +362,7 @@ const plugin = {
362
362
 
363
363
  // ── Slash Commands ──
364
364
  // Register command with optional short alias
365
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
365
+
366
366
  const registerCommandWithAlias = (name: string, alias: string | null, desc: string, handler: any, opts?: { acceptsArgs?: boolean }) => {
367
367
  const base = {
368
368
  name,
@@ -380,17 +380,17 @@ const plugin = {
380
380
  }
381
381
  };
382
382
 
383
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
383
+
384
384
  registerCommandWithAlias('pd-init', 'pdi', getCommandDescription('pd-init', language), (ctx: any) => handleInitStrategy(ctx));
385
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
385
+
386
386
  registerCommandWithAlias('pd-okr', 'pdk', getCommandDescription('pd-okr', language), (ctx: any) => handleManageOkr(ctx));
387
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
387
+
388
388
  registerCommandWithAlias('pd-bootstrap', 'pdb', getCommandDescription('pd-bootstrap', language), (ctx: any) => handleBootstrapTools(ctx));
389
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
389
+
390
390
  registerCommandWithAlias('pd-research', 'pdr', getCommandDescription('pd-research', language), (ctx: any) => handleResearchTools(ctx));
391
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
391
+
392
392
  registerCommandWithAlias('pd-thinking', 'pdt', getCommandDescription('pd-thinking', language), (ctx: any) => handleThinkingOs(ctx), { acceptsArgs: true });
393
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
393
+
394
394
  registerCommandWithAlias('pd-reflect', 'pdrl', getCommandDescription('pd-reflect', language), (ctx: any) => {
395
395
  try {
396
396
  // Resolve agentId from sessionKey (if available), fallback to 'main'
@@ -1,3 +1,4 @@
1
+
1
2
  import Database from 'better-sqlite3';
2
3
  import fs from 'fs';
3
4
  import path from 'path';
@@ -200,7 +201,7 @@ export class CentralDatabase {
200
201
  /**
201
202
  * Sync data from a single workspace into the central database
202
203
  */
203
- // eslint-disable-next-line complexity -- complexity 12, refactor candidate
204
+
204
205
  syncWorkspace(workspaceName: string): number {
205
206
  const workspace = this.workspaces.find(w => w.name === workspaceName);
206
207
  if (!workspace) {
@@ -714,7 +715,7 @@ export class CentralDatabase {
714
715
  syncEnabled: c.sync_enabled === 1,
715
716
  }));
716
717
  }
717
- // eslint-disable-next-line complexity -- complexity 12, refactor candidate
718
+
718
719
 
719
720
  updateWorkspaceConfig(
720
721
  workspaceName: string,
@@ -1,3 +1,4 @@
1
+
1
2
  import { getCentralDatabase } from './central-database.js';
2
3
  import { HealthQueryService } from './health-query-service.js';
3
4
 
@@ -18,7 +19,7 @@ export interface CentralHealthResponse {
18
19
  */
19
20
  export class CentralHealthService {
20
21
 
21
- // eslint-disable-next-line @typescript-eslint/class-methods-use-this
22
+
22
23
  getAllWorkspaceHealth(): CentralHealthResponse {
23
24
  const centralDb = getCentralDatabase();
24
25
  const workspaces: WorkspaceHealthEntry[] = [];
@@ -1,3 +1,4 @@
1
+
1
2
  import { getCentralDatabase, type CentralDatabase } from './central-database.js';
2
3
  import { getThinkingModelDefinitions } from '../core/thinking-models.js';
3
4
  import type { OverviewResponse } from './control-ui-query-service.js';
@@ -24,7 +25,7 @@ export class CentralOverviewService {
24
25
  }
25
26
 
26
27
 
27
- // eslint-disable-next-line @typescript-eslint/class-methods-use-this
28
+
28
29
  dispose(): void {
29
30
  // Do NOT dispose centralDb — it's a singleton shared across all requests.
30
31
  // Individual services that open per-request connections (e.g. HealthQueryService)
@@ -62,7 +63,7 @@ export class CentralOverviewService {
62
63
 
63
64
  // D-06: sampleQueue.counters from aggregated_correction_samples GROUP BY review_status
64
65
 
65
- // eslint-disable-next-line no-useless-assignment
66
+
66
67
  let sampleCounters: Record<string, number> = {};
67
68
  try {
68
69
  sampleCounters = this.centralDb.getSampleCountersByStatus();
@@ -255,7 +255,7 @@ export class ControlUiQueryService {
255
255
  this.uiDb.dispose();
256
256
  }
257
257
 
258
- // eslint-disable-next-line complexity -- complexity 14, refactor candidate
258
+
259
259
  getOverview(days = 30): OverviewResponse {
260
260
  const stats = this.trajectory.getDataStats();
261
261
  const regressionRows = this.uiDb.all<{
@@ -400,7 +400,7 @@ export class ControlUiQueryService {
400
400
  };
401
401
  }
402
402
 
403
- // eslint-disable-next-line complexity -- complexity 13, refactor candidate
403
+
404
404
  listSamples(filters: SampleListFilters = {}): SamplesResponse {
405
405
  const page = Math.max(1, Number(filters.page ?? 1));
406
406
  const pageSize = clampPageSize(filters.pageSize);
@@ -137,7 +137,7 @@ function countAllHooks(filePath: string): Record<string, number> {
137
137
  * @param openclawDir - Base OpenClaw directory (e.g., ~/.openclaw)
138
138
  * @param expectedToolHooks - Hook names that should appear in the primary workspace
139
139
  */
140
- // eslint-disable-next-line complexity -- complexity 11, slightly over threshold
140
+
141
141
  export async function auditEventLogs(
142
142
  openclawDir: string,
143
143
  expectedToolHooks: string[] = ['before_tool_call', 'after_tool_call'],
@@ -210,7 +210,7 @@ export async function auditEventLogs(
210
210
  /**
211
211
  * Format audit report for display.
212
212
  */
213
- // eslint-disable-next-line complexity -- complexity 13, refactor candidate
213
+
214
214
  export function formatAuditReport(report: AuditReport): string {
215
215
  const lines: string[] = [];
216
216
 
@@ -155,7 +155,7 @@ export class EvolutionQueryService {
155
155
  * 注意:不关闭 trajectory,因为它是单例由 TrajectoryRegistry 管理
156
156
  */
157
157
 
158
- // eslint-disable-next-line @typescript-eslint/class-methods-use-this
158
+
159
159
  dispose(): void {
160
160
  // EvolutionQueryService 不拥有 trajectory,所以不关闭它
161
161
  // trajectory 是由 TrajectoryRegistry 管理的单例
@@ -349,13 +349,13 @@ export class EvolutionQueryService {
349
349
  for (const task of recentTasks) {
350
350
  const [createdDay] = task.createdAt.split('T');
351
351
  if (activityByDay.has(createdDay)) {
352
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Reason: has() check guarantees entry exists
352
+
353
353
  activityByDay.get(createdDay)!.created++;
354
354
  }
355
355
  if (task.completedAt) {
356
356
  const [completedDay] = task.completedAt.split('T');
357
357
  if (activityByDay.has(completedDay)) {
358
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Reason: has() check guarantees entry exists
358
+
359
359
  activityByDay.get(completedDay)!.completed++;
360
360
  }
361
361
  }
@@ -1,3 +1,5 @@
1
+
2
+
1
3
  /* global NodeJS */
2
4
 
3
5
  import * as fs from 'fs';
@@ -231,8 +233,6 @@ function buildFallbackNocturnalSnapshot(
231
233
  };
232
234
  }
233
235
 
234
- const PAIN_QUEUE_DEDUP_WINDOW_MS = 30 * 60 * 1000;
235
-
236
236
  // Queue lock constants and requireQueueLock are imported from queue-io.ts
237
237
 
238
238
  export function extractEvolutionTaskId(task: string): string | null {
@@ -282,13 +282,6 @@ export function purgeStaleFailedTasks(
282
282
  return { purged: purged.length, remaining: queue.length, byReason };
283
283
  }
284
284
 
285
- function normalizePainDedupKey(source: string, preview: string, reason?: string): string {
286
- // Include reason in dedup key to match createEvolutionTaskId() behavior
287
- // Different reasons for the same source/preview should create different tasks
288
- const normalizedReason = (reason || '').trim().toLowerCase();
289
- return `${source.trim().toLowerCase()}::${preview.trim().toLowerCase()}::${normalizedReason}`;
290
- }
291
-
292
285
 
293
286
 
294
287
  export function hasRecentDuplicateTask(queue: EvolutionQueueItem[], source: string, preview: string, now: number, reason?: string): boolean {
@@ -665,7 +658,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
665
658
  workspaceDir: wctx.workspaceDir,
666
659
  stateDir: wctx.stateDir,
667
660
  logger: api?.logger || logger,
668
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Reason: api is guaranteed non-null in this recovery path where runtimeAdapter is required
661
+
669
662
  runtimeAdapter: new OpenClawTrinityRuntimeAdapter(api!),
670
663
  subagent: api?.runtime?.subagent,
671
664
  });
@@ -1183,7 +1176,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
1183
1176
  let snapshotData: NocturnalSessionSnapshot | undefined;
1184
1177
 
1185
1178
  if (isPollingTask) {
1186
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Reason: polling path requires existing resultRef
1179
+
1187
1180
  workflowId = sleepTask.resultRef!;
1188
1181
  } else {
1189
1182
  // Phase 1: Build trajectory snapshot for Nocturnal pipeline
@@ -1335,15 +1328,15 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
1335
1328
 
1336
1329
  try {
1337
1330
  payload = lastEvent?.payload ?? {};
1338
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1331
+
1339
1332
  if ((payload as any).skipReason) {
1340
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1333
+
1341
1334
  detailedError += ` (skipReason: ${(payload as any).skipReason})`;
1342
1335
 
1343
1336
  }
1344
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1337
+
1345
1338
  if ((payload as any).failures && Array.isArray((payload as any).failures) && (payload as any).failures.length > 0) {
1346
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1339
+
1347
1340
  detailedError += ` | failures: ${((payload as any).failures as string[]).slice(0, 3).join(', ')}`;
1348
1341
  }
1349
1342
  } catch { /* ignore parse errors */ }
@@ -1359,7 +1352,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
1359
1352
  sleepOutcomes.push({ taskKind: 'sleep_reflection', succeeded: true });
1360
1353
 
1361
1354
  logger?.warn?.(`[PD:EvolutionWorker] sleep_reflection task ${sleepTask.id} background runtime unavailable, using stub fallback: ${errorReason}`);
1362
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1355
+
1363
1356
  } else if ((payload as any).skipReason === 'no_violating_sessions') {
1364
1357
  // #244: No meaningful violations found (thin filter) → skip without failure
1365
1358
  sleepTask.status = 'completed';
@@ -1554,7 +1547,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
1554
1547
  const manager = new CorrectionObserverWorkflowManager({
1555
1548
  workspaceDir: wctx.workspaceDir,
1556
1549
  logger,
1557
- subagent: api?.runtime?.subagent!, /* eslint-disable-line @typescript-eslint/no-non-null-assertion */
1550
+ subagent: api?.runtime?.subagent!,
1558
1551
  agentSession: api?.runtime?.agent?.session,
1559
1552
  });
1560
1553
 
@@ -1568,7 +1561,7 @@ async function processEvolutionQueue(wctx: WorkspaceContext, logger: PluginLogge
1568
1561
  workflowId = handle.workflowId;
1569
1562
  koTask.resultRef = workflowId;
1570
1563
  } else {
1571
- workflowId = koTask.resultRef!; /* eslint-disable-line @typescript-eslint/no-non-null-assertion */
1564
+ workflowId = koTask.resultRef!;
1572
1565
  }
1573
1566
 
1574
1567
  // Poll workflow state