@principles/pd-cli 1.152.11 → 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/dist/commands/candidate.d.ts +3 -3
- package/dist/commands/candidate.d.ts.map +1 -1
- package/dist/commands/candidate.js +9 -21
- package/dist/commands/candidate.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
- package/dist/services/rulehost-pipeline-runner.js +4 -17
- package/dist/services/rulehost-pipeline-runner.js.map +1 -1
- package/package.json +13 -7
- 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 -1260
- 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 -1216
- 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 -565
- 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 -1175
- 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 -9
package/src/commands/task.ts
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pd task list/show commands — Runtime v2 task inspection.
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* pd task list [--status <status>] [--kind <kind>] [--limit <n>]
|
|
6
|
-
* pd task show <taskId>
|
|
7
|
-
*/
|
|
8
|
-
import * as path from 'path';
|
|
9
|
-
import type { Command } from 'commander';
|
|
10
|
-
import { RuntimeStateManager, MalformedRunError, type RunRecord } from '@principles/core';
|
|
11
|
-
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
12
|
-
import { withWorkspaceAndJson } from './command-helpers.js';
|
|
13
|
-
|
|
14
|
-
interface TaskListOptions {
|
|
15
|
-
status?: string;
|
|
16
|
-
kind?: string;
|
|
17
|
-
limit?: number;
|
|
18
|
-
workspace?: string;
|
|
19
|
-
json?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export async function handleTaskList(opts: TaskListOptions): Promise<void> {
|
|
23
|
-
// Pass through resolveWorkspaceDir to honor its consistency warning when
|
|
24
|
-
// --workspace disagrees with workspace.default in .pd/config.yaml.
|
|
25
|
-
const workspaceDir = resolveWorkspaceDir(opts.workspace);
|
|
26
|
-
const stateManager = new RuntimeStateManager({ workspaceDir });
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
await stateManager.initialize();
|
|
30
|
-
|
|
31
|
-
const filter: Record<string, string | number> = {};
|
|
32
|
-
if (opts.status) filter.status = opts.status;
|
|
33
|
-
if (opts.kind) filter.taskKind = opts.kind;
|
|
34
|
-
if (opts.limit) filter.limit = opts.limit;
|
|
35
|
-
|
|
36
|
-
const tasks = await stateManager.listTasks(Object.keys(filter).length > 0 ? filter : undefined);
|
|
37
|
-
|
|
38
|
-
if (opts.json) {
|
|
39
|
-
console.log(JSON.stringify({
|
|
40
|
-
ok: true,
|
|
41
|
-
count: tasks.length,
|
|
42
|
-
workspace: workspaceDir,
|
|
43
|
-
tasks: tasks.map((t) => ({
|
|
44
|
-
taskId: t.taskId,
|
|
45
|
-
taskKind: t.taskKind,
|
|
46
|
-
status: t.status,
|
|
47
|
-
attemptCount: t.attemptCount,
|
|
48
|
-
maxAttempts: t.maxAttempts,
|
|
49
|
-
leaseOwner: t.leaseOwner ?? null,
|
|
50
|
-
leaseExpiresAt: t.leaseExpiresAt ?? null,
|
|
51
|
-
createdAt: t.createdAt,
|
|
52
|
-
updatedAt: t.updatedAt,
|
|
53
|
-
})),
|
|
54
|
-
}, null, 2));
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (tasks.length === 0) {
|
|
59
|
-
console.log('No tasks found.');
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
console.log(`\nTasks (${tasks.length}):\n`);
|
|
64
|
-
console.log(
|
|
65
|
-
'%-22s %-12s %-10s %-4s/%-4s %-15s %s',
|
|
66
|
-
'TASK_ID', 'KIND', 'STATUS', 'ATT', 'MAX', 'LEASE_OWNER', 'LEASE_EXPIRES',
|
|
67
|
-
);
|
|
68
|
-
console.log('-'.repeat(90));
|
|
69
|
-
|
|
70
|
-
for (const task of tasks) {
|
|
71
|
-
const expiresAt = task.leaseExpiresAt
|
|
72
|
-
? new Date(task.leaseExpiresAt).toLocaleString()
|
|
73
|
-
: '-';
|
|
74
|
-
console.log(
|
|
75
|
-
'%-22s %-12s %-10s %-4s %-4s %-15s %s',
|
|
76
|
-
task.taskId.substring(0, 22),
|
|
77
|
-
task.taskKind.substring(0, 12),
|
|
78
|
-
task.status,
|
|
79
|
-
task.attemptCount,
|
|
80
|
-
task.maxAttempts,
|
|
81
|
-
task.leaseOwner ?? '-',
|
|
82
|
-
expiresAt.substring(0, 19),
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
console.log('');
|
|
86
|
-
} catch (err: unknown) {
|
|
87
|
-
// EP-04: failure paths emit a single parseable JSON object with
|
|
88
|
-
// structured reason + nextAction (mirror handleTaskShow).
|
|
89
|
-
if (opts.json) {
|
|
90
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
91
|
-
console.log(JSON.stringify({
|
|
92
|
-
ok: false,
|
|
93
|
-
count: 0,
|
|
94
|
-
workspace: workspaceDir,
|
|
95
|
-
reason,
|
|
96
|
-
nextAction: 'Check workspace path and database accessibility. The workspace may need bootstrap (run "pd runtime internalization integrity-repair --confirm") or the workspace dir may be wrong.',
|
|
97
|
-
}, null, 2));
|
|
98
|
-
} else {
|
|
99
|
-
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
100
|
-
}
|
|
101
|
-
process.exit(1);
|
|
102
|
-
return;
|
|
103
|
-
} finally {
|
|
104
|
-
await stateManager.close();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
interface TaskShowOptions {
|
|
109
|
-
id: string;
|
|
110
|
-
json?: boolean;
|
|
111
|
-
workspace?: string;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export async function handleTaskShow(opts: TaskShowOptions): Promise<void> {
|
|
115
|
-
const workspaceDir = opts.workspace ? path.resolve(opts.workspace) : resolveWorkspaceDir();
|
|
116
|
-
const stateManager = new RuntimeStateManager({ workspaceDir });
|
|
117
|
-
await stateManager.initialize();
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
const task = await stateManager.getTask(opts.id);
|
|
121
|
-
|
|
122
|
-
if (!task) {
|
|
123
|
-
if (opts.json) {
|
|
124
|
-
console.log(JSON.stringify({
|
|
125
|
-
ok: false,
|
|
126
|
-
reason: `Task not found: ${opts.id}`,
|
|
127
|
-
nextAction: 'Specify a valid taskId',
|
|
128
|
-
}, null, 2));
|
|
129
|
-
} else {
|
|
130
|
-
console.error(`Task not found: ${opts.id}`);
|
|
131
|
-
}
|
|
132
|
-
process.exit(1);
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
let runs: RunRecord[] = [];
|
|
137
|
-
let degradedRuns: { runId: string; error: string; rawRow: Record<string, unknown> }[] = [];
|
|
138
|
-
let isDegraded = false;
|
|
139
|
-
let malformedError: MalformedRunError | null = null;
|
|
140
|
-
|
|
141
|
-
try {
|
|
142
|
-
runs = await stateManager.getRunsByTask(opts.id);
|
|
143
|
-
} catch (err: unknown) {
|
|
144
|
-
if (err instanceof MalformedRunError) {
|
|
145
|
-
const { validRuns, degradedRuns: malformedRuns } = err;
|
|
146
|
-
runs = validRuns;
|
|
147
|
-
degradedRuns = malformedRuns;
|
|
148
|
-
isDegraded = true;
|
|
149
|
-
malformedError = err;
|
|
150
|
-
} else {
|
|
151
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
152
|
-
if (opts.json) {
|
|
153
|
-
console.log(JSON.stringify({
|
|
154
|
-
ok: false,
|
|
155
|
-
reason: errorMsg,
|
|
156
|
-
nextAction: 'Check state.db connection and schema integrity',
|
|
157
|
-
}, null, 2));
|
|
158
|
-
} else {
|
|
159
|
-
console.error(`Error: ${errorMsg}`);
|
|
160
|
-
}
|
|
161
|
-
process.exit(1);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (opts.json) {
|
|
167
|
-
if (isDegraded) {
|
|
168
|
-
console.log(JSON.stringify({
|
|
169
|
-
ok: false,
|
|
170
|
-
task,
|
|
171
|
-
runs,
|
|
172
|
-
degradedRuns: degradedRuns.map(dr => ({
|
|
173
|
-
runId: dr.runId,
|
|
174
|
-
error: dr.error,
|
|
175
|
-
})),
|
|
176
|
-
reason: malformedError?.message ?? 'Unknown malformed run schema',
|
|
177
|
-
nextAction: 'Malformed run rows are visible here but not auto-repaired. Runner execution tolerates them (uses the latest valid run). To quarantine malformed rows: pd runtime internalization integrity-repair --confirm --json',
|
|
178
|
-
}, null, 2));
|
|
179
|
-
process.exitCode = 1;
|
|
180
|
-
} else {
|
|
181
|
-
console.log(JSON.stringify({ task, runs }, null, 2));
|
|
182
|
-
}
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
console.log(`\nTask: ${task.taskId}\n`);
|
|
187
|
-
console.log(` Kind: ${task.taskKind}`);
|
|
188
|
-
console.log(` Status: ${task.status}`);
|
|
189
|
-
console.log(` Attempts: ${task.attemptCount} / ${task.maxAttempts}`);
|
|
190
|
-
if (task.leaseOwner) {
|
|
191
|
-
console.log(` Lease Owner: ${task.leaseOwner}`);
|
|
192
|
-
console.log(` Lease Expires: ${task.leaseExpiresAt ? new Date(task.leaseExpiresAt).toLocaleString() : '-'}`);
|
|
193
|
-
}
|
|
194
|
-
if (task.lastError) {
|
|
195
|
-
console.log(` Last Error: ${task.lastError}`);
|
|
196
|
-
}
|
|
197
|
-
if (task.inputRef) {
|
|
198
|
-
console.log(` Input Ref: ${task.inputRef}`);
|
|
199
|
-
}
|
|
200
|
-
if (task.resultRef) {
|
|
201
|
-
console.log(` Result Ref: ${task.resultRef}`);
|
|
202
|
-
}
|
|
203
|
-
console.log(` Created: ${new Date(task.createdAt).toLocaleString()}`);
|
|
204
|
-
console.log(` Updated: ${new Date(task.updatedAt).toLocaleString()}`);
|
|
205
|
-
console.log('');
|
|
206
|
-
|
|
207
|
-
if (runs.length > 0) {
|
|
208
|
-
console.log(`Runs (${runs.length}):`);
|
|
209
|
-
console.log(' %-22s %-12s %-6s %s', 'RUN_ID', 'STATUS', 'ATT', 'STARTED');
|
|
210
|
-
console.log(' ' + '-'.repeat(65));
|
|
211
|
-
for (const run of runs) {
|
|
212
|
-
console.log(
|
|
213
|
-
' %-22s %-12s %-6s %s',
|
|
214
|
-
run.runId.substring(0, 22),
|
|
215
|
-
run.executionStatus,
|
|
216
|
-
run.attemptNumber,
|
|
217
|
-
new Date(run.startedAt).toLocaleString(),
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
console.log('');
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (isDegraded && degradedRuns.length > 0) {
|
|
224
|
-
console.warn(`WARNING: Task has ${degradedRuns.length} malformed run(s) in database!`);
|
|
225
|
-
console.warn(`Reason: ${malformedError?.message ?? 'Unknown malformed run schema'}`);
|
|
226
|
-
console.warn(`nextAction: Malformed run rows are visible here but not auto-repaired. Runner execution tolerates them (uses the latest valid run). To quarantine malformed rows: pd runtime internalization integrity-repair --confirm --json\n`);
|
|
227
|
-
console.log('Degraded Runs:');
|
|
228
|
-
for (const dr of degradedRuns) {
|
|
229
|
-
console.log(` - Run: ${dr.runId}`);
|
|
230
|
-
console.log(` Error: ${dr.error}`);
|
|
231
|
-
}
|
|
232
|
-
console.log('');
|
|
233
|
-
process.exitCode = 1;
|
|
234
|
-
}
|
|
235
|
-
} catch (err: unknown) {
|
|
236
|
-
if (opts.json) {
|
|
237
|
-
console.log(JSON.stringify({
|
|
238
|
-
ok: false,
|
|
239
|
-
reason: err instanceof Error ? err.message : String(err),
|
|
240
|
-
nextAction: 'Check workspace path and task ID',
|
|
241
|
-
}, null, 2));
|
|
242
|
-
} else {
|
|
243
|
-
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
244
|
-
}
|
|
245
|
-
process.exitCode = 1;
|
|
246
|
-
} finally {
|
|
247
|
-
await stateManager.close();
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Register the `pd task list` subcommand.
|
|
253
|
-
*
|
|
254
|
-
* Single source of truth for both production (`index.ts`) and parser tests
|
|
255
|
-
* (mvp-smoke.test.ts). Reuses the `withWorkspaceAndJson` helper so adding a
|
|
256
|
-
* new --workspace/--json pair elsewhere is one line, not five.
|
|
257
|
-
*/
|
|
258
|
-
export function registerTaskListCommand(taskCmd: Command): Command {
|
|
259
|
-
const listCmd = taskCmd
|
|
260
|
-
.command('list')
|
|
261
|
-
.description('List runtime tasks')
|
|
262
|
-
.option('-s, --status <status>', 'Filter by status (pending, leased, retry_wait, succeeded, failed)')
|
|
263
|
-
.option('-k, --kind <kind>', 'Filter by task kind')
|
|
264
|
-
.option('-l, --limit <number>', 'Limit number of results', parseInt, 50)
|
|
265
|
-
.action(async (opts: { status?: string; kind?: string; limit?: number; workspace?: string; json?: boolean }) => {
|
|
266
|
-
await handleTaskList({ status: opts.status, kind: opts.kind, limit: opts.limit, workspace: opts.workspace, json: opts.json });
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
withWorkspaceAndJson(listCmd);
|
|
270
|
-
return listCmd;
|
|
271
|
-
}
|
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pd telemetry — Anonymous Product Telemetry v1 control plane
|
|
3
|
-
* (PRI-597, SPEC §40-§43).
|
|
4
|
-
*
|
|
5
|
-
* Consent lives at the machine level (~/.pd/product-telemetry.json via
|
|
6
|
-
* host-runtime); measurement (daily ID, dedup, retry, lock) is
|
|
7
|
-
* workspace-scoped. The release feature flag (anonymous_product_telemetry)
|
|
8
|
-
* is an INDEPENDENT gate read from the resolved workspace's .pd/config.yaml.
|
|
9
|
-
*
|
|
10
|
-
* Commands:
|
|
11
|
-
* pd telemetry status — gates, consent, eligibility, bounded export status
|
|
12
|
-
* pd telemetry enable — explicit consent (default dry-run; --confirm to write)
|
|
13
|
-
* pd telemetry disable — deny consent + delete local identity (default dry-run)
|
|
14
|
-
* pd telemetry reset — rotate/delete identity (default dry-run)
|
|
15
|
-
* pd telemetry preview — exact outbound payload; never sends
|
|
16
|
-
*
|
|
17
|
-
* --json outputs exactly one parseable object; failures carry reason +
|
|
18
|
-
* nextAction; the telemetry secret is never printed.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
import * as path from 'path';
|
|
22
|
-
import type { Command } from 'commander';
|
|
23
|
-
import {
|
|
24
|
-
createProductTelemetryService,
|
|
25
|
-
PREVIEW_BANNER,
|
|
26
|
-
type ProductTelemetryStatusView,
|
|
27
|
-
} from '@principles/host-runtime';
|
|
28
|
-
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
29
|
-
import { emitError, emitFlagConflict, emitResult } from '../services/cli-output.js';
|
|
30
|
-
|
|
31
|
-
// ── Output types ─────────────────────────────────────────────────────────────
|
|
32
|
-
|
|
33
|
-
export interface TelemetryStatusOutput {
|
|
34
|
-
status: 'ok' | 'degraded' | 'failed';
|
|
35
|
-
command: 'telemetry:status';
|
|
36
|
-
consent: string;
|
|
37
|
-
consentVersion: string;
|
|
38
|
-
hasSecret: boolean;
|
|
39
|
-
flagEnabled: boolean | null;
|
|
40
|
-
flagSource: string | null;
|
|
41
|
-
environmentSuppressed: boolean;
|
|
42
|
-
suppressionReasons: string[];
|
|
43
|
-
canExport: boolean;
|
|
44
|
-
blockers: string[];
|
|
45
|
-
lastAttemptedAt?: string;
|
|
46
|
-
lastSucceededAt?: string;
|
|
47
|
-
lastFailureCode?: string;
|
|
48
|
-
nextRetryAt?: string;
|
|
49
|
-
endpoint: string;
|
|
50
|
-
workspaceDir?: string;
|
|
51
|
-
nextAction?: string;
|
|
52
|
-
reason?: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface TelemetryMutationOutput {
|
|
56
|
-
status: 'ok' | 'failed';
|
|
57
|
-
command: 'telemetry:enable' | 'telemetry:disable' | 'telemetry:reset';
|
|
58
|
-
dryRun: boolean;
|
|
59
|
-
applied: boolean;
|
|
60
|
-
consent?: string;
|
|
61
|
-
/** What the applied/dry-run mutation changes, in plain terms. */
|
|
62
|
-
effect: string;
|
|
63
|
-
reason?: string;
|
|
64
|
-
nextAction?: string;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface TelemetryPreviewOutput {
|
|
68
|
-
status: 'ok';
|
|
69
|
-
command: 'telemetry:preview';
|
|
70
|
-
banner: string;
|
|
71
|
-
snapshot: Record<string, unknown>;
|
|
72
|
-
gates: {
|
|
73
|
-
flagEnabled: boolean | null;
|
|
74
|
-
consent: string;
|
|
75
|
-
environmentSuppressed: boolean;
|
|
76
|
-
suppressionReasons: string[];
|
|
77
|
-
canExport: boolean;
|
|
78
|
-
blockers: string[];
|
|
79
|
-
};
|
|
80
|
-
notes: string[];
|
|
81
|
-
secretEphemeral: boolean;
|
|
82
|
-
nextAction?: string;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// ── Text formatting ──────────────────────────────────────────────────────────
|
|
86
|
-
|
|
87
|
-
function formatStatusText(output: TelemetryStatusOutput): string {
|
|
88
|
-
const lines: string[] = [];
|
|
89
|
-
lines.push('PD Anonymous Product Telemetry');
|
|
90
|
-
lines.push(`consent: ${output.consent} (v${output.consentVersion})`);
|
|
91
|
-
lines.push(`feature flag: ${output.flagEnabled === null ? 'unknown (no workspace)' : output.flagEnabled ? 'on' : 'off'}${output.flagSource ? ` (${output.flagSource})` : ''}`);
|
|
92
|
-
lines.push(`environment: ${output.environmentSuppressed ? `suppressed (${output.suppressionReasons.join(', ')})` : 'eligible'}`);
|
|
93
|
-
lines.push(`can export: ${output.canExport ? 'yes' : `no (${output.blockers.join(', ')})`}`);
|
|
94
|
-
lines.push(`local secret: ${output.hasSecret ? 'present' : 'absent'}`);
|
|
95
|
-
if (output.lastAttemptedAt) lines.push(`last attempted: ${output.lastAttemptedAt}`);
|
|
96
|
-
if (output.lastSucceededAt) lines.push(`last succeeded: ${output.lastSucceededAt}`);
|
|
97
|
-
if (output.lastFailureCode) lines.push(`last failure: ${output.lastFailureCode}`);
|
|
98
|
-
if (output.nextRetryAt) lines.push(`next retry: ${output.nextRetryAt}`);
|
|
99
|
-
lines.push(`collector: ${output.endpoint}`);
|
|
100
|
-
lines.push('');
|
|
101
|
-
lines.push('Collects: PD version, anonymous tri-state milestones (true/false/unavailable), coarse reliability.');
|
|
102
|
-
lines.push('Never collects: conversations, code/files, Principle content, Pain content.');
|
|
103
|
-
if (output.nextAction) lines.push(`Next action: ${output.nextAction}`);
|
|
104
|
-
return lines.join('\n');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function formatMutationText(output: TelemetryMutationOutput): string {
|
|
108
|
-
const lines: string[] = [];
|
|
109
|
-
lines.push(`PD telemetry ${output.command.split(':')[1]} ${output.applied ? 'applied' : '(dry-run — not applied)'}`);
|
|
110
|
-
lines.push(output.effect);
|
|
111
|
-
if (!output.applied) lines.push('Re-run with --confirm to apply.');
|
|
112
|
-
if (output.nextAction) lines.push(`Next action: ${output.nextAction}`);
|
|
113
|
-
return lines.join('\n');
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function formatPreviewText(output: TelemetryPreviewOutput): string {
|
|
117
|
-
const lines: string[] = [];
|
|
118
|
-
lines.push(output.secretEphemeral
|
|
119
|
-
? 'PD Telemetry Preview — exact payload shape (dailyTelemetryId is provisional until enabled)'
|
|
120
|
-
: 'PD Telemetry Preview — exact outbound payload');
|
|
121
|
-
lines.push('');
|
|
122
|
-
lines.push(JSON.stringify(output.snapshot, null, 2));
|
|
123
|
-
lines.push('');
|
|
124
|
-
lines.push(`Collected: PD version, anonymous tri-state milestones (true/false/unavailable), coarse reliability.`);
|
|
125
|
-
lines.push(`Never collected: conversations, code/files, Principle content, Pain content.`);
|
|
126
|
-
lines.push(`Gates: flag=${output.gates.flagEnabled ?? 'unresolved'} consent=${output.gates.consent} environment=${output.gates.environmentSuppressed ? 'suppressed' : 'eligible'} → wouldExport=${output.gates.canExport}`);
|
|
127
|
-
if (output.notes.length > 0) {
|
|
128
|
-
lines.push('Notes:');
|
|
129
|
-
for (const note of output.notes) lines.push(` [!] ${note}`);
|
|
130
|
-
}
|
|
131
|
-
lines.push('');
|
|
132
|
-
lines.push(`>>> ${PREVIEW_BANNER}`);
|
|
133
|
-
return lines.join('\n');
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// ── Shared helpers ───────────────────────────────────────────────────────────
|
|
137
|
-
|
|
138
|
-
interface TelemetryOptions {
|
|
139
|
-
workspace?: string;
|
|
140
|
-
json?: boolean;
|
|
141
|
-
confirm?: boolean;
|
|
142
|
-
dryRun?: boolean;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function resolveWorkspaceOrNull(opts: TelemetryOptions): string | undefined {
|
|
146
|
-
if (opts.workspace) return path.resolve(opts.workspace);
|
|
147
|
-
try {
|
|
148
|
-
return resolveWorkspaceDir();
|
|
149
|
-
} catch {
|
|
150
|
-
// Consent/identity commands are machine-scope; a workspace is only needed
|
|
151
|
-
// to report the workspace-scope flag gate. Absent workspace = flag unknown.
|
|
152
|
-
return undefined;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function makeService() {
|
|
157
|
-
return createProductTelemetryService({});
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function checkDryRunConfirmMutex(opts: TelemetryOptions, json: boolean): boolean {
|
|
161
|
-
if (opts.dryRun === true && opts.confirm === true) {
|
|
162
|
-
process.exitCode = emitFlagConflict({ json });
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
return true;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// ── Handlers ─────────────────────────────────────────────────────────────────
|
|
169
|
-
|
|
170
|
-
export async function handleTelemetryStatus(opts: TelemetryOptions): Promise<void> {
|
|
171
|
-
const service = makeService();
|
|
172
|
-
const workspaceDir = resolveWorkspaceOrNull(opts);
|
|
173
|
-
const result = service.getStatus(workspaceDir);
|
|
174
|
-
if (!result.ok) {
|
|
175
|
-
process.exitCode = emitError(new Error(result.reason), { json: opts.json ?? false, nextAction: result.nextAction });
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
const view: ProductTelemetryStatusView = result.view;
|
|
179
|
-
const output: TelemetryStatusOutput = {
|
|
180
|
-
status: 'ok',
|
|
181
|
-
command: 'telemetry:status',
|
|
182
|
-
consent: view.consent,
|
|
183
|
-
consentVersion: view.consentVersion,
|
|
184
|
-
hasSecret: view.hasSecret,
|
|
185
|
-
flagEnabled: view.flagEnabled,
|
|
186
|
-
flagSource: view.flagSource,
|
|
187
|
-
environmentSuppressed: view.environmentSuppressed,
|
|
188
|
-
suppressionReasons: view.suppressionReasons,
|
|
189
|
-
canExport: view.canExport,
|
|
190
|
-
blockers: view.blockers,
|
|
191
|
-
...(view.lastAttemptedAt !== undefined ? { lastAttemptedAt: view.lastAttemptedAt } : {}),
|
|
192
|
-
...(view.lastSucceededAt !== undefined ? { lastSucceededAt: view.lastSucceededAt } : {}),
|
|
193
|
-
...(view.lastFailureCode !== undefined ? { lastFailureCode: view.lastFailureCode } : {}),
|
|
194
|
-
...(view.nextRetryAt !== undefined ? { nextRetryAt: view.nextRetryAt } : {}),
|
|
195
|
-
endpoint: view.endpoint,
|
|
196
|
-
...(workspaceDir !== undefined ? { workspaceDir } : {}),
|
|
197
|
-
...(view.nextAction !== undefined ? { nextAction: view.nextAction } : {}),
|
|
198
|
-
};
|
|
199
|
-
emitResult(output, { json: opts.json ?? false, formatText: formatStatusText });
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
type MutationKind = 'enable' | 'disable' | 'reset';
|
|
203
|
-
|
|
204
|
-
const MUTATION_EFFECTS: Record<MutationKind, string> = {
|
|
205
|
-
enable: 'Records explicit telemetry consent (granted) and creates a local random secret for daily unlinkable IDs. Nothing is exported unless the feature flag and environment eligibility also allow it.',
|
|
206
|
-
disable: 'Records consent denied and deletes the local telemetry secret and export status. Future telemetry export requests: 0.',
|
|
207
|
-
reset: 'Deletes the local telemetry secret and export status. If consent remains granted, a fresh secret is generated — future daily IDs are unrelated to previous ones.',
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
const MUTATION_NEXT_ACTIONS: Record<MutationKind, string> = {
|
|
211
|
-
enable: 'Run "pd telemetry preview" to inspect the exact outbound payload.',
|
|
212
|
-
disable: 'Telemetry is fully off. Re-enable anytime with "pd telemetry enable --confirm".',
|
|
213
|
-
reset: 'Previous daily IDs can no longer be derived. See "pd telemetry status".',
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
export async function handleTelemetryMutation(kind: MutationKind, opts: TelemetryOptions): Promise<void> {
|
|
217
|
-
const json = opts.json ?? false;
|
|
218
|
-
if (!checkDryRunConfirmMutex(opts, json)) return;
|
|
219
|
-
const applied = opts.confirm === true;
|
|
220
|
-
const service = makeService();
|
|
221
|
-
|
|
222
|
-
if (!applied) {
|
|
223
|
-
const output: TelemetryMutationOutput = {
|
|
224
|
-
status: 'ok',
|
|
225
|
-
command: `telemetry:${kind}`,
|
|
226
|
-
dryRun: true,
|
|
227
|
-
applied: false,
|
|
228
|
-
effect: MUTATION_EFFECTS[kind],
|
|
229
|
-
nextAction: 'Re-run with --confirm to apply.',
|
|
230
|
-
};
|
|
231
|
-
emitResult(output, { json, formatText: formatMutationText });
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const result =
|
|
236
|
-
kind === 'enable' ? service.enable() : kind === 'disable' ? service.disable() : service.reset();
|
|
237
|
-
if (!result.ok) {
|
|
238
|
-
process.exitCode = emitError(new Error(result.reason), { json, nextAction: result.nextAction });
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
const output: TelemetryMutationOutput = {
|
|
242
|
-
status: 'ok',
|
|
243
|
-
command: `telemetry:${kind}`,
|
|
244
|
-
dryRun: false,
|
|
245
|
-
applied: true,
|
|
246
|
-
consent: result.consent,
|
|
247
|
-
effect: MUTATION_EFFECTS[kind],
|
|
248
|
-
nextAction: MUTATION_NEXT_ACTIONS[kind],
|
|
249
|
-
};
|
|
250
|
-
emitResult(output, { json, formatText: formatMutationText });
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
export async function handleTelemetryPreview(opts: TelemetryOptions): Promise<void> {
|
|
254
|
-
let workspaceDir: string;
|
|
255
|
-
if (opts.workspace) {
|
|
256
|
-
workspaceDir = path.resolve(opts.workspace);
|
|
257
|
-
} else {
|
|
258
|
-
try {
|
|
259
|
-
workspaceDir = resolveWorkspaceDir();
|
|
260
|
-
} catch (error) {
|
|
261
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
262
|
-
process.exitCode = emitError(new Error(`workspace_unresolvable: ${message}`), {
|
|
263
|
-
json: opts.json ?? false,
|
|
264
|
-
nextAction: 'Pass --workspace <path> or run from a PD workspace',
|
|
265
|
-
});
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
const service = makeService();
|
|
270
|
-
const preview = service.preview(workspaceDir);
|
|
271
|
-
const output: TelemetryPreviewOutput = {
|
|
272
|
-
status: 'ok',
|
|
273
|
-
command: 'telemetry:preview',
|
|
274
|
-
banner: PREVIEW_BANNER,
|
|
275
|
-
snapshot: preview.snapshot,
|
|
276
|
-
gates: {
|
|
277
|
-
flagEnabled: preview.gates.flagEnabled,
|
|
278
|
-
consent: preview.gates.consent,
|
|
279
|
-
environmentSuppressed: preview.gates.environmentSuppressed,
|
|
280
|
-
suppressionReasons: preview.gates.suppressionReasons,
|
|
281
|
-
canExport: preview.gates.canExport,
|
|
282
|
-
blockers: preview.gates.blockers,
|
|
283
|
-
},
|
|
284
|
-
notes: preview.notes,
|
|
285
|
-
secretEphemeral: preview.secretEphemeral,
|
|
286
|
-
};
|
|
287
|
-
emitResult(output, { json: opts.json ?? false, formatText: formatPreviewText });
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// ── Registration (used by index.ts and wiring tests) ─────────────────────────
|
|
291
|
-
|
|
292
|
-
export function registerTelemetryCommand(parent: Command): Command {
|
|
293
|
-
const telemetry = parent
|
|
294
|
-
.command('telemetry')
|
|
295
|
-
.description('Anonymous product telemetry control (opt-in, privacy-preserving)');
|
|
296
|
-
|
|
297
|
-
telemetry
|
|
298
|
-
.command('status')
|
|
299
|
-
.description('Show telemetry consent, gates, eligibility, and bounded export status')
|
|
300
|
-
.option('-w, --workspace <path>', 'Workspace directory (for the feature-flag gate)')
|
|
301
|
-
.option('--json', 'Output raw JSON')
|
|
302
|
-
.action(async (opts) => {
|
|
303
|
-
await handleTelemetryStatus({ workspace: opts.workspace, json: opts.json });
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
telemetry
|
|
307
|
-
.command('enable')
|
|
308
|
-
.description('Grant explicit telemetry consent (default OFF until enabled)')
|
|
309
|
-
.option('--dry-run', 'Show the effect without writing (default)')
|
|
310
|
-
.option('--confirm', 'Apply the consent change (required to write)')
|
|
311
|
-
.option('-w, --workspace <path>', 'Workspace directory (reporting only)')
|
|
312
|
-
.option('--json', 'Output raw JSON')
|
|
313
|
-
.action(async (opts) => {
|
|
314
|
-
await handleTelemetryMutation('enable', { workspace: opts.workspace, json: opts.json, confirm: opts.confirm, dryRun: opts.dryRun });
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
telemetry
|
|
318
|
-
.command('disable')
|
|
319
|
-
.description('Deny consent and delete the local telemetry identity (zero future exports)')
|
|
320
|
-
.option('--dry-run', 'Show the effect without writing (default)')
|
|
321
|
-
.option('--confirm', 'Apply the change (required to write)')
|
|
322
|
-
.option('-w, --workspace <path>', 'Workspace directory (reporting only)')
|
|
323
|
-
.option('--json', 'Output raw JSON')
|
|
324
|
-
.action(async (opts) => {
|
|
325
|
-
await handleTelemetryMutation('disable', { workspace: opts.workspace, json: opts.json, confirm: opts.confirm, dryRun: opts.dryRun });
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
telemetry
|
|
329
|
-
.command('reset')
|
|
330
|
-
.description('Delete and rotate the local telemetry identity (unlink from previous daily IDs)')
|
|
331
|
-
.option('--dry-run', 'Show the effect without writing (default)')
|
|
332
|
-
.option('--confirm', 'Apply the change (required to write)')
|
|
333
|
-
.option('-w, --workspace <path>', 'Workspace directory (reporting only)')
|
|
334
|
-
.option('--json', 'Output raw JSON')
|
|
335
|
-
.action(async (opts) => {
|
|
336
|
-
await handleTelemetryMutation('reset', { workspace: opts.workspace, json: opts.json, confirm: opts.confirm, dryRun: opts.dryRun });
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
telemetry
|
|
340
|
-
.command('preview')
|
|
341
|
-
.description('Show the exact outbound telemetry payload (nothing is sent)')
|
|
342
|
-
.option('-w, --workspace <path>', 'Workspace directory')
|
|
343
|
-
.option('--json', 'Output raw JSON')
|
|
344
|
-
.action(async (opts) => {
|
|
345
|
-
await handleTelemetryPreview({ workspace: opts.workspace, json: opts.json });
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
return telemetry;
|
|
349
|
-
}
|