@principles/pd-cli 1.73.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.
- package/README.md +90 -0
- package/dist/commands/artifact.d.ts +14 -0
- package/dist/commands/artifact.d.ts.map +1 -0
- package/dist/commands/artifact.js +67 -0
- package/dist/commands/artifact.js.map +1 -0
- package/dist/commands/candidate.d.ts +83 -0
- package/dist/commands/candidate.d.ts.map +1 -0
- package/dist/commands/candidate.js +891 -0
- package/dist/commands/candidate.js.map +1 -0
- package/dist/commands/central-sync.d.ts +10 -0
- package/dist/commands/central-sync.d.ts.map +1 -0
- package/dist/commands/central-sync.js +32 -0
- package/dist/commands/central-sync.js.map +1 -0
- package/dist/commands/console.d.ts +9 -0
- package/dist/commands/console.d.ts.map +1 -0
- package/dist/commands/console.js +114 -0
- package/dist/commands/console.js.map +1 -0
- package/dist/commands/context.d.ts +7 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +55 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/demo-story-a.d.ts +12 -0
- package/dist/commands/demo-story-a.d.ts.map +1 -0
- package/dist/commands/demo-story-a.js +175 -0
- package/dist/commands/demo-story-a.js.map +1 -0
- package/dist/commands/diagnose.d.ts +35 -0
- package/dist/commands/diagnose.d.ts.map +1 -0
- package/dist/commands/diagnose.js +390 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/evolution-tasks-list.d.ts +15 -0
- package/dist/commands/evolution-tasks-list.d.ts.map +1 -0
- package/dist/commands/evolution-tasks-list.js +34 -0
- package/dist/commands/evolution-tasks-list.js.map +1 -0
- package/dist/commands/evolution-tasks-show.d.ts +14 -0
- package/dist/commands/evolution-tasks-show.d.ts.map +1 -0
- package/dist/commands/evolution-tasks-show.js +52 -0
- package/dist/commands/evolution-tasks-show.js.map +1 -0
- package/dist/commands/flow.d.ts +7 -0
- package/dist/commands/flow.d.ts.map +1 -0
- package/dist/commands/flow.js +57 -0
- package/dist/commands/flow.js.map +1 -0
- package/dist/commands/health.d.ts +16 -0
- package/dist/commands/health.d.ts.map +1 -0
- package/dist/commands/health.js +150 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/history.d.ts +11 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +50 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/legacy-cleanup.d.ts +27 -0
- package/dist/commands/legacy-cleanup.d.ts.map +1 -0
- package/dist/commands/legacy-cleanup.js +171 -0
- package/dist/commands/legacy-cleanup.js.map +1 -0
- package/dist/commands/legacy-import.d.ts +7 -0
- package/dist/commands/legacy-import.d.ts.map +1 -0
- package/dist/commands/legacy-import.js +86 -0
- package/dist/commands/legacy-import.js.map +1 -0
- package/dist/commands/pain-record.d.ts +10 -0
- package/dist/commands/pain-record.d.ts.map +1 -0
- package/dist/commands/pain-record.js +162 -0
- package/dist/commands/pain-record.js.map +1 -0
- package/dist/commands/proven-channel-baseline.d.ts +12 -0
- package/dist/commands/proven-channel-baseline.d.ts.map +1 -0
- package/dist/commands/proven-channel-baseline.js +97 -0
- package/dist/commands/proven-channel-baseline.js.map +1 -0
- package/dist/commands/remediation-output.d.ts +40 -0
- package/dist/commands/remediation-output.d.ts.map +1 -0
- package/dist/commands/remediation-output.js +23 -0
- package/dist/commands/remediation-output.js.map +1 -0
- package/dist/commands/run.d.ts +10 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +68 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/runtime-activation.d.ts +11 -0
- package/dist/commands/runtime-activation.d.ts.map +1 -0
- package/dist/commands/runtime-activation.js +150 -0
- package/dist/commands/runtime-activation.js.map +1 -0
- package/dist/commands/runtime-canary.d.ts +30 -0
- package/dist/commands/runtime-canary.d.ts.map +1 -0
- package/dist/commands/runtime-canary.js +343 -0
- package/dist/commands/runtime-canary.js.map +1 -0
- package/dist/commands/runtime-diagnostics-export.d.ts +20 -0
- package/dist/commands/runtime-diagnostics-export.d.ts.map +1 -0
- package/dist/commands/runtime-diagnostics-export.js +177 -0
- package/dist/commands/runtime-diagnostics-export.js.map +1 -0
- package/dist/commands/runtime-features.d.ts +26 -0
- package/dist/commands/runtime-features.d.ts.map +1 -0
- package/dist/commands/runtime-features.js +70 -0
- package/dist/commands/runtime-features.js.map +1 -0
- package/dist/commands/runtime-gfi-snapshot.d.ts +7 -0
- package/dist/commands/runtime-gfi-snapshot.d.ts.map +1 -0
- package/dist/commands/runtime-gfi-snapshot.js +101 -0
- package/dist/commands/runtime-gfi-snapshot.js.map +1 -0
- package/dist/commands/runtime-health-snapshot.d.ts +7 -0
- package/dist/commands/runtime-health-snapshot.d.ts.map +1 -0
- package/dist/commands/runtime-health-snapshot.js +93 -0
- package/dist/commands/runtime-health-snapshot.js.map +1 -0
- package/dist/commands/runtime-idle-trigger.d.ts +12 -0
- package/dist/commands/runtime-idle-trigger.d.ts.map +1 -0
- package/dist/commands/runtime-idle-trigger.js +102 -0
- package/dist/commands/runtime-idle-trigger.js.map +1 -0
- package/dist/commands/runtime-internalization-enqueue-successors.d.ts +9 -0
- package/dist/commands/runtime-internalization-enqueue-successors.d.ts.map +1 -0
- package/dist/commands/runtime-internalization-enqueue-successors.js +393 -0
- package/dist/commands/runtime-internalization-enqueue-successors.js.map +1 -0
- package/dist/commands/runtime-internalization-integrity-repair.d.ts +9 -0
- package/dist/commands/runtime-internalization-integrity-repair.d.ts.map +1 -0
- package/dist/commands/runtime-internalization-integrity-repair.js +54 -0
- package/dist/commands/runtime-internalization-integrity-repair.js.map +1 -0
- package/dist/commands/runtime-internalization-integrity.d.ts +7 -0
- package/dist/commands/runtime-internalization-integrity.d.ts.map +1 -0
- package/dist/commands/runtime-internalization-integrity.js +53 -0
- package/dist/commands/runtime-internalization-integrity.js.map +1 -0
- package/dist/commands/runtime-internalization-queue.d.ts +7 -0
- package/dist/commands/runtime-internalization-queue.d.ts.map +1 -0
- package/dist/commands/runtime-internalization-queue.js +85 -0
- package/dist/commands/runtime-internalization-queue.js.map +1 -0
- package/dist/commands/runtime-internalization-run-once.d.ts +12 -0
- package/dist/commands/runtime-internalization-run-once.d.ts.map +1 -0
- package/dist/commands/runtime-internalization-run-once.js +546 -0
- package/dist/commands/runtime-internalization-run-once.js.map +1 -0
- package/dist/commands/runtime-internalization-wake-once.d.ts +8 -0
- package/dist/commands/runtime-internalization-wake-once.d.ts.map +1 -0
- package/dist/commands/runtime-internalization-wake-once.js +72 -0
- package/dist/commands/runtime-internalization-wake-once.js.map +1 -0
- package/dist/commands/runtime-pain-flood-simulation.d.ts +10 -0
- package/dist/commands/runtime-pain-flood-simulation.d.ts.map +1 -0
- package/dist/commands/runtime-pain-flood-simulation.js +104 -0
- package/dist/commands/runtime-pain-flood-simulation.js.map +1 -0
- package/dist/commands/runtime-pruning.d.ts +45 -0
- package/dist/commands/runtime-pruning.d.ts.map +1 -0
- package/dist/commands/runtime-pruning.js +355 -0
- package/dist/commands/runtime-pruning.js.map +1 -0
- package/dist/commands/runtime-recovery.d.ts +9 -0
- package/dist/commands/runtime-recovery.d.ts.map +1 -0
- package/dist/commands/runtime-recovery.js +94 -0
- package/dist/commands/runtime-recovery.js.map +1 -0
- package/dist/commands/runtime-synthetic-baseline.d.ts +7 -0
- package/dist/commands/runtime-synthetic-baseline.d.ts.map +1 -0
- package/dist/commands/runtime-synthetic-baseline.js +59 -0
- package/dist/commands/runtime-synthetic-baseline.js.map +1 -0
- package/dist/commands/runtime-uat.d.ts +52 -0
- package/dist/commands/runtime-uat.d.ts.map +1 -0
- package/dist/commands/runtime-uat.js +274 -0
- package/dist/commands/runtime-uat.js.map +1 -0
- package/dist/commands/runtime.d.ts +20 -0
- package/dist/commands/runtime.d.ts.map +1 -0
- package/dist/commands/runtime.js +256 -0
- package/dist/commands/runtime.js.map +1 -0
- package/dist/commands/samples-list.d.ts +11 -0
- package/dist/commands/samples-list.d.ts.map +1 -0
- package/dist/commands/samples-list.js +37 -0
- package/dist/commands/samples-list.js.map +1 -0
- package/dist/commands/samples-review.d.ts +14 -0
- package/dist/commands/samples-review.d.ts.map +1 -0
- package/dist/commands/samples-review.js +22 -0
- package/dist/commands/samples-review.js.map +1 -0
- package/dist/commands/task.d.ts +14 -0
- package/dist/commands/task.d.ts.map +1 -0
- package/dist/commands/task.js +92 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/commands/trace.d.ts +19 -0
- package/dist/commands/trace.d.ts.map +1 -0
- package/dist/commands/trace.js +154 -0
- package/dist/commands/trace.js.map +1 -0
- package/dist/commands/trajectory.d.ts +11 -0
- package/dist/commands/trajectory.d.ts.map +1 -0
- package/dist/commands/trajectory.js +47 -0
- package/dist/commands/trajectory.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +736 -0
- package/dist/index.js.map +1 -0
- package/dist/legacy/legacy-import.d.ts +15 -0
- package/dist/legacy/legacy-import.d.ts.map +1 -0
- package/dist/legacy/legacy-import.js +141 -0
- package/dist/legacy/legacy-import.js.map +1 -0
- package/dist/legacy/session-history-import.d.ts +26 -0
- package/dist/legacy/session-history-import.d.ts.map +1 -0
- package/dist/legacy/session-history-import.js +151 -0
- package/dist/legacy/session-history-import.js.map +1 -0
- package/dist/principle-tree-ledger-adapter.d.ts +12 -0
- package/dist/principle-tree-ledger-adapter.d.ts.map +1 -0
- package/dist/principle-tree-ledger-adapter.js +12 -0
- package/dist/principle-tree-ledger-adapter.js.map +1 -0
- package/dist/resolve-workspace.d.ts +12 -0
- package/dist/resolve-workspace.d.ts.map +1 -0
- package/dist/resolve-workspace.js +20 -0
- package/dist/resolve-workspace.js.map +1 -0
- package/dist/services/demo-story-a-runner.d.ts +8 -0
- package/dist/services/demo-story-a-runner.d.ts.map +1 -0
- package/dist/services/demo-story-a-runner.js +369 -0
- package/dist/services/demo-story-a-runner.js.map +1 -0
- package/dist/services/feature-flag-loader.d.ts +6 -0
- package/dist/services/feature-flag-loader.d.ts.map +1 -0
- package/dist/services/feature-flag-loader.js +54 -0
- package/dist/services/feature-flag-loader.js.map +1 -0
- package/dist/services/pain-flood-simulation-runner.d.ts +10 -0
- package/dist/services/pain-flood-simulation-runner.d.ts.map +1 -0
- package/dist/services/pain-flood-simulation-runner.js +289 -0
- package/dist/services/pain-flood-simulation-runner.js.map +1 -0
- package/dist/services/proven-channel-baseline-runner.d.ts +12 -0
- package/dist/services/proven-channel-baseline-runner.d.ts.map +1 -0
- package/dist/services/proven-channel-baseline-runner.js +114 -0
- package/dist/services/proven-channel-baseline-runner.js.map +1 -0
- package/dist/services/synthetic-baseline-runner.d.ts +8 -0
- package/dist/services/synthetic-baseline-runner.d.ts.map +1 -0
- package/dist/services/synthetic-baseline-runner.js +251 -0
- package/dist/services/synthetic-baseline-runner.js.map +1 -0
- package/package.json +35 -0
- package/src/commands/artifact.ts +82 -0
- package/src/commands/candidate.ts +1117 -0
- package/src/commands/central-sync.ts +44 -0
- package/src/commands/console.ts +121 -0
- package/src/commands/context.ts +72 -0
- package/src/commands/demo-story-a.ts +195 -0
- package/src/commands/diagnose.ts +452 -0
- package/src/commands/evolution-tasks-list.ts +44 -0
- package/src/commands/evolution-tasks-show.ts +60 -0
- package/src/commands/flow.ts +60 -0
- package/src/commands/health.ts +189 -0
- package/src/commands/history.ts +63 -0
- package/src/commands/legacy-cleanup.ts +206 -0
- package/src/commands/legacy-import.ts +104 -0
- package/src/commands/pain-record.ts +167 -0
- package/src/commands/proven-channel-baseline.ts +113 -0
- package/src/commands/remediation-output.ts +66 -0
- package/src/commands/run.ts +89 -0
- package/src/commands/runtime-activation.ts +176 -0
- package/src/commands/runtime-canary.ts +371 -0
- package/src/commands/runtime-diagnostics-export.ts +229 -0
- package/src/commands/runtime-features.ts +103 -0
- package/src/commands/runtime-gfi-snapshot.ts +135 -0
- package/src/commands/runtime-health-snapshot.ts +106 -0
- package/src/commands/runtime-internalization-enqueue-successors.ts +479 -0
- package/src/commands/runtime-internalization-integrity-repair.ts +69 -0
- package/src/commands/runtime-internalization-integrity.ts +63 -0
- package/src/commands/runtime-internalization-queue.ts +106 -0
- package/src/commands/runtime-internalization-run-once.ts +658 -0
- package/src/commands/runtime-internalization-wake-once.ts +87 -0
- package/src/commands/runtime-pain-flood-simulation.ts +121 -0
- package/src/commands/runtime-pruning.ts +438 -0
- package/src/commands/runtime-recovery.ts +107 -0
- package/src/commands/runtime-synthetic-baseline.ts +70 -0
- package/src/commands/runtime-uat.ts +339 -0
- package/src/commands/runtime.ts +281 -0
- package/src/commands/samples-list.ts +43 -0
- package/src/commands/samples-review.ts +32 -0
- package/src/commands/task.ts +130 -0
- package/src/commands/trace.ts +174 -0
- package/src/commands/trajectory.ts +64 -0
- package/src/index.ts +829 -0
- package/src/legacy/legacy-import.ts +179 -0
- package/src/legacy/session-history-import.ts +231 -0
- package/src/principle-tree-ledger-adapter.ts +13 -0
- package/src/resolve-workspace.ts +20 -0
- package/src/services/demo-story-a-runner.ts +472 -0
- package/src/services/feature-flag-loader.ts +73 -0
- package/src/services/pain-flood-simulation-runner.ts +354 -0
- package/src/services/proven-channel-baseline-runner.ts +150 -0
- package/src/services/synthetic-baseline-runner.ts +291 -0
- package/tests/commands/candidate-audit-repair.test.ts +338 -0
- package/tests/commands/candidate-intake.test.ts +589 -0
- package/tests/commands/candidate-internalization-backfill.test.ts +480 -0
- package/tests/commands/candidate-internalize.test.ts +272 -0
- package/tests/commands/candidate-route.test.ts +328 -0
- package/tests/commands/candidate-show.test.ts +95 -0
- package/tests/commands/cli-command-tree.test.ts +64 -0
- package/tests/commands/context.test.ts +114 -0
- package/tests/commands/demo-story-a.test.ts +255 -0
- package/tests/commands/diagnose.test.ts +792 -0
- package/tests/commands/health.test.ts +330 -0
- package/tests/commands/pain-record.test.ts +316 -0
- package/tests/commands/plugin-config-resolution-cutover.test.ts +220 -0
- package/tests/commands/proven-channel-baseline.test.ts +441 -0
- package/tests/commands/runtime-activation.test.ts +168 -0
- package/tests/commands/runtime-canary.test.ts +369 -0
- package/tests/commands/runtime-diagnostics-export.test.ts +170 -0
- package/tests/commands/runtime-features.test.ts +114 -0
- package/tests/commands/runtime-health-snapshot.test.ts +357 -0
- package/tests/commands/runtime-internalization-enqueue-successors.test.ts +803 -0
- package/tests/commands/runtime-internalization-integrity-repair.test.ts +169 -0
- package/tests/commands/runtime-internalization-integrity.test.ts +102 -0
- package/tests/commands/runtime-internalization-queue.test.ts +252 -0
- package/tests/commands/runtime-internalization-run-once.test.ts +1318 -0
- package/tests/commands/runtime-internalization-wake-once.test.ts +170 -0
- package/tests/commands/runtime-internalization.test.ts +52 -0
- package/tests/commands/runtime-pain-flood-simulation.test.ts +418 -0
- package/tests/commands/runtime-pruning.test.ts +693 -0
- package/tests/commands/runtime-recovery.test.ts +96 -0
- package/tests/commands/runtime-synthetic-baseline.test.ts +249 -0
- package/tests/commands/runtime-uat.test.ts +397 -0
- package/tests/commands/runtime.test.ts +262 -0
- package/tests/commands/trace.test.ts +314 -0
- package/tests/e2e/candidate-intake-e2e.test.ts +316 -0
- package/tests/services/feature-flag-loader.test.ts +207 -0
- package/tests/services/proven-channel-baseline-runner.test.ts +30 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pd diagnose run/status commands — Diagnostician execution and status inspection.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* pd diagnose status --task-id <taskId> --workspace <path>
|
|
6
|
+
* pd diagnose run --task-id <taskId> --workspace <path>
|
|
7
|
+
*/
|
|
8
|
+
import {
|
|
9
|
+
RuntimeStateManager,
|
|
10
|
+
SqliteHistoryQuery,
|
|
11
|
+
SqliteContextAssembler,
|
|
12
|
+
SqliteDiagnosticianCommitter,
|
|
13
|
+
SqliteTrajectoryLocator,
|
|
14
|
+
SqliteSourceTraceLocator,
|
|
15
|
+
StoreEventEmitter,
|
|
16
|
+
storeEmitter,
|
|
17
|
+
DiagnosticianRunner,
|
|
18
|
+
DefaultDiagnosticianValidator,
|
|
19
|
+
TestDoubleRuntimeAdapter,
|
|
20
|
+
OpenClawCliRuntimeAdapter,
|
|
21
|
+
PiAiRuntimeAdapter,
|
|
22
|
+
PDRuntimeError,
|
|
23
|
+
resolveRuntimeConfig,
|
|
24
|
+
isRuntimeConfigError,
|
|
25
|
+
CandidateIntakeService,
|
|
26
|
+
run as diagnoseRun,
|
|
27
|
+
status as diagnoseStatus,
|
|
28
|
+
} from '@principles/core/runtime-v2';
|
|
29
|
+
import type { PDRuntimeAdapter, RuntimeConfig } from '@principles/core/runtime-v2';
|
|
30
|
+
import { PrincipleTreeLedgerAdapter } from '../principle-tree-ledger-adapter.js';
|
|
31
|
+
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
32
|
+
import * as path from 'path';
|
|
33
|
+
|
|
34
|
+
interface DiagnoseStatusOptions {
|
|
35
|
+
taskId: string;
|
|
36
|
+
workspace?: string;
|
|
37
|
+
json?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface DiagnoseRunOptions {
|
|
41
|
+
taskId: string;
|
|
42
|
+
workspace?: string;
|
|
43
|
+
json?: boolean;
|
|
44
|
+
runtime?: string;
|
|
45
|
+
openclawLocal?: boolean;
|
|
46
|
+
openclawGateway?: boolean;
|
|
47
|
+
agent?: string;
|
|
48
|
+
provider?: string;
|
|
49
|
+
model?: string;
|
|
50
|
+
apiKeyEnv?: string;
|
|
51
|
+
baseUrl?: string;
|
|
52
|
+
maxRetries?: number;
|
|
53
|
+
timeoutMs?: number;
|
|
54
|
+
intake?: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* pd diagnose status --task-id <taskId> [--workspace <path>] [--json]
|
|
59
|
+
*
|
|
60
|
+
* Inspects the current status of a diagnostician task.
|
|
61
|
+
*/
|
|
62
|
+
export async function handleDiagnoseStatus(opts: DiagnoseStatusOptions): Promise<void> {
|
|
63
|
+
const workspaceDir = resolveWorkspaceDir(opts.workspace);
|
|
64
|
+
const stateManager = new RuntimeStateManager({ workspaceDir });
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
await stateManager.initialize();
|
|
68
|
+
const result = await diagnoseStatus({
|
|
69
|
+
taskId: opts.taskId,
|
|
70
|
+
stateManager,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (!result) {
|
|
74
|
+
console.error(`Task not found: ${opts.taskId}`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (opts.json) {
|
|
80
|
+
console.log(JSON.stringify(result, null, 2));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
console.log(`\nDiagnostician Task: ${result.taskId}\n`);
|
|
85
|
+
console.log(` Status: ${result.status}`);
|
|
86
|
+
console.log(` Attempts: ${result.attemptCount} / ${result.maxAttempts}`);
|
|
87
|
+
if (result.commitId) {
|
|
88
|
+
console.log(` Result Ref: commit://${result.commitId}`);
|
|
89
|
+
console.log(` Commit ID: ${result.commitId}`);
|
|
90
|
+
console.log(` Artifact ID: ${result.artifactId ?? 'N/A'}`);
|
|
91
|
+
console.log(` Candidates: ${result.candidateCount ?? 0}`);
|
|
92
|
+
}
|
|
93
|
+
if (result.lastError) {
|
|
94
|
+
console.log(` Last Error: ${result.lastError}`);
|
|
95
|
+
}
|
|
96
|
+
console.log('');
|
|
97
|
+
} finally {
|
|
98
|
+
await stateManager.close();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* pd diagnose run --task-id <taskId> [--workspace <path>] [--json]
|
|
104
|
+
*
|
|
105
|
+
* Executes the diagnostician runner for a task.
|
|
106
|
+
*/
|
|
107
|
+
export async function handleDiagnoseRun(opts: DiagnoseRunOptions): Promise<void> {
|
|
108
|
+
const workspaceDir = resolveWorkspaceDir(opts.workspace);
|
|
109
|
+
|
|
110
|
+
// Validate mutually exclusive flags (HG-03)
|
|
111
|
+
if (opts.openclawLocal && opts.openclawGateway) {
|
|
112
|
+
console.error('error: --openclaw-local and --openclaw-gateway are mutually exclusive');
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const runtimeKind = opts.runtime ?? 'test-double';
|
|
117
|
+
|
|
118
|
+
const stateManager = new RuntimeStateManager({ workspaceDir });
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
await stateManager.initialize();
|
|
122
|
+
|
|
123
|
+
// Build context assembler from internal stores
|
|
124
|
+
const sqliteConn = stateManager.connection;
|
|
125
|
+
const {taskStore} = stateManager;
|
|
126
|
+
const {runStore} = stateManager;
|
|
127
|
+
const historyQuery = new SqliteHistoryQuery(sqliteConn);
|
|
128
|
+
const trajectoryLocator = new SqliteTrajectoryLocator(sqliteConn);
|
|
129
|
+
const sourceTraceLocator = new SqliteSourceTraceLocator(taskStore, trajectoryLocator);
|
|
130
|
+
const contextAssembler = new SqliteContextAssembler(taskStore, historyQuery, runStore, { sourceTraceLocator });
|
|
131
|
+
|
|
132
|
+
// Select runtime adapter based on --runtime flag (CLI-02)
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
134
|
+
let runtimeAdapter: PDRuntimeAdapter;
|
|
135
|
+
if (runtimeKind === 'openclaw-cli') {
|
|
136
|
+
const stateDir = `${workspaceDir}/.state`;
|
|
137
|
+
const configResult = resolveRuntimeConfig(stateDir, { openclawLocal: opts.openclawLocal, openclawGateway: opts.openclawGateway, requestedRuntimeKind: 'openclaw-cli' });
|
|
138
|
+
if (isRuntimeConfigError(configResult)) {
|
|
139
|
+
if (opts.json) {
|
|
140
|
+
console.log(JSON.stringify({ ok: false, reason: configResult.reason, message: configResult.message, nextAction: configResult.nextAction }));
|
|
141
|
+
} else {
|
|
142
|
+
console.error(`error: ${configResult.message}`);
|
|
143
|
+
console.error(`nextAction: ${configResult.nextAction}`);
|
|
144
|
+
}
|
|
145
|
+
process.exit(1);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const { openclawMode } = configResult;
|
|
149
|
+
if (!openclawMode) {
|
|
150
|
+
if (opts.json) {
|
|
151
|
+
console.log(JSON.stringify({ ok: false, reason: 'missing_openclaw_mode', message: 'runtimeKind is openclaw-cli but no mode resolved', nextAction: 'Provide --openclaw-local or --openclaw-gateway, or set openclawMode in workflows.yaml' }));
|
|
152
|
+
} else {
|
|
153
|
+
console.error('error: runtimeKind is openclaw-cli but no mode resolved');
|
|
154
|
+
console.error('nextAction: Provide --openclaw-local or --openclaw-gateway, or set openclawMode in workflows.yaml');
|
|
155
|
+
}
|
|
156
|
+
process.exit(1);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
runtimeAdapter = new OpenClawCliRuntimeAdapter({
|
|
161
|
+
runtimeMode: openclawMode,
|
|
162
|
+
workspaceDir,
|
|
163
|
+
agentId: opts.agent ?? 'main',
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// TELE-01: runtime_adapter_selected — user explicitly chose openclaw-cli runtime
|
|
167
|
+
storeEmitter.emitTelemetry({
|
|
168
|
+
eventType: 'runtime_adapter_selected',
|
|
169
|
+
traceId: opts.taskId,
|
|
170
|
+
timestamp: new Date().toISOString(),
|
|
171
|
+
sessionId: 'pd-cli-diagnose',
|
|
172
|
+
agentId: 'openclaw-cli-adapter',
|
|
173
|
+
payload: {
|
|
174
|
+
runtimeKind: 'openclaw-cli',
|
|
175
|
+
runtimeMode: openclawMode,
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
} else if (runtimeKind === 'test-double') {
|
|
179
|
+
runtimeAdapter = new TestDoubleRuntimeAdapter({
|
|
180
|
+
onPollRun: (_runId: string) => ({
|
|
181
|
+
runId: _runId,
|
|
182
|
+
status: 'succeeded',
|
|
183
|
+
startedAt: new Date().toISOString(),
|
|
184
|
+
endedAt: new Date().toISOString(),
|
|
185
|
+
}),
|
|
186
|
+
onFetchOutput: (_runId: string) => ({
|
|
187
|
+
runId: _runId,
|
|
188
|
+
payload: {
|
|
189
|
+
valid: true,
|
|
190
|
+
diagnosisId: `diag-cli-${Date.now()}`,
|
|
191
|
+
taskId: opts.taskId,
|
|
192
|
+
summary: 'CLI test diagnosis — validate tool arguments before execution',
|
|
193
|
+
rootCause: 'Test root cause — missing argument validation',
|
|
194
|
+
violatedPrinciples: [],
|
|
195
|
+
evidence: [],
|
|
196
|
+
recommendations: [
|
|
197
|
+
{ kind: 'principle', description: 'Always validate tool arguments before execution to prevent silent failures' },
|
|
198
|
+
{ kind: 'rule', description: 'Use schema validation for external inputs' },
|
|
199
|
+
],
|
|
200
|
+
confidence: 0.9,
|
|
201
|
+
},
|
|
202
|
+
}),
|
|
203
|
+
});
|
|
204
|
+
} else if (runtimeKind === 'pi-ai') {
|
|
205
|
+
const stateDir = `${workspaceDir}/.state`;
|
|
206
|
+
let policyConfig: RuntimeConfig | null = null;
|
|
207
|
+
try {
|
|
208
|
+
const configResult = resolveRuntimeConfig(stateDir);
|
|
209
|
+
if (!isRuntimeConfigError(configResult)) {
|
|
210
|
+
policyConfig = configResult;
|
|
211
|
+
} else {
|
|
212
|
+
console.warn(`[pd diagnose] workflows.yaml policy load failed: ${configResult.message}. Using CLI flags if provided.`);
|
|
213
|
+
}
|
|
214
|
+
} catch (err: unknown) {
|
|
215
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
216
|
+
console.warn(`[pd diagnose] workflows.yaml policy load failed: ${detail}. Using CLI flags if provided.`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const provider = opts.provider ?? policyConfig?.provider;
|
|
220
|
+
const model = opts.model ?? policyConfig?.model;
|
|
221
|
+
const apiKeyEnv = opts.apiKeyEnv ?? policyConfig?.apiKeyEnv;
|
|
222
|
+
const baseUrl = opts.baseUrl ?? policyConfig?.baseUrl;
|
|
223
|
+
const maxRetries = opts.maxRetries ?? policyConfig?.maxRetries;
|
|
224
|
+
const effectiveTimeoutMs = opts.timeoutMs ?? policyConfig?.timeoutMs;
|
|
225
|
+
|
|
226
|
+
// D-11: validate config — missing fields + fix suggestion
|
|
227
|
+
const missing: string[] = [];
|
|
228
|
+
if (!provider) missing.push('provider');
|
|
229
|
+
if (!model) missing.push('model');
|
|
230
|
+
if (!apiKeyEnv) missing.push('apiKeyEnv');
|
|
231
|
+
if (missing.length > 0) {
|
|
232
|
+
console.error(
|
|
233
|
+
`error: missing required pi-ai config: ${missing.join(', ')}.\n` +
|
|
234
|
+
`Pass via --flag or add to workflows.yaml pd-runtime-v2-diagnosis funnel policy.\n` +
|
|
235
|
+
`Example:\n` +
|
|
236
|
+
` pd diagnose run --runtime pi-ai --provider openrouter --model anthropic/claude-sonnet-4 --apiKeyEnv OPENROUTER_API_KEY\n` +
|
|
237
|
+
` Or add to workflows.yaml:\n` +
|
|
238
|
+
` policy:\n` +
|
|
239
|
+
` runtimeKind: pi-ai\n` +
|
|
240
|
+
` provider: openrouter\n` +
|
|
241
|
+
` model: anthropic/claude-sonnet-4\n` +
|
|
242
|
+
` apiKeyEnv: OPENROUTER_API_KEY`,
|
|
243
|
+
);
|
|
244
|
+
process.exit(1);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// After validation: all fields are confirmed non-null
|
|
248
|
+
const validProvider: string = provider as string;
|
|
249
|
+
const validModel: string = model as string;
|
|
250
|
+
const validApiKeyEnv: string = apiKeyEnv as string;
|
|
251
|
+
|
|
252
|
+
// D-09: validate env var exists
|
|
253
|
+
if (!process.env[validApiKeyEnv]) {
|
|
254
|
+
console.error(`error: environment variable '${validApiKeyEnv}' is not set`);
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
runtimeAdapter = new PiAiRuntimeAdapter({
|
|
259
|
+
provider: validProvider,
|
|
260
|
+
model: validModel,
|
|
261
|
+
apiKeyEnv: validApiKeyEnv,
|
|
262
|
+
baseUrl,
|
|
263
|
+
maxRetries,
|
|
264
|
+
timeoutMs: effectiveTimeoutMs,
|
|
265
|
+
workspace: workspaceDir,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// TELE: runtime_adapter_selected telemetry
|
|
269
|
+
storeEmitter.emitTelemetry({
|
|
270
|
+
eventType: 'runtime_adapter_selected',
|
|
271
|
+
traceId: opts.taskId,
|
|
272
|
+
timestamp: new Date().toISOString(),
|
|
273
|
+
sessionId: 'pd-cli-diagnose',
|
|
274
|
+
agentId: 'pi-ai-adapter',
|
|
275
|
+
payload: { runtimeKind: 'pi-ai', provider: validProvider, model: validModel, baseUrlPresent: !!baseUrl },
|
|
276
|
+
});
|
|
277
|
+
} else {
|
|
278
|
+
console.error(`error: unknown runtime kind '${runtimeKind}' (supported: openclaw-cli, test-double, pi-ai)`);
|
|
279
|
+
process.exit(1);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const eventEmitter = new StoreEventEmitter();
|
|
283
|
+
const committer = new SqliteDiagnosticianCommitter(sqliteConn);
|
|
284
|
+
const runner = new DiagnosticianRunner(
|
|
285
|
+
{
|
|
286
|
+
stateManager,
|
|
287
|
+
contextAssembler,
|
|
288
|
+
runtimeAdapter,
|
|
289
|
+
eventEmitter,
|
|
290
|
+
validator: new DefaultDiagnosticianValidator(),
|
|
291
|
+
committer,
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
owner: 'pd-cli-diagnose',
|
|
295
|
+
runtimeKind,
|
|
296
|
+
pollIntervalMs: 100,
|
|
297
|
+
timeoutMs: 300_000, // 5 min — same as probe timeout for real LLM calls
|
|
298
|
+
agentId: opts.agent,
|
|
299
|
+
},
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
if (!opts.json) {
|
|
303
|
+
console.log(`\nRunning diagnostician for task: ${opts.taskId}`);
|
|
304
|
+
console.log(`Workspace: ${workspaceDir}\n`);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const result = await diagnoseRun({
|
|
308
|
+
taskId: opts.taskId,
|
|
309
|
+
stateManager,
|
|
310
|
+
runner,
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
if (result.status !== 'succeeded') {
|
|
314
|
+
if (opts.json) {
|
|
315
|
+
console.log(JSON.stringify(result, null, 2));
|
|
316
|
+
} else {
|
|
317
|
+
console.log(`\nResult:`);
|
|
318
|
+
console.log(` Status: ${result.status}`);
|
|
319
|
+
console.log(` Task ID: ${result.taskId}`);
|
|
320
|
+
if (result.errorCategory) {
|
|
321
|
+
console.log(` Error Category: ${result.errorCategory}`);
|
|
322
|
+
}
|
|
323
|
+
if (result.failureReason) {
|
|
324
|
+
console.log(` Failure Reason: ${result.failureReason}`);
|
|
325
|
+
}
|
|
326
|
+
console.log(` Attempt Count: ${result.attemptCount}`);
|
|
327
|
+
console.log('');
|
|
328
|
+
}
|
|
329
|
+
process.exit(1);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const candidates = await stateManager.getCandidatesByTaskId(opts.taskId);
|
|
334
|
+
const intakeResults: { candidateId: string; ledgerEntryId?: string; status: string; error?: string; nextAction?: string }[] = [];
|
|
335
|
+
let intakeFailed = false;
|
|
336
|
+
|
|
337
|
+
if (opts.intake === false) {
|
|
338
|
+
for (const candidate of candidates) {
|
|
339
|
+
intakeResults.push({
|
|
340
|
+
candidateId: candidate.candidateId,
|
|
341
|
+
status: 'skipped',
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
const ledgerAdapter = new PrincipleTreeLedgerAdapter({ stateDir: path.join(workspaceDir, '.state') });
|
|
346
|
+
const intakeService = new CandidateIntakeService({ stateManager, ledgerAdapter });
|
|
347
|
+
|
|
348
|
+
for (const candidate of candidates) {
|
|
349
|
+
try {
|
|
350
|
+
const entry = await intakeService.intake(candidate.candidateId);
|
|
351
|
+
if (candidate.status !== 'consumed') {
|
|
352
|
+
await stateManager.updateCandidateStatus(candidate.candidateId, { status: 'consumed' });
|
|
353
|
+
}
|
|
354
|
+
intakeResults.push({
|
|
355
|
+
candidateId: candidate.candidateId,
|
|
356
|
+
ledgerEntryId: entry.id,
|
|
357
|
+
status: 'consumed',
|
|
358
|
+
});
|
|
359
|
+
} catch (intakeErr: unknown) {
|
|
360
|
+
intakeFailed = true;
|
|
361
|
+
const intakeErrorMessage = intakeErr instanceof Error ? intakeErr.message : String(intakeErr);
|
|
362
|
+
intakeResults.push({
|
|
363
|
+
candidateId: candidate.candidateId,
|
|
364
|
+
status: 'intake_failed',
|
|
365
|
+
error: intakeErrorMessage,
|
|
366
|
+
nextAction: `pd candidate intake --candidate-id ${candidate.candidateId} --workspace "${workspaceDir}"`,
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (opts.json) {
|
|
373
|
+
const jsonOutput = {
|
|
374
|
+
...result,
|
|
375
|
+
intake: {
|
|
376
|
+
enabled: opts.intake !== false,
|
|
377
|
+
candidates: intakeResults,
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
381
|
+
if (intakeFailed) {
|
|
382
|
+
process.exit(1);
|
|
383
|
+
}
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
console.log(`\nResult:`);
|
|
388
|
+
console.log(` Status: ${result.status}`);
|
|
389
|
+
console.log(` Task ID: ${result.taskId}`);
|
|
390
|
+
if (result.contextHash) {
|
|
391
|
+
console.log(` Context Hash: ${result.contextHash.substring(0, 16)}...`);
|
|
392
|
+
}
|
|
393
|
+
if (result.output) {
|
|
394
|
+
console.log(` Diagnosis ID: ${result.output.diagnosisId}`);
|
|
395
|
+
console.log(` Summary: ${result.output.summary}`);
|
|
396
|
+
if (result.output.recommendations) {
|
|
397
|
+
const principleCount = result.output.recommendations.filter((r: { kind: string }) => r.kind === 'principle').length;
|
|
398
|
+
if (principleCount > 0) {
|
|
399
|
+
console.log(` Principles: ${principleCount} candidate(s) generated`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
console.log(` Attempt Count: ${result.attemptCount}`);
|
|
404
|
+
|
|
405
|
+
if (intakeResults.length > 0) {
|
|
406
|
+
console.log(`\n Candidate Intake:`);
|
|
407
|
+
for (const ir of intakeResults) {
|
|
408
|
+
if (ir.status === 'consumed') {
|
|
409
|
+
console.log(` ${ir.candidateId}: consumed (ledger: ${ir.ledgerEntryId})`);
|
|
410
|
+
} else if (ir.status === 'skipped') {
|
|
411
|
+
console.log(` ${ir.candidateId}: skipped (--no-intake)`);
|
|
412
|
+
} else if (ir.status === 'intake_failed') {
|
|
413
|
+
console.log(` ${ir.candidateId}: INTAKE FAILED — ${ir.error}`);
|
|
414
|
+
console.log(` Next action: pd candidate intake --candidate-id ${ir.candidateId} --workspace "${workspaceDir}"`);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (opts.intake === false && candidates.length > 0) {
|
|
420
|
+
console.log(`\n Note: --no-intake was set. Candidates remain at 'pending'.`);
|
|
421
|
+
console.log(` To intake manually:`);
|
|
422
|
+
for (const c of candidates) {
|
|
423
|
+
console.log(` pd candidate intake --candidate-id ${c.candidateId} --workspace "${workspaceDir}"`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
console.log('');
|
|
428
|
+
|
|
429
|
+
if (intakeFailed) {
|
|
430
|
+
process.exit(1);
|
|
431
|
+
}
|
|
432
|
+
} catch (error: unknown) {
|
|
433
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
434
|
+
let errorCategory = 'execution_failed';
|
|
435
|
+
if (error instanceof PDRuntimeError) {
|
|
436
|
+
errorCategory = error.category;
|
|
437
|
+
}
|
|
438
|
+
if (opts.json) {
|
|
439
|
+
console.log(JSON.stringify({
|
|
440
|
+
status: 'failed',
|
|
441
|
+
errorCategory,
|
|
442
|
+
message,
|
|
443
|
+
runtimeKind,
|
|
444
|
+
}, null, 2));
|
|
445
|
+
} else {
|
|
446
|
+
console.error(`error: ${message} (${errorCategory})`);
|
|
447
|
+
}
|
|
448
|
+
process.exit(1);
|
|
449
|
+
} finally {
|
|
450
|
+
await stateManager.close();
|
|
451
|
+
}
|
|
452
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pd evolution tasks list command implementation.
|
|
3
|
+
*
|
|
4
|
+
* Usage: pd evolution tasks list [--status pending|in_progress|completed|all]
|
|
5
|
+
* [--limit <number>] [--date-from <date>] [--date-to <date>]
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { listEvolutionTasks } from '@principles/core/evolution-store';
|
|
9
|
+
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
10
|
+
|
|
11
|
+
interface EvolutionTasksListOptions {
|
|
12
|
+
status?: string;
|
|
13
|
+
limit?: number;
|
|
14
|
+
dateFrom?: string;
|
|
15
|
+
dateTo?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function handleEvolutionTasksList(opts: EvolutionTasksListOptions): Promise<void> {
|
|
19
|
+
const workspaceDir = resolveWorkspaceDir();
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const tasks = listEvolutionTasks(workspaceDir, {
|
|
23
|
+
status: opts.status === 'all' ? undefined : opts.status,
|
|
24
|
+
limit: opts.limit,
|
|
25
|
+
dateFrom: opts.dateFrom,
|
|
26
|
+
dateTo: opts.dateTo,
|
|
27
|
+
});
|
|
28
|
+
if (tasks.length === 0) {
|
|
29
|
+
console.log('No evolution tasks found.');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
for (const task of tasks) {
|
|
33
|
+
const enqueuedAt = task.enqueuedAt ?? 'null';
|
|
34
|
+
console.log(
|
|
35
|
+
`[${task.status}] ${task.taskId} (${task.taskKind}) score=${task.score} source=${task.source} enqueued=${enqueuedAt}`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
console.log(`${tasks.length} task(s)`);
|
|
39
|
+
return;
|
|
40
|
+
} catch {
|
|
41
|
+
console.log('No evolution tasks found.');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pd evolution tasks show command implementation.
|
|
3
|
+
*
|
|
4
|
+
* Usage: pd evolution tasks show <id>
|
|
5
|
+
*
|
|
6
|
+
* Displays full details for a single evolution task.
|
|
7
|
+
* Accepts both numeric id and string taskId.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { getEvolutionTask } from '@principles/core/evolution-store';
|
|
11
|
+
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
12
|
+
|
|
13
|
+
interface EvolutionTasksShowOptions {
|
|
14
|
+
id: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function handleEvolutionTasksShow(opts: EvolutionTasksShowOptions): Promise<void> {
|
|
18
|
+
const workspaceDir = resolveWorkspaceDir();
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
21
|
+
let foundTask;
|
|
22
|
+
try {
|
|
23
|
+
const numericId = isNaN(Number(opts.id)) ? undefined : Number(opts.id);
|
|
24
|
+
foundTask = getEvolutionTask(workspaceDir, numericId ?? opts.id);
|
|
25
|
+
} catch {
|
|
26
|
+
console.log('No evolution tasks found.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!foundTask) {
|
|
31
|
+
console.error(`Task not found: ${opts.id}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const fields = [
|
|
36
|
+
['id', String(foundTask.id)],
|
|
37
|
+
['taskId', foundTask.taskId],
|
|
38
|
+
['traceId', foundTask.traceId],
|
|
39
|
+
['source', foundTask.source],
|
|
40
|
+
['reason', foundTask.reason ?? 'null'],
|
|
41
|
+
['score', String(foundTask.score)],
|
|
42
|
+
['status', foundTask.status],
|
|
43
|
+
['enqueuedAt', foundTask.enqueuedAt ?? 'null'],
|
|
44
|
+
['startedAt', foundTask.startedAt ?? 'null'],
|
|
45
|
+
['completedAt', foundTask.completedAt ?? 'null'],
|
|
46
|
+
['resolution', foundTask.resolution ?? 'null'],
|
|
47
|
+
['taskKind', foundTask.taskKind ?? 'null'],
|
|
48
|
+
['priority', foundTask.priority ?? 'null'],
|
|
49
|
+
['retryCount', foundTask.retryCount != null ? String(foundTask.retryCount) : 'null'],
|
|
50
|
+
['maxRetries', foundTask.maxRetries != null ? String(foundTask.maxRetries) : 'null'],
|
|
51
|
+
['lastError', foundTask.lastError ?? 'null'],
|
|
52
|
+
['resultRef', foundTask.resultRef ?? 'null'],
|
|
53
|
+
['createdAt', foundTask.createdAt],
|
|
54
|
+
['updatedAt', foundTask.updatedAt],
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
for (const [key, value] of fields) {
|
|
58
|
+
console.log(`${key}: ${value}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pd runtime flow show command — Display workflow funnel definitions from workflows.yaml.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* pd runtime flow show [--workspace <path>] [--json]
|
|
6
|
+
*/
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { WorkflowFunnelLoader } from '@principles/core';
|
|
9
|
+
|
|
10
|
+
interface FlowShowOptions {
|
|
11
|
+
workspace?: string;
|
|
12
|
+
json?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function handleFlowShow(opts: FlowShowOptions): Promise<void> {
|
|
16
|
+
const workspaceDir = opts.workspace ?? process.cwd();
|
|
17
|
+
const stateDir = path.join(workspaceDir, '.state');
|
|
18
|
+
|
|
19
|
+
const loader = new WorkflowFunnelLoader(stateDir);
|
|
20
|
+
|
|
21
|
+
if (opts.json) {
|
|
22
|
+
const all = loader.getAllFunnelsWithPolicy();
|
|
23
|
+
console.log(JSON.stringify({ status: 'ok', funnels: [...all.values()] }, null, 2));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const all = loader.getAllFunnelsWithPolicy();
|
|
28
|
+
const funnels = [...all.values()];
|
|
29
|
+
|
|
30
|
+
if (funnels.length === 0) {
|
|
31
|
+
console.log('Workflows: (no funnels defined)\n');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.log(`Workflows (${funnels.length} funnel${funnels.length !== 1 ? 's' : ''}):\n`);
|
|
36
|
+
|
|
37
|
+
for (const funnel of funnels) {
|
|
38
|
+
console.log(` ${funnel.workflowId}`);
|
|
39
|
+
if (funnel.policy) {
|
|
40
|
+
const p = funnel.policy;
|
|
41
|
+
if (p.timeoutMs) console.log(` timeoutMs: ${p.timeoutMs}`);
|
|
42
|
+
if (p.stageOrder) console.log(` stageOrder: ${p.stageOrder}`);
|
|
43
|
+
if (p.legacyDisabled !== undefined) console.log(` legacyDisabled: ${p.legacyDisabled}`);
|
|
44
|
+
if (p.observability?.enabled !== undefined) console.log(` observability: ${p.observability.enabled}`);
|
|
45
|
+
if (p.observability?.logLevel) console.log(` logLevel: ${p.observability.logLevel}`);
|
|
46
|
+
if (p.observability?.emitEvents?.length) {
|
|
47
|
+
console.log(` emitEvents: ${p.observability.emitEvents.join(', ')}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
console.log(` stages (${funnel.stages.length}):`);
|
|
51
|
+
for (const stage of funnel.stages) {
|
|
52
|
+
const parts = [` - ${stage.name}`];
|
|
53
|
+
if (stage.timeoutMs) parts.push(` timeoutMs=${stage.timeoutMs}`);
|
|
54
|
+
if (stage.successCriteria) parts.push(` successCriteria="${stage.successCriteria}"`);
|
|
55
|
+
if (stage.legacyDisabled) parts.push(` legacyDisabled`);
|
|
56
|
+
console.log(parts.join(''));
|
|
57
|
+
}
|
|
58
|
+
console.log('');
|
|
59
|
+
}
|
|
60
|
+
}
|