principles-disciple 1.28.1 → 1.28.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/openclaw.plugin.json +4 -4
- package/package.json +1 -1
- package/src/commands/archive-impl.ts +3 -0
- package/src/commands/context.ts +4 -0
- package/src/commands/disable-impl.ts +2 -0
- package/src/commands/evolution-status.ts +2 -0
- package/src/commands/focus.ts +4 -0
- package/src/commands/nocturnal-train.ts +9 -1
- package/src/commands/pain.ts +3 -0
- package/src/commands/pd-reflect.ts +2 -0
- package/src/commands/principle-rollback.ts +1 -0
- package/src/commands/rollback-impl.ts +5 -0
- package/src/commands/rollback.ts +2 -1
- package/src/commands/samples.ts +1 -0
- package/src/commands/workflow-debug.ts +1 -0
- package/src/core/adaptive-thresholds.ts +2 -0
- package/src/core/code-implementation-storage.ts +2 -0
- package/src/core/config.ts +1 -0
- package/src/core/diagnostician-task-store.ts +2 -0
- package/src/core/dictionary.ts +1 -0
- package/src/core/empathy-keyword-matcher.ts +4 -0
- package/src/core/event-log.ts +6 -1
- package/src/core/evolution-engine.ts +4 -0
- package/src/core/evolution-logger.ts +1 -0
- package/src/core/external-training-contract.ts +2 -0
- package/src/core/focus-history.ts +15 -0
- package/src/core/init.ts +3 -0
- package/src/core/merge-gate-audit.ts +3 -0
- package/src/core/model-deployment-registry.ts +1 -0
- package/src/core/model-training-registry.ts +1 -0
- package/src/core/nocturnal-arbiter.ts +4 -0
- package/src/core/nocturnal-candidate-scoring.ts +5 -0
- package/src/core/nocturnal-compliance.ts +22 -0
- package/src/core/nocturnal-dataset.ts +3 -0
- package/src/core/nocturnal-executability.ts +1 -0
- package/src/core/nocturnal-export.ts +5 -0
- package/src/core/nocturnal-reasoning-deriver.ts +6 -0
- package/src/core/nocturnal-rule-implementation-validator.ts +1 -0
- package/src/core/nocturnal-snapshot-contract.ts +1 -0
- package/src/core/nocturnal-trinity.ts +24 -0
- package/src/core/pain-context-extractor.ts +3 -0
- package/src/core/pain.ts +3 -0
- package/src/core/pd-task-reconciler.ts +3 -0
- package/src/core/pd-task-service.ts +1 -0
- package/src/core/pd-task-store.ts +1 -0
- package/src/core/principle-internalization/deprecated-readiness.ts +2 -0
- package/src/core/principle-internalization/principle-lifecycle-service.ts +1 -0
- package/src/core/principle-training-state.ts +2 -0
- package/src/core/principle-tree-ledger.ts +4 -0
- package/src/core/principle-tree-migration.ts +2 -0
- package/src/core/promotion-gate.ts +7 -1
- package/src/core/replay-engine.ts +10 -0
- package/src/core/risk-calculator.ts +2 -0
- package/src/core/rule-host.ts +3 -0
- package/src/core/session-tracker.ts +5 -0
- package/src/core/shadow-observation-registry.ts +1 -0
- package/src/core/thinking-models.ts +1 -0
- package/src/core/thinking-os-parser.ts +1 -0
- package/src/core/trajectory.ts +9 -1
- package/src/hooks/bash-risk.ts +2 -0
- package/src/hooks/edit-verification.ts +3 -0
- package/src/hooks/gate-block-helper.ts +3 -0
- package/src/hooks/gate.ts +8 -0
- package/src/hooks/gfi-gate.ts +2 -0
- package/src/hooks/lifecycle-routing.ts +1 -0
- package/src/hooks/lifecycle.ts +1 -0
- package/src/hooks/llm.ts +1 -0
- package/src/hooks/pain.ts +3 -0
- package/src/hooks/progressive-trust-gate.ts +3 -0
- package/src/hooks/prompt.ts +5 -1
- package/src/hooks/subagent.ts +1 -0
- package/src/hooks/thinking-checkpoint.ts +1 -0
- package/src/hooks/trajectory-collector.ts +2 -0
- package/src/http/principles-console-route.ts +5 -0
- package/src/index.ts +7 -0
- package/src/service/central-database.ts +2 -0
- package/src/service/central-health-service.ts +1 -0
- package/src/service/central-overview-service.ts +2 -0
- package/src/service/central-sync-service.ts +1 -0
- package/src/service/control-ui-query-service.ts +2 -0
- package/src/service/event-log-auditor.ts +2 -0
- package/src/service/evolution-query-service.ts +1 -0
- package/src/service/evolution-worker.ts +31 -0
- package/src/service/health-query-service.ts +6 -1
- package/src/service/monitoring-query-service.ts +4 -0
- package/src/service/nocturnal-runtime.ts +7 -1
- package/src/service/nocturnal-service.ts +21 -0
- package/src/service/nocturnal-target-selector.ts +2 -0
- package/src/service/runtime-summary-service.ts +6 -0
- package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +2 -0
- package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +2 -0
- package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +3 -0
- package/src/service/subagent-workflow/subagent-error-utils.ts +1 -0
- package/src/service/subagent-workflow/workflow-manager-base.ts +6 -0
- package/src/service/subagent-workflow/workflow-store.ts +2 -0
- package/src/tools/critique-prompt.ts +1 -0
- package/src/tools/deep-reflect.ts +9 -0
- package/src/tools/model-index.ts +1 -0
- package/src/tools/write-pain-flag.ts +1 -0
- package/src/utils/file-lock.ts +1 -0
- package/src/utils/io.ts +2 -0
|
@@ -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
|
-
|
|
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,
|
package/src/core/rule-host.ts
CHANGED
|
@@ -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) {
|
package/src/core/trajectory.ts
CHANGED
|
@@ -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
|
-
|
|
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);
|
package/src/hooks/bash-risk.ts
CHANGED
|
@@ -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
|
};
|
package/src/hooks/gfi-gate.ts
CHANGED
|
@@ -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) {
|
package/src/hooks/lifecycle.ts
CHANGED
package/src/hooks/llm.ts
CHANGED
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}`);
|
package/src/hooks/prompt.ts
CHANGED
|
@@ -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
|
-
|
|
916
|
+
|
|
913
917
|
while ((_m = r.exec(latestUserText)) !== null) matches.push(tool);
|
|
914
918
|
return matches;
|
|
915
919
|
});
|
package/src/hooks/subagent.ts
CHANGED
|
@@ -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'
|