@principles/pd-cli 1.92.0 → 1.94.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.
@@ -5,10 +5,11 @@
5
5
  */
6
6
  import { describe, it, expect } from 'vitest';
7
7
  import { execFileSync } from 'node:child_process';
8
+ import { getBuiltPdCliPath } from '../helpers/pd-cli-path.js';
8
9
 
9
10
  function runPdHelp(args: string[]): string {
10
11
  try {
11
- return execFileSync('node', ['packages/pd-cli/dist/index.js', ...args], {
12
+ return execFileSync('node', [getBuiltPdCliPath(), ...args], {
12
13
  encoding: 'utf8',
13
14
  cwd: process.cwd(),
14
15
  });
@@ -21,6 +21,7 @@ import * as path from 'node:path';
21
21
  import { execFileSync } from 'node:child_process';
22
22
  import * as childProcessModule from 'node:child_process';
23
23
  import { EventEmitter } from 'node:events';
24
+ import { getBuiltPdCliPath } from '../helpers/pd-cli-path.js';
24
25
  import {
25
26
  isLoopbackHost,
26
27
  normalizeLoopbackHost,
@@ -757,9 +758,18 @@ describe('CLI command wiring (pd console open)', () => {
757
758
 
758
759
  function runPd(args: string[], cwd: string): string {
759
760
  try {
760
- return execFileSync('node', ['packages/pd-cli/dist/index.js', ...args], {
761
+ const env: Record<string, string> = { ...process.env };
762
+ if (!args.includes('--workspace') && !args.includes('--help') && !args.includes('-h')) {
763
+ env.USERPROFILE = '/nonexistent';
764
+ env.HOME = '/nonexistent';
765
+ env.HOMEPATH = '/nonexistent';
766
+ env.HOMEDRIVE = '/nonexistent';
767
+ delete env.PD_WORKSPACE_DIR;
768
+ }
769
+ return execFileSync('node', [getBuiltPdCliPath(), ...args], {
761
770
  encoding: 'utf8',
762
771
  cwd,
772
+ env,
763
773
  });
764
774
  } catch (err: unknown) {
765
775
  if (err && typeof err === 'object' && Object.hasOwn(err, 'stdout')) {
@@ -57,11 +57,17 @@ vi.mock('@principles/core/runtime-v2', () => {
57
57
  SqliteSourceTraceLocator: vi.fn().mockImplementation(function () { return {}; }),
58
58
  StoreEventEmitter: vi.fn().mockImplementation(function () { return {}; }),
59
59
  storeEmitter: { emitTelemetry: vi.fn() },
60
- DiagnosticianRunner: vi.fn().mockImplementation(function () { return {}; }),
61
- PassThroughValidator: vi.fn().mockImplementation(function () { return {}; }),
62
- DefaultDiagnosticianValidator: vi.fn().mockImplementation(function () { return {}; }),
60
+ SplitDiagnosticianRunner: vi.fn().mockImplementation(function () { return {}; }),
61
+ DiagRootCauseRunner: vi.fn().mockImplementation(function () { return {}; }),
62
+ DiagDistillerRunner: vi.fn().mockImplementation(function () { return {}; }),
63
+ DiagRouterRunner: vi.fn().mockImplementation(function () { return {}; }),
64
+ DefaultDiagRootCauseValidator: vi.fn().mockImplementation(function () { return {}; }),
65
+ DefaultDiagDistillerValidator: vi.fn().mockImplementation(function () { return {}; }),
66
+ DisabledDiagnosticianRunner: vi.fn().mockImplementation(function () { return {}; }),
63
67
  TestDoubleRuntimeAdapter: vi.fn().mockImplementation(function () { return {}; }),
64
68
  OpenClawCliRuntimeAdapter: vi.fn().mockImplementation(function () { return {}; }),
69
+ PiAiRuntimeAdapter: vi.fn().mockImplementation(function () { return {}; }),
70
+ SPLIT_PIPELINE_TOTAL_TIMEOUT_MS: 300000,
65
71
  PDRuntimeError: class PDRuntimeError extends Error {
66
72
  constructor(public category: string, message: string) {
67
73
  super(message);
@@ -78,7 +84,12 @@ vi.mock('@principles/core/runtime-v2', () => {
78
84
  agentId: 'main',
79
85
  }),
80
86
  isRuntimeConfigError: vi.fn().mockReturnValue(false),
87
+ isFeatureEnabled: vi.fn().mockReturnValue(true),
81
88
  resolveOutputLanguage: vi.fn().mockReturnValue({ outputLanguage: 'zh-CN' }),
89
+ validatePdConfig: vi.fn().mockReturnValue({ valid: true, errors: [] }),
90
+ computeEffectivePdConfig: vi.fn().mockReturnValue({ config: {}, source: 'defaults', warnings: [] }),
91
+ computeFeatureFlagsFromConfig: vi.fn().mockReturnValue({}),
92
+ redactPdConfig: vi.fn().mockImplementation((c) => c),
82
93
  run: vi.fn().mockResolvedValue({
83
94
  status: 'succeeded',
84
95
  taskId: 'test-task-1',
@@ -106,6 +117,11 @@ vi.mock('../../src/config-reader.js', () => ({
106
117
  readOutputLanguageFromWorkspace: vi.fn().mockReturnValue({ outputLanguage: 'zh-CN' }),
107
118
  }));
108
119
 
120
+ vi.mock('../../src/services/pd-config-loader.js', () => ({
121
+ loadPdConfig: vi.fn().mockReturnValue({ ok: true, effective: { config: {}, source: 'defaults', warnings: [] } }),
122
+ computeFlagsFromLoadResult: vi.fn().mockReturnValue({}),
123
+ }));
124
+
109
125
  import { handleDiagnoseRun, type DiagnoseRunOptions } from '../../src/commands/diagnose.js';
110
126
 
111
127
  const SUCCEEDED_RESULT = {
@@ -89,11 +89,17 @@ vi.mock('@principles/core/runtime-v2', () => {
89
89
  SqliteSourceTraceLocator: vi.fn().mockImplementation(function () { return {}; }),
90
90
  StoreEventEmitter: vi.fn().mockImplementation(function () { return {}; }),
91
91
  storeEmitter: { emitTelemetry: vi.fn() },
92
- DiagnosticianRunner: vi.fn().mockImplementation(function () { return {}; }),
93
- DefaultDiagnosticianValidator: vi.fn().mockImplementation(function () { return {}; }),
92
+ SplitDiagnosticianRunner: vi.fn().mockImplementation(function () { return {}; }),
93
+ DiagRootCauseRunner: vi.fn().mockImplementation(function () { return {}; }),
94
+ DiagDistillerRunner: vi.fn().mockImplementation(function () { return {}; }),
95
+ DiagRouterRunner: vi.fn().mockImplementation(function () { return {}; }),
96
+ DefaultDiagRootCauseValidator: vi.fn().mockImplementation(function () { return {}; }),
97
+ DefaultDiagDistillerValidator: vi.fn().mockImplementation(function () { return {}; }),
98
+ DisabledDiagnosticianRunner: vi.fn().mockImplementation(function () { return {}; }),
94
99
  TestDoubleRuntimeAdapter: vi.fn().mockImplementation(function () { return {}; }),
95
100
  OpenClawCliRuntimeAdapter: vi.fn().mockImplementation(function () { return {}; }),
96
101
  PiAiRuntimeAdapter: vi.fn().mockImplementation(function () { return {}; }),
102
+ SPLIT_PIPELINE_TOTAL_TIMEOUT_MS: 300000,
97
103
  PDRuntimeError: class PDRuntimeError extends Error {
98
104
  constructor(public category: string, message: string) {
99
105
  super(message);
@@ -103,7 +109,12 @@ vi.mock('@principles/core/runtime-v2', () => {
103
109
  CandidateIntakeService: MockCandidateIntakeService,
104
110
  resolveRuntimeConfig: mockResolveRuntimeConfig,
105
111
  isRuntimeConfigError: vi.fn().mockReturnValue(false),
112
+ isFeatureEnabled: vi.fn().mockReturnValue(true),
106
113
  resolveOutputLanguage: vi.fn().mockReturnValue({ outputLanguage: 'zh-CN' }),
114
+ validatePdConfig: vi.fn().mockReturnValue({ valid: true, errors: [] }),
115
+ computeEffectivePdConfig: vi.fn().mockReturnValue({ config: {}, source: 'defaults', warnings: [] }),
116
+ computeFeatureFlagsFromConfig: vi.fn().mockReturnValue({}),
117
+ redactPdConfig: vi.fn().mockImplementation((c) => c),
107
118
  run: mockRun,
108
119
  status: vi.fn(),
109
120
  };
@@ -6,12 +6,13 @@
6
6
  */
7
7
  import { describe, it, expect } from 'vitest';
8
8
  import { execFileSync } from 'node:child_process';
9
+ import { getBuiltPdCliPath } from '../helpers/pd-cli-path.js';
9
10
 
10
11
  function runPdHelp(args: string[]): string {
11
12
  try {
12
- return execFileSync('node', ['packages/pd-cli/dist/index.js', ...args], {
13
+ return execFileSync('node', [getBuiltPdCliPath(), ...args], {
13
14
  encoding: 'utf8',
14
- cwd: 'D:/Code/principles',
15
+ cwd: process.cwd(),
15
16
  });
16
17
  } catch (err: unknown) {
17
18
  if (err && typeof err === 'object' && 'stdout' in err) {
@@ -4,11 +4,12 @@ import { mkdtempSync, rmSync, existsSync, readFileSync, mkdirSync } from 'fs';
4
4
  import { join } from 'path';
5
5
  import { tmpdir } from 'os';
6
6
  import Database from 'better-sqlite3';
7
+ import { getBuiltPdCliPath } from '../helpers/pd-cli-path.js';
7
8
 
8
9
  describe('E2E: pd candidate intake flow', () => {
9
10
  let tempWorkspace: string;
10
11
  let db: Database.Database;
11
- const pdCliPath = join(process.cwd(), 'dist/index.js');
12
+ const pdCliPath = getBuiltPdCliPath();
12
13
 
13
14
  beforeEach(() => {
14
15
  tempWorkspace = mkdtempSync(join(tmpdir(), 'pd-e2e-'));
@@ -148,12 +149,33 @@ describe('E2E: pd candidate intake flow', () => {
148
149
  }
149
150
  }
150
151
 
151
- function readLedgerFile(workspace: string): any[] {
152
- const ledgerPath = join(workspace, '.pd', 'principle-tree-ledger.json');
152
+ function readLedgerFile(workspace: string): Array<{ id: string; sourceRef: string; status: string; evaluability: string }> {
153
+ const ledgerPath = join(workspace, '.state', 'principle_training_state.json');
153
154
  if (!existsSync(ledgerPath)) return [];
154
155
  const content = readFileSync(ledgerPath, 'utf-8');
155
- const data = JSON.parse(content);
156
- return data.principles || [];
156
+ const data: unknown = JSON.parse(content);
157
+ if (typeof data !== 'object' || data === null) return [];
158
+ const tree = (data as Record<string, unknown>)._tree ?? (data as Record<string, unknown>).tree ?? {};
159
+ if (typeof tree !== 'object' || tree === null) return [];
160
+ const principles = (tree as Record<string, unknown>).principles ?? {};
161
+ if (typeof principles !== 'object' || principles === null) return [];
162
+ return Object.values(principles).map((p: unknown) => {
163
+ if (typeof p !== 'object' || p === null) {
164
+ return { id: '', sourceRef: 'candidate://', status: '', evaluability: '' };
165
+ }
166
+ const pObj = p as Record<string, unknown>;
167
+ const painIds = pObj.derivedFromPainIds;
168
+ const candidateId = Array.isArray(painIds) && typeof painIds[0] === 'string' ? painIds[0] : '';
169
+ const id = typeof pObj.id === 'string' ? pObj.id : '';
170
+ const rawStatus = typeof pObj.status === 'string' ? pObj.status : '';
171
+ const evaluability = typeof pObj.evaluability === 'string' ? pObj.evaluability : '';
172
+ return {
173
+ id,
174
+ sourceRef: `candidate://${candidateId}`,
175
+ status: rawStatus === 'candidate' ? 'probation' : rawStatus,
176
+ evaluability,
177
+ };
178
+ });
157
179
  }
158
180
 
159
181
  it('Test 1 (Happy path E2E): pending candidate → intake → consumed → ledgerEntryId in output', () => {
@@ -0,0 +1,5 @@
1
+ import { join } from 'node:path';
2
+
3
+ export function getBuiltPdCliPath(): string {
4
+ return join(process.cwd(), 'dist', 'index.js');
5
+ }
@@ -1,9 +1,10 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
  import { execFileSync } from 'node:child_process';
3
+ import { getBuiltPdCliPath } from './helpers/pd-cli-path.js';
3
4
 
4
5
  describe('PD CLI Smoke Test', () => {
5
6
  it('should run successfully and load all dependencies including better-sqlite3 without errors', () => {
6
- const output = execFileSync('node', ['packages/pd-cli/dist/index.js', '--help'], {
7
+ const output = execFileSync('node', [getBuiltPdCliPath(), '--help'], {
7
8
  encoding: 'utf8',
8
9
  cwd: process.cwd(),
9
10
  });
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: 'node',
6
+ include: ['tests/**/*.test.ts', 'src/**/*.test.ts'],
7
+ exclude: ['**/node_modules/**', '**/dist/**'],
8
+ },
9
+ });