principles-disciple 1.41.0 → 1.43.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 (95) hide show
  1. package/.planning/codebase/ARCHITECTURE.md +157 -0
  2. package/.planning/codebase/CONCERNS.md +145 -0
  3. package/.planning/codebase/CONVENTIONS.md +148 -0
  4. package/.planning/codebase/INTEGRATIONS.md +81 -0
  5. package/.planning/codebase/STACK.md +87 -0
  6. package/.planning/codebase/STRUCTURE.md +193 -0
  7. package/.planning/codebase/TESTING.md +243 -0
  8. package/openclaw.plugin.json +1 -1
  9. package/package.json +1 -1
  10. package/src/commands/archive-impl.ts +5 -3
  11. package/src/commands/context.ts +1 -0
  12. package/src/commands/disable-impl.ts +1 -1
  13. package/src/commands/evolution-status.ts +2 -2
  14. package/src/commands/pain.ts +12 -5
  15. package/src/commands/principle-rollback.ts +1 -1
  16. package/src/commands/promote-impl.ts +13 -7
  17. package/src/commands/rollback.ts +10 -4
  18. package/src/commands/samples.ts +1 -1
  19. package/src/commands/thinking-os.ts +1 -0
  20. package/src/commands/workflow-debug.ts +1 -1
  21. package/src/core/config.ts +1 -0
  22. package/src/core/dictionary.ts +1 -0
  23. package/src/core/event-log.ts +8 -6
  24. package/src/core/evolution-types.ts +33 -1
  25. package/src/core/external-training-contract.ts +1 -1
  26. package/src/core/merge-gate-audit.ts +3 -3
  27. package/src/core/nocturnal-arbiter.ts +1 -1
  28. package/src/core/nocturnal-compliance.ts +21 -21
  29. package/src/core/nocturnal-executability.ts +1 -1
  30. package/src/core/nocturnal-reasoning-deriver.ts +4 -4
  31. package/src/core/nocturnal-rule-implementation-validator.ts +1 -1
  32. package/src/core/nocturnal-snapshot-contract.ts +1 -1
  33. package/src/core/pain-context-extractor.ts +2 -2
  34. package/src/core/path-resolver.ts +1 -0
  35. package/src/core/pd-task-reconciler.ts +1 -0
  36. package/src/core/pd-task-service.ts +1 -1
  37. package/src/core/pd-task-store.ts +1 -0
  38. package/src/core/principle-internalization/deprecated-readiness.ts +1 -1
  39. package/src/core/principle-internalization/principle-lifecycle-service.ts +1 -1
  40. package/src/core/principle-training-state.ts +2 -2
  41. package/src/core/principle-tree-migration.ts +1 -1
  42. package/src/core/replay-engine.ts +1 -0
  43. package/src/core/risk-calculator.ts +2 -1
  44. package/src/core/rule-host.ts +1 -1
  45. package/src/core/session-tracker.ts +1 -0
  46. package/src/core/shadow-observation-registry.ts +1 -1
  47. package/src/core/thinking-models.ts +1 -1
  48. package/src/core/thinking-os-parser.ts +1 -1
  49. package/src/core/trajectory.ts +2 -0
  50. package/src/hooks/bash-risk.ts +2 -2
  51. package/src/hooks/edit-verification.ts +3 -3
  52. package/src/hooks/gate.ts +8 -8
  53. package/src/hooks/gfi-gate.ts +2 -2
  54. package/src/hooks/lifecycle-routing.ts +1 -1
  55. package/src/hooks/message-sanitize.ts +18 -5
  56. package/src/hooks/pain.ts +2 -2
  57. package/src/hooks/progressive-trust-gate.ts +3 -3
  58. package/src/hooks/prompt.ts +17 -4
  59. package/src/hooks/subagent.ts +2 -3
  60. package/src/hooks/thinking-checkpoint.ts +1 -1
  61. package/src/http/principles-console-route.ts +21 -4
  62. package/src/service/central-database.ts +3 -2
  63. package/src/service/central-health-service.ts +2 -1
  64. package/src/service/central-overview-service.ts +3 -2
  65. package/src/service/control-ui-query-service.ts +2 -2
  66. package/src/service/event-log-auditor.ts +2 -2
  67. package/src/service/evolution-query-service.ts +1 -1
  68. package/src/service/evolution-worker.ts +96 -370
  69. package/src/service/health-query-service.ts +11 -10
  70. package/src/service/monitoring-query-service.ts +4 -4
  71. package/src/service/nocturnal-target-selector.ts +2 -2
  72. package/src/service/queue-io.ts +375 -0
  73. package/src/service/queue-migration.ts +122 -0
  74. package/src/service/runtime-summary-service.ts +1 -1
  75. package/src/service/sleep-cycle.ts +157 -0
  76. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +1 -0
  77. package/src/service/subagent-workflow/runtime-direct-driver.ts +1 -1
  78. package/src/service/subagent-workflow/subagent-error-utils.ts +1 -1
  79. package/src/service/subagent-workflow/workflow-store.ts +3 -2
  80. package/src/service/workflow-watchdog.ts +168 -0
  81. package/src/tools/critique-prompt.ts +1 -1
  82. package/src/tools/deep-reflect.ts +22 -11
  83. package/src/tools/model-index.ts +1 -1
  84. package/src/types/event-payload.ts +80 -0
  85. package/src/types/queue.ts +70 -0
  86. package/src/utils/file-lock.ts +2 -2
  87. package/src/utils/io.ts +11 -3
  88. package/tests/core/evolution-migration.test.ts +325 -1
  89. package/tests/core/queue-purge.test.ts +337 -0
  90. package/tests/fixtures/legacy-queue-v1.json +74 -0
  91. package/tests/queue/async-lock.test.ts +200 -0
  92. package/tests/service/evolution-worker.queue.test.ts +296 -0
  93. package/tests/service/queue-io.test.ts +229 -0
  94. package/tests/service/queue-migration.test.ts +147 -0
  95. package/tests/service/workflow-watchdog.test.ts +372 -0
