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
@@ -50,6 +50,7 @@ function trainingStateToTreePrinciple(
50
50
  text: `Principle ${principleId}`, // Minimal text, will be enriched from PRINCIPLES.md if available
51
51
  triggerPattern: '', // Unknown from legacy data
52
52
  action: '', // Unknown from legacy data
53
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
53
54
  status: mapInternalizationStatusToPrincipleStatus(state.internalizationStatus),
54
55
  priority: 'P1', // Default priority
55
56
  scope: 'general',
@@ -92,6 +93,7 @@ function mapInternalizationStatusToPrincipleStatus(
92
93
  * This function is idempotent: it only migrates principles that don't exist
93
94
  * in tree.principles yet.
94
95
  */
96
+
95
97
  export function migratePrincipleTree(
96
98
  stateDir: string,
97
99
  workspaceDir?: string
@@ -324,7 +324,7 @@ export function evaluatePromotionGate(
324
324
  ): PromotionGateResult {
325
325
  const {
326
326
  checkpointId,
327
- // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Reason: reserved for Phase 7 profile-based targeting
327
+
328
328
  targetProfile: _targetProfile,
329
329
  baselineMetrics,
330
330
  minDelta = DEFAULT_MIN_DELTA,
@@ -410,8 +410,10 @@ export function evaluatePromotionGate(
410
410
  // Shadow evidence comes from actual runtime routing decisions
411
411
  const shadowStats = computeShadowStats(stateDir, { checkpointId });
412
412
 
413
+ // eslint-disable-next-line @typescript-eslint/init-declarations
413
414
  let arbiterRejectRate: number;
414
415
 
416
+ // eslint-disable-next-line @typescript-eslint/init-declarations
415
417
  let arbiterRejectSource: 'shadow' | 'eval-proxy';
416
418
 
417
419
  if (shadowStats && shadowStats.isStatisticallySignificant) {
@@ -446,8 +448,10 @@ export function evaluatePromotionGate(
446
448
  // --- Check 6: Executability reject rate constraint ---
447
449
  // PREFER real shadow evidence: escalation rate + profile rejection rate
448
450
 
451
+ // eslint-disable-next-line @typescript-eslint/init-declarations
449
452
  let executabilityRejectRate: number;
450
453
 
454
+ // eslint-disable-next-line @typescript-eslint/init-declarations
451
455
  let executabilityRejectSource: 'shadow' | 'eval-proxy';
452
456
 
453
457
  if (shadowStats && shadowStats.isStatisticallySignificant) {
@@ -506,6 +510,7 @@ export function evaluatePromotionGate(
506
510
 
507
511
  // --- Suggest state based on checks ---
508
512
 
513
+ // eslint-disable-next-line @typescript-eslint/init-declarations
509
514
  let suggestedState: PromotionState | undefined;
510
515
  if (allPassed) {
511
516
  suggestedState = 'candidate_only';
@@ -619,6 +624,7 @@ export function advancePromotion(
619
624
  // (new eval data may reverse a previous rejection)
620
625
  //
621
626
 
627
+ // eslint-disable-next-line @typescript-eslint/init-declarations
622
628
  let targetState: PromotionState;
623
629
  if (!gateResult.passes) {
624
630
  targetState = 'rejected';
@@ -122,6 +122,7 @@ export class ReplayEngine {
122
122
  }
123
123
 
124
124
 
125
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
125
126
  runSingleSample(sample: ReplaySample, evaluator: CandidateEvaluator): ReplayResult {
126
127
  const evaluation = evaluator.evaluate(sample);
127
128
  return {
@@ -236,6 +237,7 @@ export class ReplayEngine {
236
237
  };
237
238
  }
238
239
 
240
+
239
241
  private _buildRuleHostInput(sample: ReplaySample): RuleHostInput | null {
240
242
  const snapshot = getNocturnalSessionSnapshot(
241
243
  TrajectoryRegistry.get(this.workspaceDir),
@@ -294,6 +296,7 @@ export class ReplayEngine {
294
296
  }
295
297
 
296
298
 
299
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this -- complexity 11, slightly over threshold
297
300
  private _selectToolCall(
298
301
  snapshot: NocturnalSessionSnapshot,
299
302
  classification: SampleClassification,
@@ -324,6 +327,7 @@ export class ReplayEngine {
324
327
  }
325
328
 
326
329
 
330
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
327
331
  private _matchGateBlock(
328
332
  gateBlocks: NocturnalGateBlock[],
329
333
  toolCall: NocturnalToolCall,
@@ -361,6 +365,7 @@ export class ReplayEngine {
361
365
  }
362
366
 
363
367
 
368
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
364
369
  private _estimateLineChanges(toolCall: NocturnalToolCall): number {
365
370
  if (toolCall.toolName === 'edit' || toolCall.toolName === 'write') {
366
371
  return 20;
@@ -369,6 +374,7 @@ export class ReplayEngine {
369
374
  }
370
375
 
371
376
 
377
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
372
378
  private _inferBashRisk(toolCall: NocturnalToolCall): 'safe' | 'normal' | 'dangerous' | 'unknown' {
373
379
  if (toolCall.toolName !== 'bash' && toolCall.toolName !== 'run_shell_command') {
374
380
  return 'unknown';
@@ -380,7 +386,9 @@ export class ReplayEngine {
380
386
  return toolCall.outcome === 'success' ? 'safe' : 'normal';
381
387
  }
382
388
 
389
+
383
390
 
391
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this -- complexity 11
384
392
  private _scoreEvaluation(
385
393
  sample: ReplaySample,
386
394
  result: RuleHostResult,
@@ -489,6 +497,7 @@ export class ReplayEngine {
489
497
  }
490
498
 
491
499
 
500
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
492
501
  private _determineDecision(
493
502
  pain: ClassificationSummary,
494
503
  success: ClassificationSummary,
@@ -520,6 +529,7 @@ export class ReplayEngine {
520
529
  }
521
530
 
522
531
 
532
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this
523
533
  private _deriveExpectedOutcome(
524
534
  record: NocturnalDatasetRecord,
525
535
  ): ReplaySample['expectedOutcome'] {
@@ -9,6 +9,7 @@ export interface FileModification {
9
9
  params: Record<string, unknown>;
10
10
  }
11
11
 
12
+
12
13
  export function estimateLineChanges(modification: FileModification): number {
13
14
  const { toolName, params } = modification;
14
15
 
@@ -94,6 +95,7 @@ export function getTargetFileLineCount(absoluteFilePath: string): number | null
94
95
  * @returns Maximum allowed lines (at least minLines, at most maxLines if provided)
95
96
  */
96
97
 
98
+ // eslint-disable-next-line @typescript-eslint/max-params
97
99
  export function calculatePercentageThreshold(
98
100
  targetLineCount: number,
99
101
  percentage: number,
@@ -59,6 +59,7 @@ export class RuleHost {
59
59
  * - { decision: 'block', ... } when any implementation returns block (short-circuits)
60
60
  * - { decision: 'requireApproval', ... } when any implementation returns requireApproval
61
61
  */
62
+
62
63
  evaluate(input: RuleHostInput): RuleHostResult | undefined {
63
64
  try {
64
65
  // Load active code implementations from the ledger
@@ -70,6 +71,7 @@ export class RuleHost {
70
71
 
71
72
  // Merge decisions from all active implementations
72
73
 
74
+ // eslint-disable-next-line @typescript-eslint/init-declarations
73
75
  let blocked: RuleHostResult | undefined;
74
76
  const approvals: RuleHostResult[] = [];
75
77
 
@@ -181,6 +183,7 @@ export class RuleHost {
181
183
  * Uses the shared isolated runtime loader so candidate code does not execute
182
184
  * in the host global realm.
183
185
  */
186
+
184
187
  private _loadSingleImplementation(
185
188
  impl: Implementation
186
189
  ): LoadedImplementation | null {
@@ -84,6 +84,7 @@ export function initPersistence(stateDir: string): void {
84
84
 
85
85
  // Load all existing sessions
86
86
 
87
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
87
88
  loadAllSessions();
88
89
  }
89
90
 
@@ -181,6 +182,7 @@ export function flushAllSessions(): void {
181
182
  }
182
183
 
183
184
 
185
+ // eslint-disable-next-line @typescript-eslint/max-params
184
186
  function getOrCreateSession(sessionId: string, workspaceDir?: string, sessionKey?: string, trigger?: string): SessionState {
185
187
  let state = sessions.get(sessionId);
186
188
  if (!state) {
@@ -243,6 +245,7 @@ export function trackToolRead(sessionId: string, filePath: string, workspaceDir?
243
245
  }
244
246
 
245
247
 
248
+ // eslint-disable-next-line @typescript-eslint/max-params -- complexity 12, refactor candidate
246
249
  export function trackLlmOutput(sessionId: string, usage: TokenUsage | undefined, config?: PainConfig, workspaceDir?: string, sessionKey?: string, trigger?: string): SessionState {
247
250
  const state = getOrCreateSession(sessionId, workspaceDir, sessionKey, trigger);
248
251
  state.llmTurns += 1;
@@ -282,6 +285,7 @@ export function trackLlmOutput(sessionId: string, usage: TokenUsage | undefined,
282
285
  * Tracks physical friction based on tool execution failures.
283
286
  */
284
287
 
288
+ // eslint-disable-next-line @typescript-eslint/max-params -- complexity 11, slightly over threshold
285
289
  export function trackFriction(
286
290
  sessionId: string,
287
291
  deltaF: number,
@@ -548,6 +552,7 @@ export function decayGfi(sessionId: string, elapsedMinutes: number): SessionStat
548
552
  if (!state || state.currentGfi <= 0 || elapsedMinutes <= 0) return undefined;
549
553
 
550
554
  // Determine decay rate based on current GFI level (segmented)
555
+ // eslint-disable-next-line @typescript-eslint/init-declarations
551
556
  let decayRate: number;
552
557
  if (state.currentGfi >= 70) {
553
558
  decayRate = 0.03; // 3%/min for severe friction
@@ -342,6 +342,7 @@ export function completeShadowObservation(
342
342
  * @returns The updated ShadowObservation, or null if not found
343
343
  */
344
344
 
345
+ // eslint-disable-next-line @typescript-eslint/max-params
345
346
  export function completeShadowObservationByTask(
346
347
  stateDir: string,
347
348
  taskFingerprint: string,
@@ -202,6 +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
  export function listThinkingModels(workspaceDir?: string): ThinkingModelDefinition[] {
206
207
  const cacheKey = workspaceDir ?? '__global__';
207
208
  if (_cachedDefinitions && _cachedWorkspace === cacheKey) {
@@ -45,6 +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
  let _match: RegExpExecArray | null = null;
49
50
 
50
51
  while ((_match = directiveRegex.exec(content)) !== null) {
@@ -208,7 +208,7 @@ export class TrajectoryDatabase {
208
208
  const createdAt = input.createdAt ?? nowIso();
209
209
  // Extract filePath from paramsJson if provided and is an object with filePath
210
210
  const paramsObj = input.paramsJson as Record<string, unknown> | undefined;
211
- /* eslint-disable @typescript-eslint/no-unused-vars -- Reason: _filePath extracted for potential future use but currently unused */
211
+
212
212
  const _filePath = paramsObj && typeof paramsObj.filePath === 'string' ? paramsObj.filePath : null;
213
213
  const rowId = this.withWrite(() => {
214
214
  const result = this.db.prepare(`
@@ -442,6 +442,7 @@ export class TrajectoryDatabase {
442
442
  const now = nowIso();
443
443
  // Cast to V2 to access new fields
444
444
  const v2Updates = updates;
445
+
445
446
  this.withWrite(() => {
446
447
  const setClauses: string[] = ['updated_at = ?'];
447
448
  const values: unknown[] = [now];
@@ -554,6 +555,7 @@ export class TrajectoryDatabase {
554
555
  LIMIT ? OFFSET ?
555
556
  `).all(...values, limit, offset) as Record<string, unknown>[];
556
557
 
558
+
557
559
  return rows.map((row) => ({
558
560
  id: Number(row.id),
559
561
  taskId: String(row.task_id),
@@ -588,6 +590,7 @@ export class TrajectoryDatabase {
588
590
  const offset = filters.offset ?? 0;
589
591
 
590
592
 
593
+ // eslint-disable-next-line @typescript-eslint/init-declarations
591
594
  let rows: Record<string, unknown>[];
592
595
  if (traceId) {
593
596
  rows = this.db.prepare(`
@@ -625,6 +628,7 @@ export class TrajectoryDatabase {
625
628
  * Returns: Analytics data aggregated from trajectory database.
626
629
  * Not: Runtime truth or real-time queue state.
627
630
  */
631
+
628
632
  getEvolutionTaskByTraceId(traceId: string): EvolutionTaskRecord | null {
629
633
  const row = this.db.prepare(`
630
634
  SELECT id, task_id, trace_id, source, reason, score, status,
@@ -775,6 +779,7 @@ export class TrajectoryDatabase {
775
779
  WHERE session_id = ?
776
780
  ORDER BY id ASC
777
781
  `).all(sessionId) as Record<string, unknown>[];
782
+
778
783
 
779
784
  return rows.map((row) => {
780
785
  // Extract filePath from params_json if present
@@ -784,6 +789,7 @@ export class TrajectoryDatabase {
784
789
  const params = JSON.parse(row.params_json);
785
790
  if (params && typeof params.filePath === 'string') {
786
791
 
792
+ // eslint-disable-next-line @typescript-eslint/prefer-destructuring
787
793
  filePath = params.filePath;
788
794
  }
789
795
  } catch {
@@ -1610,6 +1616,7 @@ export class TrajectoryDatabase {
1610
1616
  }
1611
1617
 
1612
1618
 
1619
+ // eslint-disable-next-line @typescript-eslint/max-params
1613
1620
  private recordExportAudit(
1614
1621
  exportKind: string,
1615
1622
  mode: CorrectionExportMode,
@@ -1675,6 +1682,7 @@ export class TrajectoryDatabase {
1675
1682
  if (referenced.has(entry)) continue;
1676
1683
  const fullPath = path.join(this.blobDir, entry);
1677
1684
 
1685
+ // eslint-disable-next-line @typescript-eslint/init-declarations
1678
1686
  let stat: fs.Stats;
1679
1687
  try {
1680
1688
  stat = fs.statSync(fullPath);
@@ -39,6 +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
  export function analyzeBashCommand(
43
44
  command: string,
44
45
  safePatterns: string[],
@@ -153,6 +154,7 @@ export interface DynamicThresholdConfig {
153
154
  * @param config - Configuration with large_change_lines and ep_tier_multipliers
154
155
  * @returns The adjusted threshold (minimum 0)
155
156
  */
157
+ // eslint-disable-next-line @typescript-eslint/max-params
156
158
  export function calculateDynamicThreshold(
157
159
  baseThreshold: number,
158
160
  epTier: number,
@@ -127,6 +127,7 @@ 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
  export function handleEditVerification(
131
132
  event: PluginHookBeforeToolCallEvent,
132
133
  wctx: WorkspaceContext,
@@ -156,6 +157,7 @@ export function handleEditVerification(
156
157
 
157
158
  // 2. Resolve and read file
158
159
 
160
+ // eslint-disable-next-line @typescript-eslint/init-declarations
159
161
  let absolutePath: string;
160
162
  try {
161
163
  absolutePath = wctx.resolve(filePath);
@@ -223,6 +225,7 @@ export function handleEditVerification(
223
225
 
224
226
  // 3. Read current file content with improved error handling
225
227
 
228
+ // eslint-disable-next-line @typescript-eslint/init-declarations
226
229
  let currentContent: string;
227
230
  try {
228
231
  currentContent = fs.readFileSync(absolutePath, 'utf-8');
@@ -95,6 +95,7 @@ export function recordGateBlockAndReturn(
95
95
  } catch (error: unknown) {
96
96
  logWarn(`[PD_GATE] Failed to record trajectory gate block: ${String(error)}`);
97
97
 
98
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
98
99
  scheduleTrajectoryGateBlockRetry(wctx, trajectoryPayload, 1, logWarn, logError);
99
100
  }
100
101
 
@@ -122,6 +123,7 @@ export function recordGateBlockAndReturn(
122
123
 
123
124
  // Write to pain flag file (merge with existing if present)
124
125
  try {
126
+ // eslint-disable-next-line @typescript-eslint/prefer-destructuring
125
127
  const workspaceDir = wctx.workspaceDir;
126
128
  const currentFlag = wctx.eventLog.findLatestPainSignal(sessionId);
127
129
  const currentScore = currentFlag?.score ?? 0;
@@ -181,6 +183,7 @@ This is a mandatory security gate. The operation was blocked because the modific
181
183
  * Failures are logged but do not affect the runtime block decision.
182
184
  */
183
185
 
186
+ // eslint-disable-next-line @typescript-eslint/max-params
184
187
  function scheduleTrajectoryGateBlockRetry(
185
188
  wctx: WorkspaceContext,
186
189
  payload: {
package/src/hooks/gate.ts CHANGED
@@ -135,6 +135,7 @@ export function handleBeforeToolCall(
135
135
 
136
136
  if (mutationMatch) {
137
137
 
138
+ // eslint-disable-next-line @typescript-eslint/prefer-destructuring
138
139
  filePath = mutationMatch[1];
139
140
  } else {
140
141
  const hasRiskPath = profile.risk_paths.some(rp => command.includes(rp));
@@ -168,29 +169,36 @@ export function handleBeforeToolCall(
168
169
  toolName: event.toolName,
169
170
  normalizedPath: relPath,
170
171
 
172
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
171
173
  paramsSummary: _extractParamsSummary(event.params),
172
174
  },
173
175
  workspace: {
174
176
  isRiskPath: risky,
175
177
 
178
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
176
179
  planStatus: _getPlanStatus(ctx.workspaceDir),
177
180
 
181
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
178
182
  hasPlanFile: _hasPlanFile(ctx.workspaceDir),
179
183
  },
180
184
  session: {
181
185
  sessionId: ctx.sessionId,
182
186
 
187
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
183
188
  currentGfi: _getCurrentGfi(ctx.sessionId),
184
189
 
190
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
185
191
  recentThinking: _hasRecentThinking(ctx.sessionId),
186
192
  },
187
193
  evolution: {
188
194
 
195
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
189
196
  epTier: _getEpTier(wctx.workspaceDir),
190
197
  },
191
198
  derived: {
192
199
  estimatedLineChanges: estimateLineChanges({ toolName: event.toolName, params: event.params }),
193
200
 
201
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
194
202
  bashRisk: _getBashRisk(event, profile),
195
203
  },
196
204
  };
@@ -48,6 +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
  function block(
52
53
  wctx: WorkspaceContext,
53
54
  filePath: string,
@@ -69,6 +70,7 @@ function block(
69
70
  }
70
71
 
71
72
 
73
+ // eslint-disable-next-line @typescript-eslint/max-params
72
74
  export function checkGfiGate(
73
75
  event: PluginHookBeforeToolCallEvent,
74
76
  wctx: WorkspaceContext,
@@ -66,6 +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
  export function detectLifecycleIntent(message: string): LifecycleIntent {
70
71
  // Check promote patterns
71
72
  for (const p of PROMOTE_PATTERNS_EN) {
@@ -197,6 +197,7 @@ export async function handleBeforeCompaction(
197
197
 
198
198
  // 新增:提取并保存工作记忆
199
199
 
200
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
200
201
  await extractAndSaveWorkingMemory(event.sessionFile, ctx, wctx);
201
202
  }
202
203
  }
package/src/hooks/llm.ts CHANGED
@@ -256,6 +256,7 @@ export function handleLlmOutput(
256
256
 
257
257
  // ═══ Thinking OS: Mental Model Usage Tracking ═══
258
258
 
259
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
259
260
  trackThinkingModelUsage({
260
261
  text,
261
262
  wctx,
package/src/hooks/pain.ts CHANGED
@@ -131,6 +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
  const errorType = extractErrorType(event.error || errorText);
135
136
  const filePath = params.file_path || params.path || params.file;
136
137
  const relPath = typeof filePath === 'string' ? normalizePath(filePath, effectiveWorkspaceDir) : 'unknown';
@@ -193,6 +194,7 @@ export function handleAfterToolCall(
193
194
  const session = getSession(sessionId);
194
195
  const toolFailureGfi = session?.gfiBySource?.tool_failure || 0;
195
196
 
197
+ // eslint-disable-next-line @typescript-eslint/init-declarations
196
198
  let resetState: SessionState;
197
199
  if (toolFailureGfi > 0) {
198
200
  // Reduce tool_failure source by 50% (relief from successful tool execution)
@@ -391,6 +393,7 @@ export function handleAfterToolCall(
391
393
  });
392
394
  }
393
395
 
396
+
394
397
  function extractErrorType(error: unknown): string {
395
398
  if (!error) return 'Unknown';
396
399
  const msg = String(error);
@@ -87,6 +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
  function block(
91
92
  filePath: string,
92
93
  reason: string,
@@ -120,6 +121,7 @@ function block(
120
121
  * @returns PluginHookBeforeToolCallResult to block, or undefined to allow
121
122
  */
122
123
 
124
+ // eslint-disable-next-line @typescript-eslint/max-params
123
125
  export function checkProgressiveTrustGate(
124
126
  event: PluginHookBeforeToolCallEvent,
125
127
  wctx: WorkspaceContext,
@@ -152,6 +154,7 @@ export function checkProgressiveTrustGate(
152
154
 
153
155
  const currentTier = epDecision.currentTier ?? 1;
154
156
 
157
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
155
158
  const tierName = getTierName(currentTier);
156
159
 
157
160
  logger.info?.(`[PD_GATE] EP Gate: Tier ${currentTier} (${tierName}), Tool: ${event.toolName}, Risk: ${risky}, Allowed: ${epDecision.allowed}`);
@@ -202,6 +202,7 @@ export function loadContextInjectionConfig(workspaceDir: string): ContextInjecti
202
202
  * Falls back to main model if no diagnostician model is configured
203
203
  * @internal Helper for model configuration resolution
204
204
  */
205
+
205
206
  export function getDiagnosticianModel(api: PromptHookApi | null, logger?: PluginLogger): string {
206
207
  // Determines logger: prefer api.logger, fallback to provided logger
207
208
  // 1. getDiagnosticianModel(api) - uses api.logger
@@ -367,6 +368,7 @@ export async function handleBeforePromptBuild(
367
368
  // prependContext: Only short dynamic directives: evolutionDirective + heartbeat
368
369
 
369
370
 
371
+ // eslint-disable-next-line @typescript-eslint/init-declarations
370
372
  let prependSystemContext: string;
371
373
  let prependContext = '';
372
374
  let appendSystemContext = '';
@@ -682,6 +684,7 @@ ${taskBlocks}${processingNote}
682
684
 
683
685
  // ──── 6. Dynamic Attitude Matrix (based on GFI) ────
684
686
 
687
+ // eslint-disable-next-line @typescript-eslint/init-declarations
685
688
  let attitudeDirective: string;
686
689
  const currentGfi = session?.currentGfi || 0;
687
690
 
@@ -907,9 +910,10 @@ ${taskBlocks}${processingNote}
907
910
  const toolMatches = toolPatterns.flatMap(({ pattern, tool }) => {
908
911
  const matches: string[] = [];
909
912
 
913
+ // eslint-disable-next-line @typescript-eslint/init-declarations
910
914
  let _m;
911
915
  const r = new RegExp(pattern.source, pattern.flags);
912
- /* eslint-disable @typescript-eslint/no-unused-vars -- Reason: regex exec side effect used, match variable intentionally unused */
916
+
913
917
  while ((_m = r.exec(latestUserText)) !== null) matches.push(tool);
914
918
  return matches;
915
919
  });
@@ -14,6 +14,7 @@ import type { WorkflowManager } from '../service/subagent-workflow/types.js';
14
14
  * Used by the subagent_ended hook to dispatch lifecycle recovery to the right manager.
15
15
  */
16
16
 
17
+ // eslint-disable-next-line @typescript-eslint/max-params
17
18
  function createWorkflowManagerForType(
18
19
  workflowType: string,
19
20
  workspaceDir: string,
@@ -41,6 +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
  export function checkThinkingCheckpoint(
45
46
  event: PluginHookBeforeToolCallEvent,
46
47
  config: ThinkingCheckpointConfig,
@@ -212,6 +212,7 @@ export function handleLlmOutput(
212
212
  * 消息写入前的处理
213
213
  * 记录:用户/助手消息内容
214
214
  */
215
+
215
216
  export function handleBeforeMessageWrite(
216
217
  event: PluginHookBeforeMessageWriteEvent,
217
218
  ctx: PluginHookAgentContext & { workspaceDir?: string }
@@ -230,6 +231,7 @@ export function handleBeforeMessageWrite(
230
231
  if (typeof msg.content === 'string') {
231
232
 
232
233
  // Reason: msg.content is string | ContentPart[]; destructuring would require renaming in the else branch
234
+ // eslint-disable-next-line @typescript-eslint/prefer-destructuring
233
235
  content = msg.content;
234
236
  } else if (Array.isArray(msg.content)) {
235
237
  content = msg.content
@@ -96,6 +96,7 @@ function createService(api: OpenClawPluginApi): ControlUiQueryService {
96
96
  }
97
97
 
98
98
 
99
+ // eslint-disable-next-line @typescript-eslint/max-params
99
100
  function handleApiRoute(
100
101
  api: OpenClawPluginApi,
101
102
  pathname: string,
@@ -104,11 +105,13 @@ function handleApiRoute(
104
105
  ): Promise<boolean> | boolean {
105
106
  // Check authentication for API routes
106
107
 
108
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
107
109
  if (!validateGatewayAuth(req)) {
108
110
  json(res, 401, { error: 'unauthorized', message: 'Valid Gateway token required.' });
109
111
  return true;
110
112
  }
111
113
 
114
+ // eslint-disable-next-line @typescript-eslint/init-declarations
112
115
  let service: ControlUiQueryService;
113
116
  try {
114
117
  service = createService(api);
@@ -578,6 +581,7 @@ export function createPrinciplesConsoleRoutes(api: OpenClawPluginApi): OpenClawP
578
581
  path: ROUTE_PREFIX,
579
582
  auth: 'plugin',
580
583
  match: 'prefix',
584
+
581
585
  async handler(req, res) {
582
586
  if (!api.rootDir) { text(res, 500, 'Plugin rootDir not available'); return true; }
583
587
  const url = new URL(req.url || ROUTE_PREFIX, 'http://127.0.0.1');
@@ -640,6 +644,7 @@ export function createPrinciplesConsoleRoute(api: OpenClawPluginApi): OpenClawPl
640
644
  path: ROUTE_PREFIX,
641
645
  auth: 'plugin',
642
646
  match: 'prefix',
647
+
643
648
  async handler(req, res) {
644
649
  if (!api.rootDir) { text(res, 500, 'Plugin rootDir not available'); return true; }
645
650
  const url = new URL(req.url || ROUTE_PREFIX, 'http://127.0.0.1');
package/src/index.ts CHANGED
@@ -401,6 +401,7 @@ const plugin = {
401
401
 
402
402
  // ── Slash Commands ──
403
403
  // Register command with optional short alias
404
+ // eslint-disable-next-line @typescript-eslint/max-params, @typescript-eslint/no-explicit-any
404
405
  const registerCommandWithAlias = (name: string, alias: string | null, desc: string, handler: any, opts?: { acceptsArgs?: boolean }) => {
405
406
  const base = {
406
407
  name,
@@ -418,11 +419,17 @@ const plugin = {
418
419
  }
419
420
  };
420
421
 
422
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
421
423
  registerCommandWithAlias('pd-init', 'pdi', getCommandDescription('pd-init', language), (ctx: any) => handleInitStrategy(ctx));
424
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
422
425
  registerCommandWithAlias('pd-okr', 'pdk', getCommandDescription('pd-okr', language), (ctx: any) => handleManageOkr(ctx));
426
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
423
427
  registerCommandWithAlias('pd-bootstrap', 'pdb', getCommandDescription('pd-bootstrap', language), (ctx: any) => handleBootstrapTools(ctx));
428
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
424
429
  registerCommandWithAlias('pd-research', 'pdr', getCommandDescription('pd-research', language), (ctx: any) => handleResearchTools(ctx));
430
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
425
431
  registerCommandWithAlias('pd-thinking', 'pdt', getCommandDescription('pd-thinking', language), (ctx: any) => handleThinkingOs(ctx), { acceptsArgs: true });
432
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
426
433
  registerCommandWithAlias('pd-reflect', 'pdrl', getCommandDescription('pd-reflect', language), (ctx: any) => {
427
434
  try {
428
435
  // Resolve agentId from sessionKey (if available), fallback to 'main'