@principles/pd-cli 1.133.0 → 1.134.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/dist/commands/__tests__/intent-flag-wiring.test.js +74 -3
- package/dist/commands/__tests__/intent-flag-wiring.test.js.map +1 -1
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts +2 -0
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.d.ts.map +1 -0
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js +60 -0
- package/dist/commands/__tests__/pain-retry-maxTokens-flag.test.js.map +1 -0
- package/dist/commands/__tests__/rulecode-flag-wiring.test.js +11 -4
- package/dist/commands/__tests__/rulecode-flag-wiring.test.js.map +1 -1
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js +9 -0
- package/dist/commands/__tests__/run-rulehost-flag-wiring.test.js.map +1 -1
- package/dist/commands/admission-gate.d.ts +24 -0
- package/dist/commands/admission-gate.d.ts.map +1 -0
- package/dist/commands/admission-gate.js +29 -0
- package/dist/commands/admission-gate.js.map +1 -0
- package/dist/commands/candidate.d.ts.map +1 -1
- package/dist/commands/candidate.js +72 -6
- package/dist/commands/candidate.js.map +1 -1
- package/dist/commands/console.d.ts.map +1 -1
- package/dist/commands/console.js +40 -0
- package/dist/commands/console.js.map +1 -1
- package/dist/commands/demo-story-a.d.ts.map +1 -1
- package/dist/commands/demo-story-a.js +4 -2
- package/dist/commands/demo-story-a.js.map +1 -1
- package/dist/commands/diagnose.d.ts.map +1 -1
- package/dist/commands/diagnose.js +155 -8
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/errors-list.d.ts +25 -0
- package/dist/commands/errors-list.d.ts.map +1 -0
- package/dist/commands/errors-list.js +368 -0
- package/dist/commands/errors-list.js.map +1 -0
- package/dist/commands/health-codex.d.ts +7 -0
- package/dist/commands/health-codex.d.ts.map +1 -0
- package/dist/commands/health-codex.js +209 -0
- package/dist/commands/health-codex.js.map +1 -0
- package/dist/commands/health.d.ts +24 -0
- package/dist/commands/health.d.ts.map +1 -1
- package/dist/commands/health.js +48 -0
- package/dist/commands/health.js.map +1 -1
- package/dist/commands/intent.d.ts +21 -4
- package/dist/commands/intent.d.ts.map +1 -1
- package/dist/commands/intent.js +88 -27
- package/dist/commands/intent.js.map +1 -1
- package/dist/commands/pain-evidence.d.ts +6 -0
- package/dist/commands/pain-evidence.d.ts.map +1 -1
- package/dist/commands/pain-evidence.js +6 -0
- package/dist/commands/pain-evidence.js.map +1 -1
- package/dist/commands/pain-record.d.ts.map +1 -1
- package/dist/commands/pain-record.js +21 -0
- package/dist/commands/pain-record.js.map +1 -1
- package/dist/commands/pain-retry.d.ts +4 -0
- package/dist/commands/pain-retry.d.ts.map +1 -1
- package/dist/commands/pain-retry.js +327 -32
- package/dist/commands/pain-retry.js.map +1 -1
- package/dist/commands/proven-channel-baseline.d.ts.map +1 -1
- package/dist/commands/proven-channel-baseline.js +4 -2
- package/dist/commands/proven-channel-baseline.js.map +1 -1
- package/dist/commands/runtime-activation.d.ts +30 -0
- package/dist/commands/runtime-activation.d.ts.map +1 -1
- package/dist/commands/runtime-activation.js +567 -11
- package/dist/commands/runtime-activation.js.map +1 -1
- package/dist/commands/runtime-canary.d.ts.map +1 -1
- package/dist/commands/runtime-canary.js +32 -7
- package/dist/commands/runtime-canary.js.map +1 -1
- package/dist/commands/runtime-health-snapshot.d.ts.map +1 -1
- package/dist/commands/runtime-health-snapshot.js +4 -2
- package/dist/commands/runtime-health-snapshot.js.map +1 -1
- package/dist/commands/runtime-init.d.ts +43 -0
- package/dist/commands/runtime-init.d.ts.map +1 -0
- package/dist/commands/runtime-init.js +264 -0
- package/dist/commands/runtime-init.js.map +1 -0
- package/dist/commands/runtime-internalization-context-trace.d.ts +25 -0
- package/dist/commands/runtime-internalization-context-trace.d.ts.map +1 -0
- package/dist/commands/runtime-internalization-context-trace.js +374 -0
- package/dist/commands/runtime-internalization-context-trace.js.map +1 -0
- package/dist/commands/runtime-internalization-enqueue-successors.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-enqueue-successors.js +3 -1
- package/dist/commands/runtime-internalization-enqueue-successors.js.map +1 -1
- package/dist/commands/runtime-internalization-integrity.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-integrity.js +4 -2
- package/dist/commands/runtime-internalization-integrity.js.map +1 -1
- package/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-run-once.js +20 -5
- package/dist/commands/runtime-internalization-run-once.js.map +1 -1
- package/dist/commands/runtime-internalization-run-rulehost.d.ts +1 -0
- package/dist/commands/runtime-internalization-run-rulehost.d.ts.map +1 -1
- package/dist/commands/runtime-internalization-run-rulehost.js +149 -6
- package/dist/commands/runtime-internalization-run-rulehost.js.map +1 -1
- package/dist/commands/runtime-uat.d.ts.map +1 -1
- package/dist/commands/runtime-uat.guard.test.js +13 -15
- package/dist/commands/runtime-uat.guard.test.js.map +1 -1
- package/dist/commands/runtime-uat.js +4 -3
- package/dist/commands/runtime-uat.js.map +1 -1
- package/dist/config-reader.js +1 -1
- package/dist/config-reader.js.map +1 -1
- package/dist/index.js +54 -78
- package/dist/index.js.map +1 -1
- package/dist/services/__tests__/evaluator-runner-deps.test.d.ts +2 -0
- package/dist/services/__tests__/evaluator-runner-deps.test.d.ts.map +1 -0
- package/dist/services/__tests__/evaluator-runner-deps.test.js +304 -0
- package/dist/services/__tests__/evaluator-runner-deps.test.js.map +1 -0
- package/dist/services/__tests__/rulehost-readiness.test.js.map +1 -1
- package/dist/services/__tests__/runtime-adapter-resolver.test.js.map +1 -1
- package/dist/services/config-doctor.d.ts.map +1 -1
- package/dist/services/config-doctor.js +9 -2
- package/dist/services/config-doctor.js.map +1 -1
- package/dist/services/pain-flood-simulation-runner.d.ts.map +1 -1
- package/dist/services/pain-flood-simulation-runner.js +9 -0
- package/dist/services/pain-flood-simulation-runner.js.map +1 -1
- package/dist/services/pd-config-loader.js +2 -2
- package/dist/services/pd-config-loader.js.map +1 -1
- package/dist/services/proven-channel-baseline-runner.d.ts.map +1 -1
- package/dist/services/proven-channel-baseline-runner.js +10 -2
- package/dist/services/proven-channel-baseline-runner.js.map +1 -1
- package/dist/services/quality-scorecard/data-extractor.js.map +1 -1
- package/dist/services/resolve-runtime-from-pd-config.js.map +1 -1
- package/dist/services/rulehost-pipeline-runner.d.ts +77 -1
- package/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
- package/dist/services/rulehost-pipeline-runner.js +111 -7
- package/dist/services/rulehost-pipeline-runner.js.map +1 -1
- package/dist/services/rulehost-readiness.js.map +1 -1
- package/dist/services/runtime-adapter-resolver.d.ts +1 -0
- package/dist/services/runtime-adapter-resolver.d.ts.map +1 -1
- package/dist/services/runtime-adapter-resolver.js +3 -0
- package/dist/services/runtime-adapter-resolver.js.map +1 -1
- package/dist/services/synthetic-baseline-runner.d.ts.map +1 -1
- package/dist/services/synthetic-baseline-runner.js +11 -0
- package/dist/services/synthetic-baseline-runner.js.map +1 -1
- package/dist/utils/production-workspace-guard.d.ts +4 -4
- package/dist/utils/production-workspace-guard.d.ts.map +1 -1
- package/dist/utils/production-workspace-guard.js +19 -16
- package/dist/utils/production-workspace-guard.js.map +1 -1
- package/dist/utils/production-workspace-guard.test.js +54 -19
- package/dist/utils/production-workspace-guard.test.js.map +1 -1
- package/package.json +8 -5
- package/src/commands/__tests__/intent-flag-wiring.test.ts +88 -3
- package/src/commands/__tests__/pain-retry-maxTokens-flag.test.ts +73 -0
- package/src/commands/__tests__/rulecode-flag-wiring.test.ts +31 -24
- package/src/commands/__tests__/run-rulehost-flag-wiring.test.ts +12 -0
- package/src/commands/admission-gate.ts +30 -0
- package/src/commands/candidate.ts +74 -6
- package/src/commands/console.ts +40 -0
- package/src/commands/demo-story-a.ts +4 -2
- package/src/commands/diagnose.ts +158 -10
- package/src/commands/errors-list.ts +440 -0
- package/src/commands/health-codex.ts +249 -0
- package/src/commands/health.ts +60 -0
- package/src/commands/intent.ts +98 -29
- package/src/commands/pain-evidence.ts +6 -0
- package/src/commands/pain-record.ts +21 -0
- package/src/commands/pain-retry.ts +353 -35
- package/src/commands/proven-channel-baseline.ts +4 -2
- package/src/commands/runtime-activation.ts +657 -12
- package/src/commands/runtime-canary.ts +31 -5
- package/src/commands/runtime-health-snapshot.ts +4 -2
- package/src/commands/runtime-init.ts +305 -0
- package/src/commands/runtime-internalization-context-trace.ts +445 -0
- package/src/commands/runtime-internalization-enqueue-successors.ts +3 -1
- package/src/commands/runtime-internalization-integrity.ts +4 -2
- package/src/commands/runtime-internalization-run-once.ts +20 -5
- package/src/commands/runtime-internalization-run-rulehost.ts +159 -6
- package/src/commands/runtime-uat.guard.test.ts +14 -16
- package/src/commands/runtime-uat.ts +4 -3
- package/src/config-reader.ts +1 -1
- package/src/index.ts +69 -78
- package/src/services/__tests__/evaluator-runner-deps.test.ts +341 -0
- package/src/services/config-doctor.ts +9 -2
- package/src/services/pain-flood-simulation-runner.ts +9 -0
- package/src/services/pd-config-loader.ts +2 -2
- package/src/services/proven-channel-baseline-runner.ts +10 -3
- package/src/services/rulehost-pipeline-runner.ts +157 -6
- package/src/services/runtime-adapter-resolver.ts +4 -0
- package/src/services/synthetic-baseline-runner.ts +11 -0
- package/src/utils/production-workspace-guard.test.ts +62 -20
- package/src/utils/production-workspace-guard.ts +19 -16
- package/tests/bdd/cli-contract.steps.ts +343 -0
- package/tests/bdd/context-trace.steps.ts +229 -0
- package/tests/bdd/support/gherkin-loader.ts +147 -0
- package/tests/bdd/support/repo-root.ts +62 -0
- package/tests/bdd/support/vitest-bdd.ts +179 -0
- package/tests/commands/admission-gate-coverage.test.ts +79 -0
- package/tests/commands/candidate-audit-repair.test.ts +77 -0
- package/tests/commands/candidate-intake.test.ts +155 -10
- package/tests/commands/candidate-internalization-backfill.test.ts +30 -0
- package/tests/commands/cli-help-snapshot.test.ts +15 -1
- package/tests/commands/console-open.test.ts +19 -0
- package/tests/commands/diagnose.test.ts +619 -14
- package/tests/commands/errors-list.test.ts +678 -0
- package/tests/commands/health-codex.test.ts +243 -0
- package/tests/commands/health-host-wiring.test.ts +76 -0
- package/tests/commands/intent.test.ts +4 -4
- package/tests/commands/pain-record.test.ts +80 -0
- package/tests/commands/pain-retry.test.ts +94 -3
- package/tests/commands/run-rulehost-handler.test.ts +133 -0
- package/tests/commands/runtime-activation-approve-flag-wiring.test.ts +227 -0
- package/tests/commands/runtime-activation-deactivate-flag-wiring.test.ts +167 -0
- package/tests/commands/runtime-activation-dispatch-flag-wiring.test.ts +262 -0
- package/tests/commands/runtime-activation-list-flag-wiring.test.ts +193 -0
- package/tests/commands/runtime-activation-promote-flag-wiring.test.ts +222 -0
- package/tests/commands/runtime-activation.test.ts +1090 -5
- package/tests/commands/runtime-canary.test.ts +50 -0
- package/tests/commands/runtime-features.test.ts +2 -0
- package/tests/commands/runtime-init-empty-workspace.test.ts +234 -0
- package/tests/commands/runtime-init.test.ts +346 -0
- package/tests/commands/runtime-internalization-context-trace.test.ts +110 -0
- package/tests/commands/runtime-internalization.test.ts +2 -2
- package/tests/config-reader.test.ts +6 -5
- package/tests/e2e/cross-package-acceptance.test.ts +55 -13
- package/tests/services/mainline-snapshot-assembler.test.ts +6 -3
- package/tests/services/resolve-runtime-from-pd-config.test.ts +2 -0
- package/tests/services/rulehost-pipeline-runner.test.ts +1 -1
- package/vitest.config.ts +1 -1
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pd errors list — List PD pipeline errors (failed tasks + worker errors).
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* pd errors list [--json] [--kind <runnerKind>] [--since <hours>] [--limit <n>] [--workspace <path>]
|
|
6
|
+
*
|
|
7
|
+
* Aggregates two error sources into a single operator-facing read-only view:
|
|
8
|
+
* 1. SQLite state.db tasks where status IN ('failed', 'needs_human_review')
|
|
9
|
+
* (via SqliteTaskStore.listFailedTasks — Task 8).
|
|
10
|
+
* 2. worker-status.json `errors` array written by EvolutionWorker
|
|
11
|
+
* (Task 2 extended the entry shape to { at, kind, principleId, error } | string).
|
|
12
|
+
*
|
|
13
|
+
* CLI gate compliance:
|
|
14
|
+
* - cli-1-strict-json: --json stdout is exactly one parseable JSON object.
|
|
15
|
+
* - cli-2-exit-stops: every process.exit(...) is immediately followed by return.
|
|
16
|
+
* - cli-6-output-next-action: empty result includes a `nextAction` field.
|
|
17
|
+
* - cli-4-dry-run-confirm-mutex: N/A (read-only command).
|
|
18
|
+
*
|
|
19
|
+
* Runtime contract compliance:
|
|
20
|
+
* - rc-1-treat-as-unknown: worker-status.json parsed content is treated as unknown.
|
|
21
|
+
* - rc-2-no-as-bypass: no `as` casts; runtime validation via typeof / Array.isArray.
|
|
22
|
+
* - rc-4-validate-array-elements: errors array elements are validated element-wise.
|
|
23
|
+
* - rc-5-object-hasown-not-in: Object.hasOwn used for untrusted object key checks.
|
|
24
|
+
* - rc-9-no-silent-fallback: missing worker-status.json → workerErrors=[] with
|
|
25
|
+
* a `workerStatusMissing` note; parse failures surface a `workerStatusWarning`.
|
|
26
|
+
*/
|
|
27
|
+
import * as path from 'path';
|
|
28
|
+
import * as fs from 'fs';
|
|
29
|
+
import { SqliteConnection, SqliteTaskStore } from '@principles/core';
|
|
30
|
+
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
31
|
+
/** Default and maximum values for --limit. */
|
|
32
|
+
const DEFAULT_LIMIT = 50;
|
|
33
|
+
const MAX_LIMIT = 200;
|
|
34
|
+
/**
|
|
35
|
+
* Type guard: narrow `unknown` to a plain record (rc-2: no `as` bypass).
|
|
36
|
+
* Returns true only for non-null, non-array objects.
|
|
37
|
+
*/
|
|
38
|
+
function isRecord(value) {
|
|
39
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Validate and normalize a single worker-status.json errors entry.
|
|
43
|
+
*
|
|
44
|
+
* rc-1: input is `unknown` (parsed from JSON).
|
|
45
|
+
* rc-2: no `as` — uses typeof / Object.hasOwn guards.
|
|
46
|
+
* rc-5: Object.hasOwn for key checks (not `in`).
|
|
47
|
+
*
|
|
48
|
+
* Accepts:
|
|
49
|
+
* - string → { error: <string>, rawForm: 'string', others null }
|
|
50
|
+
* - { at, kind, principleId, error } → normalized object
|
|
51
|
+
* Anything else → null (skipped; caller records a warning).
|
|
52
|
+
*/
|
|
53
|
+
function normalizeWorkerErrorEntry(entry) {
|
|
54
|
+
if (typeof entry === 'string') {
|
|
55
|
+
return {
|
|
56
|
+
at: null,
|
|
57
|
+
kind: null,
|
|
58
|
+
principleId: null,
|
|
59
|
+
error: entry,
|
|
60
|
+
rawForm: 'string',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// rc-2: type guard instead of `as` cast (isRecord narrows unknown → record).
|
|
64
|
+
if (!isRecord(entry)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
// rc-5: use Object.hasOwn, not `in`, for untrusted object key checks.
|
|
68
|
+
const at = Object.hasOwn(entry, 'at') && typeof entry.at === 'string' ? entry.at : null;
|
|
69
|
+
const kind = Object.hasOwn(entry, 'kind') && typeof entry.kind === 'string' ? entry.kind : null;
|
|
70
|
+
const principleId = Object.hasOwn(entry, 'principleId') && typeof entry.principleId === 'string' ? entry.principleId : null;
|
|
71
|
+
// `error` is the only required field for the object form; if missing or
|
|
72
|
+
// non-string, fall back to JSON.stringify so we don't lose the entry.
|
|
73
|
+
let errorStr;
|
|
74
|
+
if (Object.hasOwn(entry, 'error') && typeof entry.error === 'string') {
|
|
75
|
+
errorStr = entry.error;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
try {
|
|
79
|
+
errorStr = JSON.stringify(entry);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
errorStr = '[unserializable worker-status error entry]';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
at,
|
|
87
|
+
kind,
|
|
88
|
+
principleId,
|
|
89
|
+
error: errorStr,
|
|
90
|
+
rawForm: 'object',
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Read and validate the worker-status.json `errors` array.
|
|
95
|
+
*
|
|
96
|
+
* Returns `{ entries, missing, warning }`:
|
|
97
|
+
* - `missing: true` if the file does not exist (not an error — worker hasn't run).
|
|
98
|
+
* - `warning: string` if the file exists but is unparseable / wrong shape
|
|
99
|
+
* (rc-9: surface the reason, do not silently swallow).
|
|
100
|
+
* - `entries: WorkerErrorEntry[]` validated element-wise (rc-4).
|
|
101
|
+
*/
|
|
102
|
+
function readWorkerStatusErrors(stateDir) {
|
|
103
|
+
const statusPath = path.join(stateDir, 'worker-status.json');
|
|
104
|
+
if (!fs.existsSync(statusPath)) {
|
|
105
|
+
return { entries: [], missing: true, warning: null };
|
|
106
|
+
}
|
|
107
|
+
let raw;
|
|
108
|
+
try {
|
|
109
|
+
raw = fs.readFileSync(statusPath, 'utf8');
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
return {
|
|
113
|
+
entries: [],
|
|
114
|
+
missing: false,
|
|
115
|
+
warning: `Failed to read worker-status.json: ${err instanceof Error ? err.message : String(err)}`,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
// rc-1: parsed JSON is unknown.
|
|
119
|
+
let parsed;
|
|
120
|
+
try {
|
|
121
|
+
parsed = JSON.parse(raw);
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
return {
|
|
125
|
+
entries: [],
|
|
126
|
+
missing: false,
|
|
127
|
+
warning: `Failed to parse worker-status.json: ${err instanceof Error ? err.message : String(err)}`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (!isRecord(parsed)) {
|
|
131
|
+
return {
|
|
132
|
+
entries: [],
|
|
133
|
+
missing: false,
|
|
134
|
+
warning: 'worker-status.json root is not a JSON object',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// rc-5: Object.hasOwn for untrusted key check.
|
|
138
|
+
if (!Object.hasOwn(parsed, 'errors')) {
|
|
139
|
+
// No `errors` field — treat as empty (older worker-status.json may lack it).
|
|
140
|
+
return { entries: [], missing: false, warning: null };
|
|
141
|
+
}
|
|
142
|
+
const errorsField = parsed.errors;
|
|
143
|
+
if (!Array.isArray(errorsField)) {
|
|
144
|
+
return {
|
|
145
|
+
entries: [],
|
|
146
|
+
missing: false,
|
|
147
|
+
warning: 'worker-status.json `errors` field is not an array',
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// rc-4: validate array element types; skip malformed entries.
|
|
151
|
+
const entries = [];
|
|
152
|
+
let skipped = 0;
|
|
153
|
+
for (const item of errorsField) {
|
|
154
|
+
const normalized = normalizeWorkerErrorEntry(item);
|
|
155
|
+
if (normalized === null) {
|
|
156
|
+
skipped++;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
entries.push(normalized);
|
|
160
|
+
}
|
|
161
|
+
const warning = skipped > 0
|
|
162
|
+
? `Skipped ${skipped} malformed worker-status.json error entr${skipped === 1 ? 'y' : 'ies'}`
|
|
163
|
+
: null;
|
|
164
|
+
return { entries, missing: false, warning };
|
|
165
|
+
}
|
|
166
|
+
function formatTextOutput(result, workspaceDir) {
|
|
167
|
+
const lines = [];
|
|
168
|
+
lines.push('PD Errors List');
|
|
169
|
+
lines.push(` workspace: ${workspaceDir}`);
|
|
170
|
+
lines.push(` total: ${result.total} (tasks: ${result.tasks.length}, workerErrors: ${result.workerErrors.length})`);
|
|
171
|
+
lines.push('');
|
|
172
|
+
if (result.workerStatusMissing) {
|
|
173
|
+
lines.push(` workerStatus: (missing — ${result.workerStatusPath} not found)`);
|
|
174
|
+
}
|
|
175
|
+
else if (result.workerStatusWarning) {
|
|
176
|
+
lines.push(` workerStatus: WARNING — ${result.workerStatusWarning}`);
|
|
177
|
+
}
|
|
178
|
+
if (result.tasks.length > 0) {
|
|
179
|
+
lines.push('');
|
|
180
|
+
lines.push('Failed tasks:');
|
|
181
|
+
for (const t of result.tasks) {
|
|
182
|
+
// rc-2: type guard instead of `as` cast — tasks come from SqliteTaskStore
|
|
183
|
+
// which returns FailedTaskSummary[], but we typed tasks as unknown[] to
|
|
184
|
+
// keep the result interface decoupled from core's type exports.
|
|
185
|
+
const task = isRecord(t) ? t : null;
|
|
186
|
+
const taskId = task && typeof task.taskId === 'string' ? task.taskId : '?';
|
|
187
|
+
const taskKind = task && typeof task.taskKind === 'string' ? task.taskKind : '?';
|
|
188
|
+
const status = task && typeof task.status === 'string' ? task.status : '?';
|
|
189
|
+
const lastError = task && typeof task.lastError === 'string' ? task.lastError : '-';
|
|
190
|
+
const attemptCount = task && typeof task.attemptCount === 'number' ? task.attemptCount : 0;
|
|
191
|
+
const painId = task && typeof task.painId === 'string' ? task.painId : '-';
|
|
192
|
+
const lastAttemptAt = task && typeof task.lastAttemptAt === 'string' ? task.lastAttemptAt : '-';
|
|
193
|
+
lines.push(` - ${taskId} (${taskKind}) [${status}]`);
|
|
194
|
+
lines.push(` painId: ${painId}`);
|
|
195
|
+
lines.push(` lastError: ${lastError}`);
|
|
196
|
+
lines.push(` attemptCount: ${attemptCount}`);
|
|
197
|
+
lines.push(` lastAttemptAt: ${lastAttemptAt}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (result.workerErrors.length > 0) {
|
|
201
|
+
lines.push('');
|
|
202
|
+
lines.push('Worker errors:');
|
|
203
|
+
for (const e of result.workerErrors) {
|
|
204
|
+
const at = e.at ?? '-';
|
|
205
|
+
const kind = e.kind ?? '-';
|
|
206
|
+
const pid = e.principleId ?? '-';
|
|
207
|
+
lines.push(` - [${at}] kind=${kind} principleId=${pid}`);
|
|
208
|
+
lines.push(` error: ${e.error}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (result.total === 0) {
|
|
212
|
+
lines.push('');
|
|
213
|
+
lines.push('No errors found. PD pipeline is healthy.');
|
|
214
|
+
}
|
|
215
|
+
return lines.join('\n');
|
|
216
|
+
}
|
|
217
|
+
export async function handleErrorsList(opts) {
|
|
218
|
+
const workspaceDir = opts.workspace ? path.resolve(opts.workspace) : resolveWorkspaceDir();
|
|
219
|
+
const stateDir = path.join(workspaceDir, '.pd');
|
|
220
|
+
const stateDbPath = path.join(stateDir, 'state.db');
|
|
221
|
+
// Pre-check: if state.db does not exist, fail loud (cli-2-exit-stops + rc-9).
|
|
222
|
+
if (!fs.existsSync(stateDbPath)) {
|
|
223
|
+
const msg = `Error: state.db not found at ${stateDbPath}. Workspace may not be initialized.`;
|
|
224
|
+
if (opts.json) {
|
|
225
|
+
// cli-1: even error JSON is a single object on stdout? No — cli-2 says
|
|
226
|
+
// failure paths write to stderr. JSON error envelope goes to stderr too
|
|
227
|
+
// so stdout stays clean (cli-1-strict-json guarantees stdout is parseable).
|
|
228
|
+
process.stderr.write(JSON.stringify({
|
|
229
|
+
ok: false,
|
|
230
|
+
reason: msg,
|
|
231
|
+
nextAction: 'Run "pd runtime init --confirm --workspace <dir>" to initialize databases, then retry.',
|
|
232
|
+
}, null, 2) + '\n');
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
process.stderr.write(msg + '\n');
|
|
236
|
+
}
|
|
237
|
+
process.exitCode = 1;
|
|
238
|
+
return; // cli-2-exit-stops
|
|
239
|
+
}
|
|
240
|
+
// Resolve and validate --limit.
|
|
241
|
+
let limit = DEFAULT_LIMIT;
|
|
242
|
+
if (opts.limit !== undefined) {
|
|
243
|
+
if (!Number.isFinite(opts.limit) || opts.limit <= 0) {
|
|
244
|
+
const msg = `Error: --limit must be a positive integer, got ${opts.limit}`;
|
|
245
|
+
// cli-6-output-next-action: mirror the state.db missing branch — when
|
|
246
|
+
// opts.json is true, emit a structured { ok:false, reason, nextAction }
|
|
247
|
+
// envelope to stderr instead of plain text.
|
|
248
|
+
if (opts.json) {
|
|
249
|
+
process.stderr.write(JSON.stringify({
|
|
250
|
+
ok: false,
|
|
251
|
+
reason: msg,
|
|
252
|
+
nextAction: 'Pass --limit as a positive integer (e.g. --limit 50). Maximum is 500.',
|
|
253
|
+
}, null, 2) + '\n');
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
process.stderr.write(msg + '\n');
|
|
257
|
+
}
|
|
258
|
+
process.exitCode = 1;
|
|
259
|
+
return; // cli-2-exit-stops
|
|
260
|
+
}
|
|
261
|
+
limit = Math.min(opts.limit, MAX_LIMIT);
|
|
262
|
+
}
|
|
263
|
+
// Resolve --since (hours → Unix-ms timestamp).
|
|
264
|
+
let sinceMs;
|
|
265
|
+
if (opts.since !== undefined) {
|
|
266
|
+
if (!Number.isFinite(opts.since) || opts.since < 0) {
|
|
267
|
+
const msg = `Error: --since must be a non-negative number of hours, got ${opts.since}`;
|
|
268
|
+
// cli-6-output-next-action: same JSON envelope pattern as --limit above.
|
|
269
|
+
if (opts.json) {
|
|
270
|
+
process.stderr.write(JSON.stringify({
|
|
271
|
+
ok: false,
|
|
272
|
+
reason: msg,
|
|
273
|
+
nextAction: 'Pass --since as a non-negative number of hours (e.g. --since 24 for the last 24h).',
|
|
274
|
+
}, null, 2) + '\n');
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
process.stderr.write(msg + '\n');
|
|
278
|
+
}
|
|
279
|
+
process.exitCode = 1;
|
|
280
|
+
return; // cli-2-exit-stops
|
|
281
|
+
}
|
|
282
|
+
sinceMs = Date.now() - opts.since * 3600 * 1000;
|
|
283
|
+
}
|
|
284
|
+
const connection = new SqliteConnection({ workspaceDir, readonly: true });
|
|
285
|
+
try {
|
|
286
|
+
const taskStore = new SqliteTaskStore(connection);
|
|
287
|
+
const tasks = await taskStore.listFailedTasks({
|
|
288
|
+
kind: opts.kind,
|
|
289
|
+
since: sinceMs,
|
|
290
|
+
limit,
|
|
291
|
+
});
|
|
292
|
+
const { entries: workerErrors, missing, warning } = readWorkerStatusErrors(stateDir);
|
|
293
|
+
const total = tasks.length + workerErrors.length;
|
|
294
|
+
const result = {
|
|
295
|
+
tasks,
|
|
296
|
+
workerErrors,
|
|
297
|
+
total,
|
|
298
|
+
workerStatusPath: path.join(stateDir, 'worker-status.json'),
|
|
299
|
+
};
|
|
300
|
+
if (missing) {
|
|
301
|
+
result.workerStatusMissing = true;
|
|
302
|
+
}
|
|
303
|
+
if (warning) {
|
|
304
|
+
result.workerStatusWarning = warning;
|
|
305
|
+
}
|
|
306
|
+
// cli-6-output-next-action: include nextAction only when there are no errors.
|
|
307
|
+
if (total === 0) {
|
|
308
|
+
result.nextAction = 'No errors found. PD pipeline is healthy.';
|
|
309
|
+
}
|
|
310
|
+
if (opts.json) {
|
|
311
|
+
// cli-1-strict-json: stdout is exactly one parseable JSON object.
|
|
312
|
+
console.log(JSON.stringify(result, null, 2));
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
console.log(formatTextOutput(result, workspaceDir));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
320
|
+
if (opts.json) {
|
|
321
|
+
process.stderr.write(JSON.stringify({
|
|
322
|
+
ok: false,
|
|
323
|
+
reason: `Failed to list errors: ${message}`,
|
|
324
|
+
nextAction: 'Check workspace path and state.db readability, then retry.',
|
|
325
|
+
}, null, 2) + '\n');
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
process.stderr.write(`Error: ${message}\n`);
|
|
329
|
+
}
|
|
330
|
+
process.exitCode = 1;
|
|
331
|
+
return; // cli-2-exit-stops
|
|
332
|
+
}
|
|
333
|
+
finally {
|
|
334
|
+
connection.close();
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Register the `errors` command group with `list` subcommand on a Commander
|
|
339
|
+
* program. Used by both production CLI (src/index.ts) and parser-level tests
|
|
340
|
+
* (cli-7-test-wiring).
|
|
341
|
+
*
|
|
342
|
+
* The `errors` command group is hidden from `pd --help` (operator diagnostic,
|
|
343
|
+
* same convention as `legacy` / `artifact` / `runtime recovery`).
|
|
344
|
+
*/
|
|
345
|
+
export function registerErrorsListCommand(program) {
|
|
346
|
+
const errorsCmd = program
|
|
347
|
+
.command('errors', { hidden: true })
|
|
348
|
+
.description('PD pipeline error inspection (failed tasks + worker errors)');
|
|
349
|
+
errorsCmd
|
|
350
|
+
.command('list')
|
|
351
|
+
.description('List PD pipeline errors — failed tasks + worker-status.json errors')
|
|
352
|
+
.option('-w, --workspace <path>', 'Workspace directory')
|
|
353
|
+
.option('--json', 'Output raw JSON (cli-1-strict-json: stdout is exactly one JSON object)')
|
|
354
|
+
.option('--kind <runnerKind>', 'Filter failed tasks by task_kind (e.g. diagnostician, dreamer)')
|
|
355
|
+
.option('--since <hours>', 'Only show errors from the last N hours (non-negative number)', parseInt)
|
|
356
|
+
.option('--limit <n>', 'Max failed tasks to return (default: 50, max: 200)', parseInt)
|
|
357
|
+
.action(async (opts) => {
|
|
358
|
+
await handleErrorsList({
|
|
359
|
+
workspace: opts.workspace,
|
|
360
|
+
json: opts.json === true,
|
|
361
|
+
kind: opts.kind,
|
|
362
|
+
since: opts.since,
|
|
363
|
+
limit: opts.limit,
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
return errorsCmd;
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=errors-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-list.js","sourceRoot":"","sources":["../../src/commands/errors-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-codex.d.ts","sourceRoot":"","sources":["../../src/commands/health-codex.ts"],"names":[],"mappings":"AAsBA,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA2GD,wBAAsB,iBAAiB,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoHpF"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pd health --host codex command implementation.
|
|
3
|
+
*
|
|
4
|
+
* Reports Codex adapter/runtime versions, host.codex feature flag state,
|
|
5
|
+
* hook trust status, and dual global/plugin hook registration detection.
|
|
6
|
+
*
|
|
7
|
+
* CLI gate compliance:
|
|
8
|
+
* - cli-1: --json outputs exactly one parseable JSON object on stdout.
|
|
9
|
+
* - cli-2: exit paths stop execution (return after process.exit).
|
|
10
|
+
* - cli-5: failure paths do not mutate state (read-only throughout).
|
|
11
|
+
* - cli-6: every degraded/refused result includes reason + nextAction.
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import * as os from 'os';
|
|
16
|
+
import { createRequire } from 'module';
|
|
17
|
+
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
18
|
+
import { loadPdConfigForPlugin, resolveNearestPdWorkspace } from '@principles/host-runtime';
|
|
19
|
+
import { computeFeatureFlagsFromConfig, isFeatureEnabled } from '@principles/core/runtime-v2';
|
|
20
|
+
const require = createRequire(import.meta.url);
|
|
21
|
+
function readPackageVersion(packageName) {
|
|
22
|
+
try {
|
|
23
|
+
const pkgJsonPath = require.resolve(`${packageName}/package.json`);
|
|
24
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
|
|
25
|
+
if (typeof pkg.version === 'string')
|
|
26
|
+
return pkg.version;
|
|
27
|
+
return 'unknown';
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return 'unknown';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function detectCodexConfigDir() {
|
|
34
|
+
const home = os.homedir();
|
|
35
|
+
const codexDir = path.join(home, '.codex');
|
|
36
|
+
if (fs.existsSync(codexDir))
|
|
37
|
+
return codexDir;
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
function detectHooksTrust(codexConfigDir) {
|
|
41
|
+
if (!codexConfigDir) {
|
|
42
|
+
return {
|
|
43
|
+
detectable: false,
|
|
44
|
+
reason: 'codex_config_dir_not_found',
|
|
45
|
+
nextAction: 'Install Codex CLI (>= 0.147) and run `codex` once to create ~/.codex/, then re-run `pd health --host codex` to verify hook trust state.',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Codex stores hook trust in config.toml under [features] hooks = true|false.
|
|
49
|
+
// We do a best-effort text scan rather than a full TOML parse to avoid a new
|
|
50
|
+
// dependency. If the file is missing or the hook line is absent, we report
|
|
51
|
+
// undetectable with a clear next action.
|
|
52
|
+
const configTomlPath = path.join(codexConfigDir, 'config.toml');
|
|
53
|
+
if (!fs.existsSync(configTomlPath)) {
|
|
54
|
+
return {
|
|
55
|
+
detectable: false,
|
|
56
|
+
reason: 'config_toml_not_found',
|
|
57
|
+
nextAction: `Open Codex and run /hooks to trust PD hooks, then re-run \`pd health --host codex\`. Expected config at ${configTomlPath}.`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const raw = fs.readFileSync(configTomlPath, 'utf8');
|
|
62
|
+
const match = /hooks\s*=\s*(true|false)/i.exec(raw);
|
|
63
|
+
if (!match || !match[1]) {
|
|
64
|
+
return {
|
|
65
|
+
detectable: false,
|
|
66
|
+
reason: 'hooks_setting_not_found_in_config',
|
|
67
|
+
nextAction: 'Open Codex and run /hooks to trust PD hooks. Codex config.toml exists but has no `hooks` setting under [features].',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return { detectable: true, trusted: match[1].toLowerCase() === 'true' };
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
74
|
+
return {
|
|
75
|
+
detectable: false,
|
|
76
|
+
reason: `config_toml_read_failed: ${message.slice(0, 200)}`,
|
|
77
|
+
nextAction: `Check read permissions on ${configTomlPath} and re-run \`pd health --host codex\`.`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function detectDualRegistration(codexConfigDir) {
|
|
82
|
+
const globalHooksPath = codexConfigDir ? path.join(codexConfigDir, 'hooks.json') : undefined;
|
|
83
|
+
// Plugin hooks are declared in a plugin manifest; we cannot reliably detect
|
|
84
|
+
// them from outside Codex. We only flag the global-hooks path and let the
|
|
85
|
+
// operator confirm plugin registration via /hooks in Codex.
|
|
86
|
+
const globalHooksExists = globalHooksPath ? fs.existsSync(globalHooksPath) : false;
|
|
87
|
+
if (globalHooksExists) {
|
|
88
|
+
return {
|
|
89
|
+
detected: true,
|
|
90
|
+
globalHooksPath,
|
|
91
|
+
reason: 'global_hooks_json_present',
|
|
92
|
+
nextAction: 'Global ~/.codex/hooks.json is installed. If the PD Codex plugin is also installed via marketplace, this may cause double-registration. Choose ONE: keep global hooks.json (fallback path) OR uninstall it and use the plugin (recommended). To remove global PD entries, run `create-principles-disciple uninstall --host codex`.',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return { detected: false };
|
|
96
|
+
}
|
|
97
|
+
export async function handleHealthCodex(opts = {}) {
|
|
98
|
+
const generatedAt = new Date().toISOString();
|
|
99
|
+
const workspaceDir = opts.workspace
|
|
100
|
+
? path.resolve(opts.workspace)
|
|
101
|
+
: resolveWorkspaceDir();
|
|
102
|
+
const warnings = [];
|
|
103
|
+
// Resolve workspace via the shared host-runtime resolver so pd-cli reports
|
|
104
|
+
// the same workspace the Codex hook would resolve.
|
|
105
|
+
const resolution = resolveNearestPdWorkspace(workspaceDir);
|
|
106
|
+
let resolvedWorkspace;
|
|
107
|
+
let featureFlagSource;
|
|
108
|
+
let hostCodexEnabled = false;
|
|
109
|
+
if (!resolution.ok) {
|
|
110
|
+
resolvedWorkspace = workspaceDir;
|
|
111
|
+
featureFlagSource = 'defaults';
|
|
112
|
+
warnings.push(`workspace_not_resolved: ${resolution.reason} — ${resolution.nextAction}`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
resolvedWorkspace = resolution.workspaceDir;
|
|
116
|
+
const configLoad = loadPdConfigForPlugin(resolvedWorkspace);
|
|
117
|
+
featureFlagSource = configLoad.source;
|
|
118
|
+
const flags = computeFeatureFlagsFromConfig(configLoad.effective);
|
|
119
|
+
hostCodexEnabled = isFeatureEnabled(flags, 'host.codex');
|
|
120
|
+
if (!configLoad.ok) {
|
|
121
|
+
for (const error of configLoad.errors) {
|
|
122
|
+
warnings.push(`config_error: ${error.reason} — ${error.nextAction}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const adapterVersion = readPackageVersion('@principles/codex-adapter');
|
|
127
|
+
const runtimeVersion = readPackageVersion('@principles/host-runtime');
|
|
128
|
+
const codexConfigDir = detectCodexConfigDir();
|
|
129
|
+
const hooksTrust = detectHooksTrust(codexConfigDir);
|
|
130
|
+
const dualRegistration = detectDualRegistration(codexConfigDir);
|
|
131
|
+
if (hooksTrust.reason)
|
|
132
|
+
warnings.push(`hooks_trust: ${hooksTrust.reason}`);
|
|
133
|
+
if (dualRegistration.reason)
|
|
134
|
+
warnings.push(`dual_registration: ${dualRegistration.reason}`);
|
|
135
|
+
const report = {
|
|
136
|
+
generatedAt,
|
|
137
|
+
host: 'codex',
|
|
138
|
+
workspace: resolvedWorkspace,
|
|
139
|
+
adapterVersion,
|
|
140
|
+
runtimeVersion,
|
|
141
|
+
featureFlag: {
|
|
142
|
+
name: 'host.codex',
|
|
143
|
+
enabled: hostCodexEnabled,
|
|
144
|
+
source: featureFlagSource,
|
|
145
|
+
...(hostCodexEnabled
|
|
146
|
+
? {}
|
|
147
|
+
: {
|
|
148
|
+
reason: 'host_codex_disabled',
|
|
149
|
+
nextAction: `Enable the Codex host adapter by setting features.host.codex.enabled=true in ${resolvedWorkspace}/.pd/config.yaml, then re-run \`pd health --host codex\`.`,
|
|
150
|
+
}),
|
|
151
|
+
},
|
|
152
|
+
hooksTrust,
|
|
153
|
+
dualRegistration,
|
|
154
|
+
warnings,
|
|
155
|
+
};
|
|
156
|
+
if (opts.json) {
|
|
157
|
+
// cli-1: exactly one parseable JSON object on stdout.
|
|
158
|
+
console.log(JSON.stringify(report, null, 2));
|
|
159
|
+
// cli-2: exit-stops. Non-zero only when host.codex is disabled AND hooks
|
|
160
|
+
// are not trusted — the operator must act before Codex activation works.
|
|
161
|
+
if (!hostCodexEnabled && !hooksTrust.trusted) {
|
|
162
|
+
process.exitCode = 1;
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
// Text output — still includes explicit nextAction per cli-6.
|
|
167
|
+
console.log(`generatedAt: ${report.generatedAt}`);
|
|
168
|
+
console.log(`host: ${report.host}`);
|
|
169
|
+
console.log(`workspace: ${report.workspace}`);
|
|
170
|
+
console.log(`adapterVersion: ${report.adapterVersion}`);
|
|
171
|
+
console.log(`runtimeVersion: ${report.runtimeVersion}`);
|
|
172
|
+
console.log(`featureFlag.name: ${report.featureFlag.name}`);
|
|
173
|
+
console.log(`featureFlag.enabled: ${report.featureFlag.enabled}`);
|
|
174
|
+
console.log(`featureFlag.source: ${report.featureFlag.source}`);
|
|
175
|
+
if (report.featureFlag.reason) {
|
|
176
|
+
console.log(`featureFlag.reason: ${report.featureFlag.reason}`);
|
|
177
|
+
console.log(`featureFlag.nextAction: ${report.featureFlag.nextAction ?? ''}`);
|
|
178
|
+
}
|
|
179
|
+
console.log(`hooksTrust.detectable: ${report.hooksTrust.detectable}`);
|
|
180
|
+
if (report.hooksTrust.trusted !== undefined) {
|
|
181
|
+
console.log(`hooksTrust.trusted: ${report.hooksTrust.trusted}`);
|
|
182
|
+
}
|
|
183
|
+
if (report.hooksTrust.reason) {
|
|
184
|
+
console.log(`hooksTrust.reason: ${report.hooksTrust.reason}`);
|
|
185
|
+
console.log(`hooksTrust.nextAction: ${report.hooksTrust.nextAction ?? ''}`);
|
|
186
|
+
}
|
|
187
|
+
console.log(`dualRegistration.detected: ${report.dualRegistration.detected}`);
|
|
188
|
+
if (report.dualRegistration.globalHooksPath) {
|
|
189
|
+
console.log(`dualRegistration.globalHooksPath: ${report.dualRegistration.globalHooksPath}`);
|
|
190
|
+
}
|
|
191
|
+
if (report.dualRegistration.reason) {
|
|
192
|
+
console.log(`dualRegistration.reason: ${report.dualRegistration.reason}`);
|
|
193
|
+
console.log(`dualRegistration.nextAction: ${report.dualRegistration.nextAction ?? ''}`);
|
|
194
|
+
}
|
|
195
|
+
if (report.warnings.length > 0) {
|
|
196
|
+
console.log(`warnings:`);
|
|
197
|
+
for (const w of report.warnings)
|
|
198
|
+
console.log(` - ${w}`);
|
|
199
|
+
}
|
|
200
|
+
console.log('');
|
|
201
|
+
if (!hostCodexEnabled) {
|
|
202
|
+
console.warn(`⚠️ host.codex feature flag is disabled. Enable it in ${resolvedWorkspace}/.pd/config.yaml under features.host.codex.enabled to activate Codex hooks.`);
|
|
203
|
+
}
|
|
204
|
+
if (!hooksTrust.trusted && !hooksTrust.detectable) {
|
|
205
|
+
console.warn(`⚠️ Hook trust state could not be detected. ${hooksTrust.nextAction ?? ''}`);
|
|
206
|
+
process.exitCode = 1;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=health-codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-codex.js","sourceRoot":"","sources":["../../src/commands/health-codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,10 +7,34 @@
|
|
|
7
7
|
* to provide Runtime V2 health diagnostics.
|
|
8
8
|
* Uses read models from @principles/core/runtime-v2 (no direct ledger access).
|
|
9
9
|
*/
|
|
10
|
+
import type { Command } from 'commander';
|
|
11
|
+
import { handleHealthCodex } from './health-codex.js';
|
|
10
12
|
interface HealthOptions {
|
|
11
13
|
workspace?: string;
|
|
12
14
|
json?: boolean;
|
|
13
15
|
}
|
|
14
16
|
export declare function handleHealth(opts?: HealthOptions): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Handlers backing the `pd health` command. Injected so the registration
|
|
19
|
+
* wiring test can exercise the real `registerHealthCommand` without executing
|
|
20
|
+
* real workspace/DB I/O; production uses the defaults.
|
|
21
|
+
*/
|
|
22
|
+
interface HealthCommandHandlers {
|
|
23
|
+
health?: typeof handleHealth;
|
|
24
|
+
healthCodex?: typeof handleHealthCodex;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Registers the `pd health` command on a Commander program.
|
|
28
|
+
*
|
|
29
|
+
* cli-7 test-wiring: this is the single registration used by both the CLI
|
|
30
|
+
* entrypoint and the wiring test, so a test exercising it covers the real
|
|
31
|
+
* production command (options + --host dispatch), not a copy.
|
|
32
|
+
*
|
|
33
|
+
* --host accepts only `openclaw` and `codex`; any other value is rejected with
|
|
34
|
+
* a structured reason/nextAction and a non-zero exit (cli-1/cli-2/cli-6). When
|
|
35
|
+
* `--json` is set, the rejection is emitted as exactly one parseable JSON
|
|
36
|
+
* object on stdout.
|
|
37
|
+
*/
|
|
38
|
+
export declare function registerHealthCommand(program: Command, handlers?: HealthCommandHandlers): void;
|
|
15
39
|
export {};
|
|
16
40
|
//# sourceMappingURL=health.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AA0BtD,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAoBD,wBAAsB,YAAY,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4H1E;AAED;;;;GAIG;AACH,UAAU,qBAAqB;IAC7B,MAAM,CAAC,EAAE,OAAO,YAAY,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,iBAAiB,CAAC;CACxC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAE,qBAA0B,GAAG,IAAI,CAkClG"}
|