@@ -21,7 +21,7 @@ function formatState(state: string): string {
21
21
  }
22
22
 
23
23
 
24
- // eslint-disable-next-line @typescript-eslint/max-params
24
+
25
25
  function buildOutput(
26
26
  workflowId: string,
27
27
  summary: ReturnType<InstanceType<typeof WorkflowStore>['getWorkflow']>,
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-console */
1
2
  import * as fs from 'fs';
2
3
  import * as path from 'path';
3
4
  import { atomicWriteFileSync } from '../utils/io.js';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-console */
1
2
  import * as fs from 'fs';
2
3
  import * as path from 'path';
3
4
  import { atomicWriteFileSync } from '../utils/io.js';
@@ -1,3 +1,4 @@
1
+
1
2
  import * as fs from 'fs';
2
3
  import * as path from 'path';
3
4
  import type {
@@ -94,7 +95,7 @@ export class EventLog {
94
95
  /**
95
96
  * Clean up event files older than EVENT_LOG_RETENTION_DAYS.
96
97
  */
97
- private cleanupOldEventFiles(today: string): void {
98
+ private cleanupOldEventFiles(_today: string): void {
98
99
  if (EVENT_LOG_RETENTION_DAYS <= 0) return;
99
100
 
100
101
  try {
@@ -110,8 +111,8 @@ export class EventLog {
110
111
  fs.unlinkSync(filePath);
111
112
  }
112
113
  }
113
- } catch {
114
- // Silently fail cleanup
114
+ } catch (err) {
115
+ this.logger?.debug?.(`[PD] Event file cleanup failed (non-blocking): ${String(err)}`);
115
116
  }
116
117
  }
117
118
 
@@ -220,6 +221,7 @@ export class EventLog {
220
221
  }
221
222
  }
222
223
 
224
+
223
225
  private updateStats(entry: EventLogEntry): void {
224
226
  let stats = this.statsCache.get(entry.date);
225
227
  if (!stats) {
@@ -228,8 +230,6 @@ export class EventLog {
228
230
  }
229
231
 
230
232
  if (entry.type === 'tool_call') {
231
-
232
- const _data = entry.data as unknown as ToolCallEventData;
233
233
  stats.tools.total++;
234
234
  if (entry.category === 'success') stats.tools.success++;
235
235
  else stats.tools.failure++;
@@ -349,7 +349,8 @@ export class EventLog {
349
349
  .map((line) => {
350
350
  try {
351
351
  return JSON.parse(line) as EventLogEntry;
352
- } catch {
352
+ } catch (err) {
353
+ this.logger?.warn?.(`[PD] Corrupted event line skipped: ${String(err).slice(0, 100)}`);
353
354
  return null;
354
355
  }
355
356
  })
@@ -499,6 +500,7 @@ export class EventLog {
499
500
  /**
500
501
  * Aggregate empathy stats for a specific session.
501
502
  */
503
+
502
504
  private aggregateSessionEmpathy(sessionId: string, result: EmpathyEventStats): void {
503
505
  for (const entry of this.getMergedEvents()) {
504
506
  if (entry.sessionId === sessionId && entry.type === 'pain_signal') {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Evolution Points System V2.0 - MVP
3
- *
3
+ *
4
4
  * Core Philosophy: Growth-driven替代Penalty-driven
5
5
  * - 起点0分,只能增加,不扣分
6
6
  * - 失败记录教训,不扣分
@@ -8,6 +8,9 @@
8
8
  * - 5级成长路径:Seed → Forest
9
9
  */
10
10
 
11
+ // V2 queue types require TaskKind/TaskPriority from trajectory-types
12
+ import type { TaskKind, TaskPriority } from './trajectory-types.js';
13
+
11
14
  // ===== 等级定义 =====
12
15
 
13
16
 
@@ -464,3 +467,32 @@ export type EvolutionLoopEvent =
464
467
  | { ts: string; type: 'principle_rolled_back'; data: PrincipleRolledBackData }
465
468
  | { ts: string; type: 'circuit_breaker_opened'; data: CircuitBreakerOpenedData }
466
469
  | { ts: string; type: 'legacy_import'; data: LegacyImportData };
470
+
471
+ // V2 Queue Types (moved from evolution-worker.ts for shared use)
472
+ export type QueueStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'canceled';
473
+ export type TaskResolution = 'marker_detected' | 'auto_completed_timeout' | 'failed_max_retries' | 'runtime_unavailable' | 'canceled' | 'late_marker_principle_created' | 'late_marker_no_principle' | 'stub_fallback' | 'skipped_thin_violation' | 'success' | 'failure' | 'skipped';
474
+
475
+ export interface EvolutionQueueItem {
476
+ id: string;
477
+ taskKind: TaskKind;
478
+ priority: TaskPriority;
479
+ source: string;
480
+ traceId?: string;
481
+ task?: string;
482
+ score: number;
483
+ reason: string;
484
+ timestamp: string;
485
+ enqueued_at?: string;
486
+ started_at?: string;
487
+ completed_at?: string;
488
+ assigned_session_key?: string;
489
+ trigger_text_preview?: string;
490
+ status: QueueStatus;
491
+ resolution?: TaskResolution;
492
+ session_id?: string;
493
+ agent_id?: string;
494
+ retryCount: number;
495
+ maxRetries: number;
496
+ lastError?: string;
497
+ resultRef?: string;
498
+ }
@@ -405,7 +405,7 @@ export function computeConfigFingerprint(config: Partial<TrainingHyperparameters
405
405
  */
406
406
  export function computeDatasetFingerprint(exportPath: string, sampleCount: number): string {
407
407
 
408
- // eslint-disable-next-line @typescript-eslint/init-declarations
408
+
409
409
  let contentHash: string;
410
410
  try {
411
411
  const content = fs.readFileSync(exportPath, 'utf-8');
@@ -342,7 +342,7 @@ function hasValidEvidenceSummary(parsed: unknown): boolean {
342
342
  * Validate a single replay report file and return its category.
343
343
  */
344
344
  function validateSingleReplayReport(reportPath: string): ReplayValidationCategory {
345
- // eslint-disable-next-line @typescript-eslint/init-declarations
345
+
346
346
  let rawContent: string;
347
347
  try {
348
348
  rawContent = fs.readFileSync(reportPath, 'utf-8');
@@ -350,7 +350,7 @@ function validateSingleReplayReport(reportPath: string): ReplayValidationCategor
350
350
  return 'io_error';
351
351
  }
352
352
 
353
- // eslint-disable-next-line @typescript-eslint/init-declarations
353
+
354
354
  let parsed: unknown;
355
355
  try {
356
356
  parsed = JSON.parse(rawContent);
@@ -366,7 +366,7 @@ function validateSingleReplayReport(reportPath: string): ReplayValidationCategor
366
366
  return 'missing_evidence_summary';
367
367
  }
368
368
 
369
- // eslint-disable-next-line @typescript-eslint/prefer-destructuring
369
+
370
370
  const evidenceSummary = parsed.evidenceSummary;
371
371
  if (parsed.overallDecision === 'pass' && evidenceSummary.totalSamples === 0) {
372
372
  return 'unsupported_pass';
@@ -694,7 +694,7 @@ export function parseAndValidateArtifact(
694
694
  ): ArbiterResult {
695
695
  // Step 1: Parse JSON
696
696
 
697
- // eslint-disable-next-line @typescript-eslint/init-declarations
697
+
698
698
  let parsed: unknown;
699
699
  try {
700
700
  parsed = JSON.parse(jsonString);
@@ -242,31 +242,31 @@ export function detectOpportunity(principleId: string, session: SessionEvents):
242
242
 
243
243
  switch (principleId) {
244
244
  case 'T-01':
245
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
245
+
246
246
  return detectT01Opportunity(session);
247
247
  case 'T-02':
248
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
248
+
249
249
  return detectT02Opportunity(session);
250
250
  case 'T-03':
251
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
251
+
252
252
  return detectT03Opportunity(session);
253
253
  case 'T-04':
254
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
254
+
255
255
  return detectT04Opportunity(session);
256
256
  case 'T-05':
257
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
257
+
258
258
  return detectT05Opportunity(session);
259
259
  case 'T-06':
260
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
260
+
261
261
  return detectT06Opportunity(session);
262
262
  case 'T-07':
263
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
263
+
264
264
  return detectT07Opportunity(session);
265
265
  case 'T-08':
266
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
266
+
267
267
  return detectT08Opportunity(session);
268
268
  case 'T-09':
269
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
269
+
270
270
  return detectT09Opportunity(session);
271
271
  default:
272
272
  return { applicable: false, reason: `Unknown principle: ${principleId}` };
@@ -550,31 +550,31 @@ export function detectViolation(principleId: string, session: SessionEvents): Vi
550
550
 
551
551
  switch (principleId) {
552
552
  case 'T-01':
553
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
553
+
554
554
  return detectT01Violation(session);
555
555
  case 'T-02':
556
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
556
+
557
557
  return detectT02Violation(session);
558
558
  case 'T-03':
559
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
559
+
560
560
  return detectT03Violation(session);
561
561
  case 'T-04':
562
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
562
+
563
563
  return detectT04Violation(session);
564
564
  case 'T-05':
565
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
565
+
566
566
  return detectT05Violation(session);
567
567
  case 'T-06':
568
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
568
+
569
569
  return detectT06Violation(session);
570
570
  case 'T-07':
571
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
571
+
572
572
  return detectT07Violation(session);
573
573
  case 'T-08':
574
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
574
+
575
575
  return detectT08Violation(session);
576
576
  case 'T-09':
577
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
577
+
578
578
  return detectT09Violation(session);
579
579
  default:
580
580
  console.warn(`[PD:Compliance] Unknown principle ID: ${principleId} — treating as no violation. Check for typos (P-001 vs P_001).`);
@@ -933,11 +933,11 @@ export function computeCompliance(
933
933
  : 0;
934
934
 
935
935
  // Compute violationTrend using windows
936
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
936
+
937
937
  const violationTrend = computeViolationTrend(applicableSessions, windowSize);
938
938
 
939
939
  // Build explanation
940
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
940
+
941
941
  const explanation = buildExplanation(
942
942
  principleId,
943
943
  applicableOpportunityCount,
@@ -1009,7 +1009,7 @@ function computeViolationTrend(
1009
1009
  * Builds a human-readable explanation for the compliance result.
1010
1010
  */
1011
1011
 
1012
- // eslint-disable-next-line @typescript-eslint/max-params
1012
+
1013
1013
  function buildExplanation(
1014
1014
  principleId: string,
1015
1015
  applicableOpportunityCount: number,
@@ -278,7 +278,7 @@ function isTooGeneric(text: string): boolean {
278
278
  * @param artifact - The validated artifact from arbiter (passed = true)
279
279
  * @returns ExecutabilityResult
280
280
  */
281
- // eslint-disable-next-line complexity -- complexity 14, refactor candidate
281
+
282
282
  export function validateExecutability(artifact: {
283
283
  badDecision: string;
284
284
  betterDecision: string;
@@ -144,7 +144,7 @@ export function deriveReasoningChain(assistantTurns: NocturnalAssistantTurn[]):
144
144
  // Without thinking tags we cannot extract a genuine reasoning trace, so
145
145
  // we fall back to 'low' rather than misleading the downstream pipeline
146
146
  // with activation derived from non-thinking patterns in the response text.
147
- // eslint-disable-next-line @typescript-eslint/init-declarations
147
+
148
148
  let confidenceSignal: "high" | "medium" | "low";
149
149
  if (thinkingContent.length === 0) {
150
150
  confidenceSignal = 'low';
@@ -213,7 +213,7 @@ export function deriveDecisionPoints(
213
213
 
214
214
  // Binary search: find rightmost assistant turn with createdAt < tcTime
215
215
  const findBeforeTurn = (tcTime: number): NocturnalAssistantTurn | undefined => {
216
- // eslint-disable-next-line @typescript-eslint/init-declarations
216
+
217
217
  let lo = 0, hi = sortedTurns.length - 1, result: NocturnalAssistantTurn | undefined;
218
218
  while (lo <= hi) {
219
219
  const mid = (lo + hi) >>> 1;
@@ -236,9 +236,9 @@ export function deriveDecisionPoints(
236
236
  : '';
237
237
 
238
238
  // On failure, find next assistant turn after tool call
239
- // eslint-disable-next-line @typescript-eslint/init-declarations
239
+
240
240
  let afterReflection: string | undefined;
241
- // eslint-disable-next-line @typescript-eslint/init-declarations
241
+
242
242
  let confidenceDelta: number | undefined;
243
243
 
244
244
  if (tc.outcome === 'failure') {
@@ -85,7 +85,7 @@ function extractHelperUsage(sourceCode: string): string[] {
85
85
  );
86
86
  }
87
87
 
88
- // eslint-disable-next-line complexity -- complexity 11, slightly over threshold
88
+
89
89
  function validateMeta(meta: unknown): RuleImplementationValidationFailure[] {
90
90
  if (!meta || typeof meta !== 'object') {
91
91
  return [
@@ -53,7 +53,7 @@ export function validateNocturnalSnapshotIngress(
53
53
  }
54
54
  }
55
55
 
56
- // eslint-disable-next-line @typescript-eslint/prefer-destructuring
56
+
57
57
  const stats = value.stats;
58
58
  if (!isObjectRecord(stats)) {
59
59
  reasons.push('snapshot.stats must be an object');
@@ -54,7 +54,7 @@ async function safeTail(filePath: string): Promise<string[]> {
54
54
  try {
55
55
  // Check existence and stats asynchronously
56
56
 
57
- // eslint-disable-next-line @typescript-eslint/init-declarations
57
+
58
58
  let stat: fs.Stats;
59
59
  try {
60
60
  stat = await fsPromises.stat(filePath);
@@ -237,7 +237,7 @@ export async function extractRecentConversation(
237
237
  /**
238
238
  * Extracts failed tool call context with argument correlation.
239
239
  */
240
- // eslint-disable-next-line @typescript-eslint/max-params
240
+
241
241
  export async function extractFailedToolContext(
242
242
  sessionId: string,
243
243
  agentId: string,
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-console */
1
2
  import * as path from 'path';
2
3
  import * as os from 'os';
3
4
  import * as fs from 'fs';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-console */
1
2
  import * as fs from 'fs';
2
3
  import * as path from 'path';
3
4
  import * as os from 'os';
@@ -4,7 +4,7 @@ import { reconcilePDTasks } from './pd-task-reconciler.js';
4
4
  export const PDTaskService: OpenClawPluginService = {
5
5
  id: 'principles-disciple-task-manager',
6
6
 
7
- // eslint-disable-next-line complexity -- complexity 14, refactor candidate
7
+
8
8
  async start(ctx: OpenClawPluginServiceContext): Promise<void> {
9
9
  const {workspaceDir} = ctx;
10
10
  if (!workspaceDir) {
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-console */
1
2
  import * as fs from 'fs';
2
3
  import * as path from 'path';
3
4
  import type { PDTaskSpec } from './pd-task-types.js';
@@ -65,7 +65,7 @@ export function assessDeprecatedReadiness(
65
65
  );
66
66
 
67
67
 
68
- // eslint-disable-next-line @typescript-eslint/init-declarations
68
+
69
69
  let status: DeprecatedReadinessStatus;
70
70
  if (blockingReasons.length === 0 && stableCoverageRatio === 1) {
71
71
  status = 'ready';
@@ -38,7 +38,7 @@ export interface PrincipleLifecycleAssessment {
38
38
  routeRecommendation: InternalizationRouteRecommendation;
39
39
  }
40
40
 
41
- // eslint-disable-next-line complexity -- complexity 15, refactor candidate
41
+
42
42
  function createValueMetrics(
43
43
  principle: PrincipleLifecycleEvidence,
44
44
  adherence: PrincipleAdherenceResult,
@@ -63,7 +63,7 @@ export function createDefaultPrincipleState(principleId: string): PrincipleTrain
63
63
 
64
64
  export function loadStore(stateDir: string): PrincipleTrainingStore {
65
65
 
66
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
66
+
67
67
  return ledgerTrainingStore(stateDir);
68
68
  }
69
69
 
@@ -77,7 +77,7 @@ export function saveStore(stateDir: string, store: PrincipleTrainingStore): void
77
77
 
78
78
  export async function loadStoreAsync(stateDir: string): Promise<PrincipleTrainingStore> {
79
79
 
80
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
80
+
81
81
  return ledgerTrainingStore(stateDir);
82
82
  }
83
83
 
@@ -50,7 +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
54
  status: mapInternalizationStatusToPrincipleStatus(state.internalizationStatus),
55
55
  priority: 'P1', // Default priority
56
56
  scope: 'general',
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-console */
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
+ /* eslint-disable no-console */
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';
@@ -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,7 +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
131
  export function handleEditVerification(
132
132
  event: PluginHookBeforeToolCallEvent,
133
133
  wctx: WorkspaceContext,
@@ -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) {