@principles/pd-cli 1.152.12 → 1.152.13
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/package.json +13 -7
- package/CHANGELOG.md +0 -23
- package/dist/commands/__tests__/intent-flag-wiring.test.d.ts +0 -9
- package/dist/commands/__tests__/intent-flag-wiring.test.d.ts.map +0 -1
- package/dist/commands/__tests__/intent-flag-wiring.test.js +0 -237
- package/dist/commands/__tests__/intent-flag-wiring.test.js.map +0 -1
- package/dist/commands/__tests__/legacy-cleanup.test.d.ts +0 -18
- package/dist/commands/__tests__/legacy-cleanup.test.d.ts.map +0 -1
- package/dist/commands/__tests__/legacy-cleanup.test.js +0 -467
- package/dist/commands/__tests__/legacy-cleanup.test.js.map +0 -1
- package/dist/commands/__tests__/mvp-smoke.test.d.ts +0 -15
- package/dist/commands/__tests__/mvp-smoke.test.d.ts.map +0 -1
- package/dist/commands/__tests__/mvp-smoke.test.js +0 -262
- package/dist/commands/__tests__/mvp-smoke.test.js.map +0 -1
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts +0 -2
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts.map +0 -1
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js +0 -60
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js.map +0 -1
- package/dist/commands/__tests__/rulecode-flag-wiring.test.d.ts +0 -21
- package/dist/commands/__tests__/rulecode-flag-wiring.test.d.ts.map +0 -1
- package/dist/commands/__tests__/rulecode-flag-wiring.test.js +0 -186
- package/dist/commands/__tests__/rulecode-flag-wiring.test.js.map +0 -1
- package/dist/commands/__tests__/rulecode-handler.test.d.ts +0 -16
- package/dist/commands/__tests__/rulecode-handler.test.d.ts.map +0 -1
- package/dist/commands/__tests__/rulecode-handler.test.js +0 -285
- package/dist/commands/__tests__/rulecode-handler.test.js.map +0 -1
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.d.ts +0 -24
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.d.ts.map +0 -1
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js +0 -232
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js.map +0 -1
- package/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts +0 -15
- package/dist/commands/__tests__/runtime-activation-nextaction.test.d.ts.map +0 -1
- package/dist/commands/__tests__/runtime-activation-nextaction.test.js +0 -73
- package/dist/commands/__tests__/runtime-activation-nextaction.test.js.map +0 -1
- package/dist/commands/__tests__/runtime-probe-config.test.d.ts +0 -20
- package/dist/commands/__tests__/runtime-probe-config.test.d.ts.map +0 -1
- package/dist/commands/__tests__/runtime-probe-config.test.js +0 -389
- package/dist/commands/__tests__/runtime-probe-config.test.js.map +0 -1
- package/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts +0 -9
- package/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts.map +0 -1
- package/dist/commands/__tests__/telemetry-flag-wiring.test.js +0 -76
- package/dist/commands/__tests__/telemetry-flag-wiring.test.js.map +0 -1
- package/dist/commands/__tests__/version.test.d.ts +0 -2
- package/dist/commands/__tests__/version.test.d.ts.map +0 -1
- package/dist/commands/__tests__/version.test.js +0 -238
- package/dist/commands/__tests__/version.test.js.map +0 -1
- package/dist/commands/runtime-uat.guard.test.d.ts +0 -2
- package/dist/commands/runtime-uat.guard.test.d.ts.map +0 -1
- package/dist/commands/runtime-uat.guard.test.js +0 -153
- package/dist/commands/runtime-uat.guard.test.js.map +0 -1
- package/dist/services/__tests__/cli-output.test.d.ts +0 -18
- package/dist/services/__tests__/cli-output.test.d.ts.map +0 -1
- package/dist/services/__tests__/cli-output.test.js +0 -103
- package/dist/services/__tests__/cli-output.test.js.map +0 -1
- package/dist/services/__tests__/evaluator-runner-deps.test.d.ts +0 -2
- package/dist/services/__tests__/evaluator-runner-deps.test.d.ts.map +0 -1
- package/dist/services/__tests__/evaluator-runner-deps.test.js +0 -343
- package/dist/services/__tests__/evaluator-runner-deps.test.js.map +0 -1
- package/dist/services/__tests__/rulehost-readiness.test.d.ts +0 -2
- package/dist/services/__tests__/rulehost-readiness.test.d.ts.map +0 -1
- package/dist/services/__tests__/rulehost-readiness.test.js +0 -311
- package/dist/services/__tests__/rulehost-readiness.test.js.map +0 -1
- package/dist/services/__tests__/runtime-adapter-resolver.test.d.ts +0 -18
- package/dist/services/__tests__/runtime-adapter-resolver.test.d.ts.map +0 -1
- package/dist/services/__tests__/runtime-adapter-resolver.test.js +0 -673
- package/dist/services/__tests__/runtime-adapter-resolver.test.js.map +0 -1
- package/dist/utils/production-workspace-guard.test.d.ts +0 -2
- package/dist/utils/production-workspace-guard.test.d.ts.map +0 -1
- package/dist/utils/production-workspace-guard.test.js +0 -137
- package/dist/utils/production-workspace-guard.test.js.map +0 -1
- package/scripts/llm-dogfood.ts +0 -456
- package/scripts/migrate-illegal-expected-decision.ts +0 -252
- package/src/commands/__tests__/intent-flag-wiring.test.ts +0 -282
- package/src/commands/__tests__/legacy-cleanup.test.ts +0 -602
- package/src/commands/__tests__/mvp-smoke.test.ts +0 -300
- package/src/commands/__tests__/pain-retry-maxTokens-flag.test.ts +0 -73
- package/src/commands/__tests__/rulecode-flag-wiring.test.ts +0 -237
- package/src/commands/__tests__/rulecode-handler.test.ts +0 -369
- package/src/commands/__tests__/run-rulehost-flag-wiring.test.ts +0 -292
- package/src/commands/__tests__/runtime-activation-nextaction.test.ts +0 -81
- package/src/commands/__tests__/runtime-probe-config.test.ts +0 -432
- package/src/commands/__tests__/telemetry-flag-wiring.test.ts +0 -84
- package/src/commands/__tests__/version.test.ts +0 -251
- package/src/commands/admission-gate.ts +0 -30
- package/src/commands/artifact.ts +0 -82
- package/src/commands/build-trajectory-evidence.ts +0 -298
- package/src/commands/candidate.ts +0 -1250
- package/src/commands/codex-ingest-catchup.ts +0 -114
- package/src/commands/codex-ingest-quarantine.ts +0 -127
- package/src/commands/codex-reconcile.ts +0 -84
- package/src/commands/codex-setup.ts +0 -476
- package/src/commands/codex-worker.ts +0 -185
- package/src/commands/command-helpers.ts +0 -24
- package/src/commands/config-doctor.ts +0 -193
- package/src/commands/console.ts +0 -797
- package/src/commands/context.ts +0 -72
- package/src/commands/demo-story-a.ts +0 -241
- package/src/commands/diagnose.ts +0 -756
- package/src/commands/errors-list.ts +0 -441
- package/src/commands/evolution-tasks-list.ts +0 -48
- package/src/commands/evolution-tasks-show.ts +0 -62
- package/src/commands/flow.ts +0 -60
- package/src/commands/health-codex.ts +0 -576
- package/src/commands/health.ts +0 -315
- package/src/commands/history.ts +0 -63
- package/src/commands/intent.ts +0 -457
- package/src/commands/legacy-cleanup.ts +0 -531
- package/src/commands/legacy-import.ts +0 -104
- package/src/commands/mvp-smoke.ts +0 -160
- package/src/commands/pain-evidence.ts +0 -226
- package/src/commands/pain-list.ts +0 -239
- package/src/commands/pain-record.ts +0 -612
- package/src/commands/pain-retry.ts +0 -916
- package/src/commands/principles-stats.ts +0 -700
- package/src/commands/proven-channel-baseline.ts +0 -115
- package/src/commands/quality-scorecard.ts +0 -272
- package/src/commands/remediation-output.ts +0 -66
- package/src/commands/rulecode.ts +0 -465
- package/src/commands/run.ts +0 -89
- package/src/commands/runtime-activation.ts +0 -1629
- package/src/commands/runtime-artifact-repair.ts +0 -524
- package/src/commands/runtime-canary.ts +0 -395
- package/src/commands/runtime-compatibility-scan.ts +0 -105
- package/src/commands/runtime-diagnostics-export.ts +0 -229
- package/src/commands/runtime-features.ts +0 -153
- package/src/commands/runtime-gfi-snapshot.ts +0 -135
- package/src/commands/runtime-health-snapshot.ts +0 -108
- package/src/commands/runtime-init.ts +0 -429
- package/src/commands/runtime-internalization-enqueue-successors.ts +0 -530
- package/src/commands/runtime-internalization-integrity-repair.ts +0 -79
- package/src/commands/runtime-internalization-integrity.ts +0 -107
- package/src/commands/runtime-internalization-queue.ts +0 -135
- package/src/commands/runtime-internalization-retry.ts +0 -191
- package/src/commands/runtime-internalization-run-once.ts +0 -791
- package/src/commands/runtime-internalization-run-rulehost.ts +0 -749
- package/src/commands/runtime-internalization-wake-once.ts +0 -87
- package/src/commands/runtime-pain-flood-simulation.ts +0 -121
- package/src/commands/runtime-pruning.ts +0 -438
- package/src/commands/runtime-recovery-failed-tasks.ts +0 -258
- package/src/commands/runtime-recovery.ts +0 -109
- package/src/commands/runtime-synthetic-baseline.ts +0 -70
- package/src/commands/runtime-uat.guard.test.ts +0 -175
- package/src/commands/runtime-uat.ts +0 -380
- package/src/commands/runtime.ts +0 -473
- package/src/commands/samples-list.ts +0 -39
- package/src/commands/samples-review.ts +0 -36
- package/src/commands/task.ts +0 -271
- package/src/commands/telemetry.ts +0 -349
- package/src/commands/trace.ts +0 -174
- package/src/commands/trajectory-db-unavailable.ts +0 -19
- package/src/commands/trajectory.ts +0 -64
- package/src/commands/version.ts +0 -49
- package/src/config-reader.ts +0 -122
- package/src/index.ts +0 -1276
- package/src/legacy/legacy-import.ts +0 -179
- package/src/legacy/session-history-import.ts +0 -203
- package/src/resolve-workspace.ts +0 -106
- package/src/services/__tests__/cli-output.test.ts +0 -130
- package/src/services/__tests__/evaluator-runner-deps.test.ts +0 -382
- package/src/services/__tests__/rulehost-readiness.test.ts +0 -363
- package/src/services/__tests__/runtime-adapter-resolver.test.ts +0 -793
- package/src/services/cli-output.ts +0 -95
- package/src/services/config-doctor.ts +0 -697
- package/src/services/console-launcher.ts +0 -537
- package/src/services/demo-rule-compiler.ts +0 -40
- package/src/services/demo-story-a-runner.ts +0 -471
- package/src/services/mainline-snapshot-assembler.ts +0 -579
- package/src/services/pain-flood-simulation-runner.ts +0 -462
- package/src/services/pd-config-loader.ts +0 -433
- package/src/services/proven-channel-baseline-runner.ts +0 -157
- package/src/services/quality-scorecard/data-extractor.ts +0 -150
- package/src/services/quality-scorecard/local-evaluator.ts +0 -142
- package/src/services/quality-scorecard/strong-model-gate.ts +0 -202
- package/src/services/resolve-runtime-from-pd-config.ts +0 -230
- package/src/services/rulehost-pipeline-runner.ts +0 -1214
- package/src/services/rulehost-readiness.ts +0 -326
- package/src/services/runtime-adapter-resolver.ts +0 -364
- package/src/services/synthetic-baseline-runner.ts +0 -400
- package/src/services/version-report.ts +0 -253
- package/src/services/workspace-tool-semantics.ts +0 -26
- package/src/utils/path-security.ts +0 -96
- package/src/utils/production-workspace-guard.test.ts +0 -157
- package/src/utils/production-workspace-guard.ts +0 -210
- package/tests/bdd/cli-contract.steps.ts +0 -346
- package/tests/bdd/principles-stats.steps.ts +0 -211
- package/tests/bdd/support/gherkin-loader.ts +0 -147
- package/tests/bdd/support/repo-root.ts +0 -62
- package/tests/bdd/support/vitest-bdd.ts +0 -179
- package/tests/commands/admission-gate-coverage.test.ts +0 -79
- package/tests/commands/build-trajectory-evidence.test.ts +0 -508
- package/tests/commands/candidate-audit-repair.test.ts +0 -421
- package/tests/commands/candidate-intake.test.ts +0 -732
- package/tests/commands/candidate-internalization-backfill.test.ts +0 -548
- package/tests/commands/candidate-internalize-lineage.test.ts +0 -628
- package/tests/commands/candidate-internalize.test.ts +0 -299
- package/tests/commands/candidate-route.test.ts +0 -329
- package/tests/commands/candidate-show.test.ts +0 -95
- package/tests/commands/cli-command-tree.test.ts +0 -144
- package/tests/commands/cli-help-snapshot.test.ts +0 -155
- package/tests/commands/cli-skill-contract.test.ts +0 -121
- package/tests/commands/codex-consent-reversibility.steps.test.ts +0 -299
- package/tests/commands/codex-ingest-quarantine.test.ts +0 -136
- package/tests/commands/codex-setup.test.ts +0 -297
- package/tests/commands/codex-worker-daemon.test.ts +0 -95
- package/tests/commands/codex-worker-registration.test.ts +0 -207
- package/tests/commands/config-doctor.test.ts +0 -336
- package/tests/commands/console-launcher-edge-cases.test.ts +0 -388
- package/tests/commands/console-open.test.ts +0 -1381
- package/tests/commands/context.test.ts +0 -114
- package/tests/commands/demo-story-a.test.ts +0 -318
- package/tests/commands/diagnose.test.ts +0 -1803
- package/tests/commands/errors-list.test.ts +0 -679
- package/tests/commands/evolution-tasks-list.test.ts +0 -41
- package/tests/commands/evolution-tasks-show.test.ts +0 -46
- package/tests/commands/health-codex.test.ts +0 -349
- package/tests/commands/health-host-wiring.test.ts +0 -76
- package/tests/commands/health-reliability.test.ts +0 -99
- package/tests/commands/health.test.ts +0 -413
- package/tests/commands/intent.test.ts +0 -321
- package/tests/commands/legacy-cleanup.test.ts +0 -148
- package/tests/commands/pain-evidence.test.ts +0 -518
- package/tests/commands/pain-list.test.ts +0 -219
- package/tests/commands/pain-record-async.test.ts +0 -335
- package/tests/commands/pain-record-session-parser.test.ts +0 -228
- package/tests/commands/pain-record.test.ts +0 -851
- package/tests/commands/pain-retry.test.ts +0 -1121
- package/tests/commands/plugin-config-resolution-cutover.test.ts +0 -229
- package/tests/commands/pri-393-runtime-config-unification.test.ts +0 -443
- package/tests/commands/principles-stats-wiring.test.ts +0 -135
- package/tests/commands/principles-stats.test.ts +0 -274
- package/tests/commands/product-path-regression.test.ts +0 -86
- package/tests/commands/proven-channel-baseline.test.ts +0 -441
- package/tests/commands/rulecode.test.ts +0 -177
- package/tests/commands/run-rulehost-handler.test.ts +0 -908
- package/tests/commands/runtime-activation-approve-flag-wiring.test.ts +0 -227
- package/tests/commands/runtime-activation-deactivate-flag-wiring.test.ts +0 -167
- package/tests/commands/runtime-activation-dispatch-flag-wiring.test.ts +0 -262
- package/tests/commands/runtime-activation-governance-audit.test.ts +0 -95
- package/tests/commands/runtime-activation-list-flag-wiring.test.ts +0 -193
- package/tests/commands/runtime-activation-promote-flag-wiring.test.ts +0 -248
- package/tests/commands/runtime-activation-shadow-telemetry.test.ts +0 -130
- package/tests/commands/runtime-activation.test.ts +0 -2052
- package/tests/commands/runtime-artifact-repair-registration.test.ts +0 -74
- package/tests/commands/runtime-artifact-repair.test.ts +0 -404
- package/tests/commands/runtime-canary.test.ts +0 -430
- package/tests/commands/runtime-compatibility-scan.test.ts +0 -146
- package/tests/commands/runtime-diagnostics-export.test.ts +0 -175
- package/tests/commands/runtime-features.test.ts +0 -249
- package/tests/commands/runtime-health-snapshot.test.ts +0 -358
- package/tests/commands/runtime-init-empty-workspace.test.ts +0 -252
- package/tests/commands/runtime-init.test.ts +0 -420
- package/tests/commands/runtime-internalization-enqueue-successors.test.ts +0 -782
- package/tests/commands/runtime-internalization-integrity-repair.test.ts +0 -239
- package/tests/commands/runtime-internalization-integrity.test.ts +0 -140
- package/tests/commands/runtime-internalization-queue.test.ts +0 -380
- package/tests/commands/runtime-internalization-retry-owner-authority.test.ts +0 -431
- package/tests/commands/runtime-internalization-run-once-evaluator-parity.test.ts +0 -269
- package/tests/commands/runtime-internalization-run-once-language.test.ts +0 -303
- package/tests/commands/runtime-internalization-run-once-real-config.test.ts +0 -237
- package/tests/commands/runtime-internalization-run-once-rollout-parity.test.ts +0 -706
- package/tests/commands/runtime-internalization-run-once.test.ts +0 -1791
- package/tests/commands/runtime-internalization-wake-once.test.ts +0 -171
- package/tests/commands/runtime-internalization.test.ts +0 -53
- package/tests/commands/runtime-pain-flood-simulation.test.ts +0 -418
- package/tests/commands/runtime-pruning.test.ts +0 -694
- package/tests/commands/runtime-recovery-failed-tasks.test.ts +0 -328
- package/tests/commands/runtime-recovery.test.ts +0 -120
- package/tests/commands/runtime-synthetic-baseline.test.ts +0 -249
- package/tests/commands/runtime-uat.test.ts +0 -397
- package/tests/commands/runtime.test.ts +0 -392
- package/tests/commands/samples-list.test.ts +0 -43
- package/tests/commands/samples-review.test.ts +0 -41
- package/tests/commands/task.test.ts +0 -153
- package/tests/commands/telemetry.test.ts +0 -190
- package/tests/commands/trace.test.ts +0 -316
- package/tests/config-reader.test.ts +0 -143
- package/tests/e2e/candidate-intake-e2e.test.ts +0 -338
- package/tests/e2e/cli-full-flow.test.ts +0 -233
- package/tests/e2e/cross-package-acceptance.test.ts +0 -635
- package/tests/helpers/pd-cli-path.ts +0 -5
- package/tests/pd-cli-smoke.test.ts +0 -13
- package/tests/resolve-workspace.test.ts +0 -196
- package/tests/services/config-doctor-signal-health.test.ts +0 -109
- package/tests/services/console-launcher.test.ts +0 -114
- package/tests/services/demo-rule-compiler.test.ts +0 -242
- package/tests/services/mainline-snapshot-assembler.test.ts +0 -572
- package/tests/services/pd-config-loader.test.ts +0 -505
- package/tests/services/proven-channel-baseline-runner.test.ts +0 -30
- package/tests/services/quality-scorecard/strong-model-gate.test.ts +0 -133
- package/tests/services/resolve-runtime-from-pd-config.test.ts +0 -485
- package/tests/services/rulehost-pipeline-e2e.test.ts +0 -538
- package/tests/services/rulehost-pipeline-runner.test.ts +0 -1242
- package/tests/services/workspace-tool-semantics.test.ts +0 -76
- package/tests/utils/path-security.test.ts +0 -180
- package/tsconfig.json +0 -26
- package/vitest.config.ts +0 -10
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
|
|
3
|
-
const mockDetectFailedTasks = vi.hoisted(() => vi.fn());
|
|
4
|
-
const mockRecoverFailedTask = vi.hoisted(() => vi.fn());
|
|
5
|
-
const mockServiceClose = vi.hoisted(() => vi.fn());
|
|
6
|
-
|
|
7
|
-
vi.mock('../../src/resolve-workspace.js', () => ({
|
|
8
|
-
resolveWorkspaceDir: vi.fn().mockReturnValue('/fake/workspace'),
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
vi.mock('@principles/core/runtime-v2', async (importOriginal) => {
|
|
12
|
-
// Keep the real kind guards (isPeerRunnerKind / isDiagnosticianStageKind):
|
|
13
|
-
// the per-kind execution guidance under test must exercise the actual
|
|
14
|
-
// classification, not a test-local reimplementation. Only the I/O-bearing
|
|
15
|
-
// service factory is replaced.
|
|
16
|
-
const actual = await importOriginal<typeof import('@principles/core/runtime-v2')>();
|
|
17
|
-
return {
|
|
18
|
-
...actual,
|
|
19
|
-
createRecoverySweepService: vi.fn().mockResolvedValue({
|
|
20
|
-
service: {
|
|
21
|
-
detectFailedTasks: mockDetectFailedTasks,
|
|
22
|
-
recoverFailedTask: mockRecoverFailedTask,
|
|
23
|
-
},
|
|
24
|
-
close: mockServiceClose,
|
|
25
|
-
}),
|
|
26
|
-
};
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
import { handleRuntimeRecoveryFailedTasks } from '../../src/commands/runtime-recovery-failed-tasks.js';
|
|
30
|
-
|
|
31
|
-
describe('pd runtime recovery failed-tasks command contract', () => {
|
|
32
|
-
let consoleLogSpy: ReturnType<typeof vi.spyOn>;
|
|
33
|
-
let consoleErrorSpy: ReturnType<typeof vi.spyOn>;
|
|
34
|
-
|
|
35
|
-
beforeEach(() => {
|
|
36
|
-
vi.clearAllMocks();
|
|
37
|
-
mockDetectFailedTasks.mockResolvedValue([]);
|
|
38
|
-
mockRecoverFailedTask.mockResolvedValue({
|
|
39
|
-
taskId: 'task-1',
|
|
40
|
-
previousStatus: 'failed',
|
|
41
|
-
newStatus: 'pending',
|
|
42
|
-
attemptCount: 0,
|
|
43
|
-
maxAttempts: 3,
|
|
44
|
-
forceApplied: false,
|
|
45
|
-
});
|
|
46
|
-
mockServiceClose.mockResolvedValue(undefined);
|
|
47
|
-
process.exitCode = 0;
|
|
48
|
-
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
49
|
-
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('dry-run JSON does not recover tasks and lists them as would_recover', async () => {
|
|
53
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
54
|
-
{
|
|
55
|
-
taskId: 'task-1',
|
|
56
|
-
taskKind: 'dreamer',
|
|
57
|
-
attemptCount: 1,
|
|
58
|
-
maxAttempts: 3,
|
|
59
|
-
isExhausted: false,
|
|
60
|
-
status: 'failed',
|
|
61
|
-
},
|
|
62
|
-
]);
|
|
63
|
-
|
|
64
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', dryRun: true, json: true });
|
|
65
|
-
|
|
66
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
67
|
-
expect(output).toMatchObject({
|
|
68
|
-
ok: true,
|
|
69
|
-
mode: 'dry_run',
|
|
70
|
-
recoveredCount: 1,
|
|
71
|
-
skippedCount: 0,
|
|
72
|
-
});
|
|
73
|
-
expect(output.tasks[0]).toMatchObject({
|
|
74
|
-
taskId: 'task-1',
|
|
75
|
-
action: 'would_recover',
|
|
76
|
-
reason: expect.stringContaining('attempts remain'),
|
|
77
|
-
});
|
|
78
|
-
expect(mockRecoverFailedTask).not.toHaveBeenCalled();
|
|
79
|
-
expect(mockServiceClose).toHaveBeenCalledTimes(1);
|
|
80
|
-
expect(process.exitCode).toBe(1); // exitCode 1 on dry-run when tasks are found
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('confirm JSON reports recovered tasks and mutates state', async () => {
|
|
84
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
85
|
-
{
|
|
86
|
-
taskId: 'task-1',
|
|
87
|
-
taskKind: 'dreamer',
|
|
88
|
-
attemptCount: 1,
|
|
89
|
-
maxAttempts: 3,
|
|
90
|
-
isExhausted: false,
|
|
91
|
-
status: 'failed',
|
|
92
|
-
},
|
|
93
|
-
]);
|
|
94
|
-
|
|
95
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', confirm: true, json: true });
|
|
96
|
-
|
|
97
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
98
|
-
expect(output).toMatchObject({
|
|
99
|
-
ok: true,
|
|
100
|
-
mode: 'confirm',
|
|
101
|
-
recoveredCount: 1,
|
|
102
|
-
skippedCount: 0,
|
|
103
|
-
});
|
|
104
|
-
expect(output.tasks[0]).toMatchObject({
|
|
105
|
-
taskId: 'task-1',
|
|
106
|
-
action: 'recovered',
|
|
107
|
-
});
|
|
108
|
-
expect(mockRecoverFailedTask).toHaveBeenCalledWith('task-1', undefined);
|
|
109
|
-
expect(mockServiceClose).toHaveBeenCalledTimes(1);
|
|
110
|
-
expect(process.exitCode).toBe(0);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('dry-run JSON skips exhausted tasks without force', async () => {
|
|
114
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
115
|
-
{
|
|
116
|
-
taskId: 'task-exhausted',
|
|
117
|
-
taskKind: 'dreamer',
|
|
118
|
-
attemptCount: 3,
|
|
119
|
-
maxAttempts: 3,
|
|
120
|
-
isExhausted: true,
|
|
121
|
-
status: 'failed',
|
|
122
|
-
},
|
|
123
|
-
]);
|
|
124
|
-
|
|
125
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', dryRun: true, json: true });
|
|
126
|
-
|
|
127
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
128
|
-
expect(output).toMatchObject({
|
|
129
|
-
ok: true,
|
|
130
|
-
mode: 'dry_run',
|
|
131
|
-
recoveredCount: 0,
|
|
132
|
-
skippedCount: 1,
|
|
133
|
-
});
|
|
134
|
-
expect(output.tasks[0]).toMatchObject({
|
|
135
|
-
taskId: 'task-exhausted',
|
|
136
|
-
action: 'skipped',
|
|
137
|
-
reason: expect.stringContaining('exhausted max attempts'),
|
|
138
|
-
});
|
|
139
|
-
expect(mockRecoverFailedTask).not.toHaveBeenCalled();
|
|
140
|
-
expect(process.exitCode).toBe(0); // exitCode 0 since recoveredCount is 0
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('confirm with force recovers exhausted tasks', async () => {
|
|
144
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
145
|
-
{
|
|
146
|
-
taskId: 'task-exhausted',
|
|
147
|
-
taskKind: 'dreamer',
|
|
148
|
-
attemptCount: 3,
|
|
149
|
-
maxAttempts: 3,
|
|
150
|
-
isExhausted: true,
|
|
151
|
-
status: 'failed',
|
|
152
|
-
},
|
|
153
|
-
]);
|
|
154
|
-
|
|
155
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', confirm: true, force: true, json: true });
|
|
156
|
-
|
|
157
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
158
|
-
expect(output).toMatchObject({
|
|
159
|
-
ok: true,
|
|
160
|
-
mode: 'confirm',
|
|
161
|
-
recoveredCount: 1,
|
|
162
|
-
skippedCount: 0,
|
|
163
|
-
});
|
|
164
|
-
expect(mockRecoverFailedTask).toHaveBeenCalledWith('task-exhausted', true);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('rejects mutual exclusion of dry-run and confirm in JSON mode', async () => {
|
|
168
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', dryRun: true, confirm: true, json: true });
|
|
169
|
-
|
|
170
|
-
expect(mockRecoverFailedTask).not.toHaveBeenCalled();
|
|
171
|
-
expect(mockServiceClose).not.toHaveBeenCalled();
|
|
172
|
-
expect(process.exitCode).toBe(1);
|
|
173
|
-
|
|
174
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
175
|
-
expect(output).toMatchObject({
|
|
176
|
-
ok: false,
|
|
177
|
-
reason: expect.stringContaining('mutually exclusive'),
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it('confirm JSON handles concurrent task modification gracefully (null result)', async () => {
|
|
182
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
183
|
-
{
|
|
184
|
-
taskId: 'task-concurrent',
|
|
185
|
-
taskKind: 'dreamer',
|
|
186
|
-
attemptCount: 1,
|
|
187
|
-
maxAttempts: 3,
|
|
188
|
-
isExhausted: false,
|
|
189
|
-
status: 'failed',
|
|
190
|
-
inputRef: null,
|
|
191
|
-
},
|
|
192
|
-
]);
|
|
193
|
-
mockRecoverFailedTask.mockResolvedValue(null);
|
|
194
|
-
|
|
195
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', confirm: true, json: true });
|
|
196
|
-
|
|
197
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
198
|
-
expect(output).toMatchObject({
|
|
199
|
-
ok: true,
|
|
200
|
-
mode: 'confirm',
|
|
201
|
-
recoveredCount: 0,
|
|
202
|
-
skippedCount: 1,
|
|
203
|
-
});
|
|
204
|
-
expect(output.tasks[0]).toMatchObject({
|
|
205
|
-
taskId: 'task-concurrent',
|
|
206
|
-
action: 'skipped',
|
|
207
|
-
reason: expect.stringContaining('no longer failed or concurrently modified'),
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
// ── PRI-674 review P2: per-kind execution guidance ────────────────────────
|
|
212
|
-
// Guidance must name commands that actually support the task kind:
|
|
213
|
-
// internalization → run-once; diagnostician parent / diag_* stage → diagnose run.
|
|
214
|
-
|
|
215
|
-
describe('per-kind execution nextAction (review P2)', () => {
|
|
216
|
-
it('diagnostician parent task points at pd diagnose run', async () => {
|
|
217
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
218
|
-
{ taskId: 'diagnosis_pain-001', taskKind: 'diagnostician', attemptCount: 1, maxAttempts: 3, isExhausted: false, status: 'failed', inputRef: 'pain-001' },
|
|
219
|
-
]);
|
|
220
|
-
|
|
221
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', confirm: true, json: true });
|
|
222
|
-
|
|
223
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
224
|
-
const nextAction: string = output.tasks[0].nextAction;
|
|
225
|
-
expect(nextAction).toContain('pd diagnose run --task-id diagnosis_pain-001');
|
|
226
|
-
expect(nextAction).not.toContain('internalization run-once');
|
|
227
|
-
// Summary must not claim a single internalization command executes everything
|
|
228
|
-
expect(output.nextAction).toContain('pd diagnose run');
|
|
229
|
-
expect(output.nextAction).not.toContain('run-once to execute recovered tasks');
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it('diag_* stage task resolves parent from inputRef linkage', async () => {
|
|
233
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
234
|
-
{ taskId: 'diag_rootcause-diagnosis_pain-001', taskKind: 'diag_rootcause', attemptCount: 1, maxAttempts: 3, isExhausted: false, status: 'failed', inputRef: 'diagnosis_pain-001' },
|
|
235
|
-
]);
|
|
236
|
-
|
|
237
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', confirm: true, json: true });
|
|
238
|
-
|
|
239
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
240
|
-
const nextAction: string = output.tasks[0].nextAction;
|
|
241
|
-
expect(nextAction).toContain('diagnosis_pain-001');
|
|
242
|
-
expect(nextAction).toContain('pd diagnose run --task-id diagnosis_pain-001');
|
|
243
|
-
expect(nextAction).not.toContain('run-once');
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
it('diag_* stage task falls back to diag_<stage>-<parent> ID convention when inputRef is null', async () => {
|
|
247
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
248
|
-
{ taskId: 'diag_router-diagnosis_pain-007', taskKind: 'diag_router', attemptCount: 1, maxAttempts: 3, isExhausted: false, status: 'failed', inputRef: null },
|
|
249
|
-
]);
|
|
250
|
-
|
|
251
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', confirm: true, json: true });
|
|
252
|
-
|
|
253
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
254
|
-
const nextAction: string = output.tasks[0].nextAction;
|
|
255
|
-
expect(nextAction).toContain('diagnosis_pain-007');
|
|
256
|
-
expect(nextAction).toContain('pd diagnose run --task-id diagnosis_pain-007');
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
it('diag_* stage task with no inputRef and non-conventional ID reports unresolved parent instead of a guessed command', async () => {
|
|
260
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
261
|
-
{ taskId: 'weird-stage-id', taskKind: 'diag_distiller', attemptCount: 1, maxAttempts: 3, isExhausted: false, status: 'failed', inputRef: null },
|
|
262
|
-
]);
|
|
263
|
-
|
|
264
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', confirm: true, json: true });
|
|
265
|
-
|
|
266
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
267
|
-
const nextAction: string = output.tasks[0].nextAction;
|
|
268
|
-
expect(nextAction).toContain('could not be resolved');
|
|
269
|
-
expect(nextAction).toContain('pd diagnose status --task-id weird-stage-id');
|
|
270
|
-
expect(nextAction).not.toContain('pd diagnose run --task-id');
|
|
271
|
-
expect(nextAction).not.toContain('run-once');
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
it('internalization task points at run-once with its runner kind', async () => {
|
|
275
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
276
|
-
{ taskId: 'pi-task-1', taskKind: 'scribe', attemptCount: 1, maxAttempts: 3, isExhausted: false, status: 'failed', inputRef: null },
|
|
277
|
-
]);
|
|
278
|
-
|
|
279
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', confirm: true, json: true });
|
|
280
|
-
|
|
281
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
282
|
-
const nextAction: string = output.tasks[0].nextAction;
|
|
283
|
-
expect(nextAction).toContain('pd runtime internalization run-once --runner scribe');
|
|
284
|
-
expect(nextAction).not.toContain('pd diagnose run');
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
it('mixed recovery summary splits guidance per executor instead of one command for all', async () => {
|
|
288
|
-
mockDetectFailedTasks.mockResolvedValue([
|
|
289
|
-
{ taskId: 'diagnosis_pain-001', taskKind: 'diagnostician', attemptCount: 1, maxAttempts: 3, isExhausted: false, status: 'failed', inputRef: 'pain-001' },
|
|
290
|
-
{ taskId: 'diag_rootcause-diagnosis_pain-001', taskKind: 'diag_rootcause', attemptCount: 1, maxAttempts: 3, isExhausted: false, status: 'failed', inputRef: 'diagnosis_pain-001' },
|
|
291
|
-
{ taskId: 'pi-task-1', taskKind: 'dreamer', attemptCount: 1, maxAttempts: 3, isExhausted: false, status: 'failed', inputRef: null },
|
|
292
|
-
{ taskId: 'pi-task-2', taskKind: 'rollout_reviewer', attemptCount: 1, maxAttempts: 3, isExhausted: false, status: 'failed', inputRef: null },
|
|
293
|
-
]);
|
|
294
|
-
|
|
295
|
-
await handleRuntimeRecoveryFailedTasks({ workspace: '/fake/workspace', confirm: true, json: true });
|
|
296
|
-
|
|
297
|
-
const output = JSON.parse(consoleLogSpy.mock.calls[0][0] as string);
|
|
298
|
-
expect(output.recoveredCount).toBe(4);
|
|
299
|
-
const summary: string = output.nextAction;
|
|
300
|
-
expect(summary).toContain('diagnostician parent task(s) (diagnosis_pain-001)');
|
|
301
|
-
expect(summary).toContain('pd diagnose run --task-id <taskId>');
|
|
302
|
-
expect(summary).toContain('diag_* stage task(s)');
|
|
303
|
-
expect(summary).toContain('internalization task(s) (pi-task-1, pi-task-2)');
|
|
304
|
-
expect(summary).toContain('run-once --runner <kind>');
|
|
305
|
-
// No stale single-command claim
|
|
306
|
-
expect(summary).not.toContain('Run pd runtime internalization run-once to execute recovered tasks');
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
it('guidance matches real command registrations (help wiring contract)', async () => {
|
|
310
|
-
// cli-7-test-wiring: the commands we recommend must actually be
|
|
311
|
-
// registered with the flags we name. Check the built CLI's help.
|
|
312
|
-
const { execFileSync } = await import('node:child_process');
|
|
313
|
-
const { getBuiltPdCliPath } = await import('../helpers/pd-cli-path.js');
|
|
314
|
-
const cliPath = getBuiltPdCliPath();
|
|
315
|
-
|
|
316
|
-
const diagnoseHelp = execFileSync('node', [cliPath, 'diagnose', 'run', '--help'], { encoding: 'utf8' });
|
|
317
|
-
expect(diagnoseHelp).toContain('--task-id');
|
|
318
|
-
expect(diagnoseHelp).toContain('--workspace');
|
|
319
|
-
|
|
320
|
-
const runOnceHelp = execFileSync('node', [cliPath, 'runtime', 'internalization', 'run-once', '--help'], { encoding: 'utf8' });
|
|
321
|
-
expect(runOnceHelp).toContain('--runner');
|
|
322
|
-
// run-once must NOT advertise diagnostician support: the supported list
|
|
323
|
-
// comes from SUPPORTED_RUNNERS (peer runners only)
|
|
324
|
-
expect(runOnceHelp).toMatch(/dreamer/);
|
|
325
|
-
expect(runOnceHelp).not.toMatch(/diag_|diagnostician/);
|
|
326
|
-
});
|
|
327
|
-
});
|
|
328
|
-
});
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
|
|
3
|
-
const mockDetectExpiredLeases = vi.hoisted(() => vi.fn());
|
|
4
|
-
const mockRecoverTask = vi.hoisted(() => vi.fn());
|
|
5
|
-
const mockServiceClose = vi.hoisted(() => vi.fn());
|
|
6
|
-
|
|
7
|
-
vi.mock('../../src/resolve-workspace.js', () => ({
|
|
8
|
-
resolveWorkspaceDir: vi.fn().mockReturnValue('/fake/workspace'),
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
vi.mock('@principles/core/runtime-v2', () => ({
|
|
12
|
-
createRecoverySweepService: vi.fn().mockResolvedValue({
|
|
13
|
-
service: {
|
|
14
|
-
detectExpiredLeases: mockDetectExpiredLeases,
|
|
15
|
-
recoverTask: mockRecoverTask,
|
|
16
|
-
},
|
|
17
|
-
close: mockServiceClose,
|
|
18
|
-
}),
|
|
19
|
-
createRemediationResult: vi.fn((input) => ({
|
|
20
|
-
mode: input.mode,
|
|
21
|
-
status: input.status ?? (input.mode === 'dry_run'
|
|
22
|
-
? (input.actions?.length > 0 ? 'would_change' : 'no_op')
|
|
23
|
-
: (input.repairedCount > 0 ? 'changed' : 'no_op')),
|
|
24
|
-
safeToConfirm: input.safeToConfirm ?? false,
|
|
25
|
-
repairedCount: input.repairedCount ?? 0,
|
|
26
|
-
skippedCount: input.skippedCount ?? 0,
|
|
27
|
-
actions: input.actions ?? [],
|
|
28
|
-
warnings: input.warnings ?? [],
|
|
29
|
-
})),
|
|
30
|
-
remediationAction: vi.fn((input) => input),
|
|
31
|
-
resolveOutputLanguage: vi.fn().mockReturnValue({ outputLanguage: 'zh-CN' }),
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
|
-
import { handleRuntimeRecoverySweep } from '../../src/commands/runtime-recovery.js';
|
|
35
|
-
|
|
36
|
-
describe('pd runtime recovery sweep remediation contract', () => {
|
|
37
|
-
let consoleLogSpy: ReturnType<typeof vi.spyOn>;
|
|
38
|
-
let consoleErrorSpy: ReturnType<typeof vi.spyOn>;
|
|
39
|
-
|
|
40
|
-
beforeEach(() => {
|
|
41
|
-
vi.clearAllMocks();
|
|
42
|
-
mockDetectExpiredLeases.mockResolvedValue([]);
|
|
43
|
-
mockRecoverTask.mockResolvedValue(null);
|
|
44
|
-
mockServiceClose.mockResolvedValue(undefined);
|
|
45
|
-
process.exitCode = 0;
|
|
46
|
-
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
47
|
-
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('dry-run JSON uses shared remediation contract and does not recover tasks', async () => {
|
|
51
|
-
mockDetectExpiredLeases.mockResolvedValue(['task-1']);
|
|
52
|
-
|
|
53
|
-
await handleRuntimeRecoverySweep({ workspace: '/fake/workspace', dryRun: true, json: true });
|
|
54
|
-
|
|
55
|
-
const output = JSON.parse(String(consoleLogSpy.mock.calls[0][0]));
|
|
56
|
-
expect(output).toMatchObject({
|
|
57
|
-
mode: 'dry_run',
|
|
58
|
-
status: 'would_change',
|
|
59
|
-
safeToConfirm: true,
|
|
60
|
-
repairedCount: 0,
|
|
61
|
-
skippedCount: 0,
|
|
62
|
-
});
|
|
63
|
-
expect(output.actions[0]).toMatchObject({ action: 'recover_expired_lease', targetId: 'task-1' });
|
|
64
|
-
expect(mockRecoverTask).not.toHaveBeenCalled();
|
|
65
|
-
expect(mockServiceClose).toHaveBeenCalledTimes(1);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('confirm JSON reports changed after recovering expired leases', async () => {
|
|
69
|
-
mockDetectExpiredLeases.mockResolvedValue(['task-1']);
|
|
70
|
-
mockRecoverTask.mockResolvedValue({ previousStatus: 'leased', newStatus: 'retry_wait' });
|
|
71
|
-
|
|
72
|
-
await handleRuntimeRecoverySweep({ workspace: '/fake/workspace', confirm: true, json: true });
|
|
73
|
-
|
|
74
|
-
const output = JSON.parse(String(consoleLogSpy.mock.calls[0][0]));
|
|
75
|
-
expect(output.mode).toBe('confirm');
|
|
76
|
-
expect(output.status).toBe('changed');
|
|
77
|
-
expect(output.repairedCount).toBe(1);
|
|
78
|
-
expect(mockRecoverTask).toHaveBeenCalledWith('task-1');
|
|
79
|
-
expect(mockServiceClose).toHaveBeenCalledTimes(1);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('rejects --dry-run and --confirm together before writing (no service created)', async () => {
|
|
83
|
-
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((code) => { throw new Error(`process.exit:${code}`); });
|
|
84
|
-
|
|
85
|
-
await expect(
|
|
86
|
-
handleRuntimeRecoverySweep({ workspace: '/fake/workspace', dryRun: true, confirm: true, json: true }),
|
|
87
|
-
).rejects.toThrow('process.exit:1');
|
|
88
|
-
|
|
89
|
-
expect(mockRecoverTask).not.toHaveBeenCalled();
|
|
90
|
-
expect(mockServiceClose).not.toHaveBeenCalled();
|
|
91
|
-
// PRI-432: JSON mode emits structured error to stdout (CLI Operator Gate rule #1).
|
|
92
|
-
const output = JSON.parse(String(consoleLogSpy.mock.calls[0][0]));
|
|
93
|
-
expect(output.ok).toBe(false);
|
|
94
|
-
expect(output.reason).toContain('mutually exclusive');
|
|
95
|
-
expect(output.nextAction).toBeTruthy();
|
|
96
|
-
|
|
97
|
-
exitSpy.mockRestore();
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('rejects --dry-run and --confirm together in text mode via stderr', async () => {
|
|
101
|
-
const exitSpy = vi.spyOn(process, 'exit').mockImplementation((code) => { throw new Error(`process.exit:${code}`); });
|
|
102
|
-
|
|
103
|
-
await expect(
|
|
104
|
-
handleRuntimeRecoverySweep({ workspace: '/fake/workspace', dryRun: true, confirm: true, json: false }),
|
|
105
|
-
).rejects.toThrow('process.exit:1');
|
|
106
|
-
|
|
107
|
-
expect(mockRecoverTask).not.toHaveBeenCalled();
|
|
108
|
-
expect(mockServiceClose).not.toHaveBeenCalled();
|
|
109
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('mutually exclusive'));
|
|
110
|
-
|
|
111
|
-
exitSpy.mockRestore();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('uses createRecoverySweepService (no RuntimeStateManager)', async () => {
|
|
115
|
-
const fs = await import('fs');
|
|
116
|
-
const src = fs.readFileSync(require.resolve('../../src/commands/runtime-recovery.ts'), 'utf-8');
|
|
117
|
-
expect(src).not.toContain('RuntimeStateManager');
|
|
118
|
-
expect(src).toContain('createRecoverySweepService');
|
|
119
|
-
});
|
|
120
|
-
});
|