@principles/pd-cli 1.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/README.md +90 -0
  2. package/dist/commands/artifact.d.ts +14 -0
  3. package/dist/commands/artifact.d.ts.map +1 -0
  4. package/dist/commands/artifact.js +67 -0
  5. package/dist/commands/artifact.js.map +1 -0
  6. package/dist/commands/candidate.d.ts +83 -0
  7. package/dist/commands/candidate.d.ts.map +1 -0
  8. package/dist/commands/candidate.js +891 -0
  9. package/dist/commands/candidate.js.map +1 -0
  10. package/dist/commands/central-sync.d.ts +10 -0
  11. package/dist/commands/central-sync.d.ts.map +1 -0
  12. package/dist/commands/central-sync.js +32 -0
  13. package/dist/commands/central-sync.js.map +1 -0
  14. package/dist/commands/console.d.ts +9 -0
  15. package/dist/commands/console.d.ts.map +1 -0
  16. package/dist/commands/console.js +114 -0
  17. package/dist/commands/console.js.map +1 -0
  18. package/dist/commands/context.d.ts +7 -0
  19. package/dist/commands/context.d.ts.map +1 -0
  20. package/dist/commands/context.js +55 -0
  21. package/dist/commands/context.js.map +1 -0
  22. package/dist/commands/demo-story-a.d.ts +12 -0
  23. package/dist/commands/demo-story-a.d.ts.map +1 -0
  24. package/dist/commands/demo-story-a.js +175 -0
  25. package/dist/commands/demo-story-a.js.map +1 -0
  26. package/dist/commands/diagnose.d.ts +35 -0
  27. package/dist/commands/diagnose.d.ts.map +1 -0
  28. package/dist/commands/diagnose.js +390 -0
  29. package/dist/commands/diagnose.js.map +1 -0
  30. package/dist/commands/evolution-tasks-list.d.ts +15 -0
  31. package/dist/commands/evolution-tasks-list.d.ts.map +1 -0
  32. package/dist/commands/evolution-tasks-list.js +34 -0
  33. package/dist/commands/evolution-tasks-list.js.map +1 -0
  34. package/dist/commands/evolution-tasks-show.d.ts +14 -0
  35. package/dist/commands/evolution-tasks-show.d.ts.map +1 -0
  36. package/dist/commands/evolution-tasks-show.js +52 -0
  37. package/dist/commands/evolution-tasks-show.js.map +1 -0
  38. package/dist/commands/flow.d.ts +7 -0
  39. package/dist/commands/flow.d.ts.map +1 -0
  40. package/dist/commands/flow.js +57 -0
  41. package/dist/commands/flow.js.map +1 -0
  42. package/dist/commands/health.d.ts +16 -0
  43. package/dist/commands/health.d.ts.map +1 -0
  44. package/dist/commands/health.js +150 -0
  45. package/dist/commands/health.js.map +1 -0
  46. package/dist/commands/history.d.ts +11 -0
  47. package/dist/commands/history.d.ts.map +1 -0
  48. package/dist/commands/history.js +50 -0
  49. package/dist/commands/history.js.map +1 -0
  50. package/dist/commands/legacy-cleanup.d.ts +27 -0
  51. package/dist/commands/legacy-cleanup.d.ts.map +1 -0
  52. package/dist/commands/legacy-cleanup.js +171 -0
  53. package/dist/commands/legacy-cleanup.js.map +1 -0
  54. package/dist/commands/legacy-import.d.ts +7 -0
  55. package/dist/commands/legacy-import.d.ts.map +1 -0
  56. package/dist/commands/legacy-import.js +86 -0
  57. package/dist/commands/legacy-import.js.map +1 -0
  58. package/dist/commands/pain-record.d.ts +10 -0
  59. package/dist/commands/pain-record.d.ts.map +1 -0
  60. package/dist/commands/pain-record.js +162 -0
  61. package/dist/commands/pain-record.js.map +1 -0
  62. package/dist/commands/proven-channel-baseline.d.ts +12 -0
  63. package/dist/commands/proven-channel-baseline.d.ts.map +1 -0
  64. package/dist/commands/proven-channel-baseline.js +97 -0
  65. package/dist/commands/proven-channel-baseline.js.map +1 -0
  66. package/dist/commands/remediation-output.d.ts +40 -0
  67. package/dist/commands/remediation-output.d.ts.map +1 -0
  68. package/dist/commands/remediation-output.js +23 -0
  69. package/dist/commands/remediation-output.js.map +1 -0
  70. package/dist/commands/run.d.ts +10 -0
  71. package/dist/commands/run.d.ts.map +1 -0
  72. package/dist/commands/run.js +68 -0
  73. package/dist/commands/run.js.map +1 -0
  74. package/dist/commands/runtime-activation.d.ts +11 -0
  75. package/dist/commands/runtime-activation.d.ts.map +1 -0
  76. package/dist/commands/runtime-activation.js +150 -0
  77. package/dist/commands/runtime-activation.js.map +1 -0
  78. package/dist/commands/runtime-canary.d.ts +30 -0
  79. package/dist/commands/runtime-canary.d.ts.map +1 -0
  80. package/dist/commands/runtime-canary.js +343 -0
  81. package/dist/commands/runtime-canary.js.map +1 -0
  82. package/dist/commands/runtime-diagnostics-export.d.ts +20 -0
  83. package/dist/commands/runtime-diagnostics-export.d.ts.map +1 -0
  84. package/dist/commands/runtime-diagnostics-export.js +177 -0
  85. package/dist/commands/runtime-diagnostics-export.js.map +1 -0
  86. package/dist/commands/runtime-features.d.ts +26 -0
  87. package/dist/commands/runtime-features.d.ts.map +1 -0
  88. package/dist/commands/runtime-features.js +70 -0
  89. package/dist/commands/runtime-features.js.map +1 -0
  90. package/dist/commands/runtime-gfi-snapshot.d.ts +7 -0
  91. package/dist/commands/runtime-gfi-snapshot.d.ts.map +1 -0
  92. package/dist/commands/runtime-gfi-snapshot.js +101 -0
  93. package/dist/commands/runtime-gfi-snapshot.js.map +1 -0
  94. package/dist/commands/runtime-health-snapshot.d.ts +7 -0
  95. package/dist/commands/runtime-health-snapshot.d.ts.map +1 -0
  96. package/dist/commands/runtime-health-snapshot.js +93 -0
  97. package/dist/commands/runtime-health-snapshot.js.map +1 -0
  98. package/dist/commands/runtime-idle-trigger.d.ts +12 -0
  99. package/dist/commands/runtime-idle-trigger.d.ts.map +1 -0
  100. package/dist/commands/runtime-idle-trigger.js +102 -0
  101. package/dist/commands/runtime-idle-trigger.js.map +1 -0
  102. package/dist/commands/runtime-internalization-enqueue-successors.d.ts +9 -0
  103. package/dist/commands/runtime-internalization-enqueue-successors.d.ts.map +1 -0
  104. package/dist/commands/runtime-internalization-enqueue-successors.js +393 -0
  105. package/dist/commands/runtime-internalization-enqueue-successors.js.map +1 -0
  106. package/dist/commands/runtime-internalization-integrity-repair.d.ts +9 -0
  107. package/dist/commands/runtime-internalization-integrity-repair.d.ts.map +1 -0
  108. package/dist/commands/runtime-internalization-integrity-repair.js +54 -0
  109. package/dist/commands/runtime-internalization-integrity-repair.js.map +1 -0
  110. package/dist/commands/runtime-internalization-integrity.d.ts +7 -0
  111. package/dist/commands/runtime-internalization-integrity.d.ts.map +1 -0
  112. package/dist/commands/runtime-internalization-integrity.js +53 -0
  113. package/dist/commands/runtime-internalization-integrity.js.map +1 -0
  114. package/dist/commands/runtime-internalization-queue.d.ts +7 -0
  115. package/dist/commands/runtime-internalization-queue.d.ts.map +1 -0
  116. package/dist/commands/runtime-internalization-queue.js +85 -0
  117. package/dist/commands/runtime-internalization-queue.js.map +1 -0
  118. package/dist/commands/runtime-internalization-run-once.d.ts +12 -0
  119. package/dist/commands/runtime-internalization-run-once.d.ts.map +1 -0
  120. package/dist/commands/runtime-internalization-run-once.js +546 -0
  121. package/dist/commands/runtime-internalization-run-once.js.map +1 -0
  122. package/dist/commands/runtime-internalization-wake-once.d.ts +8 -0
  123. package/dist/commands/runtime-internalization-wake-once.d.ts.map +1 -0
  124. package/dist/commands/runtime-internalization-wake-once.js +72 -0
  125. package/dist/commands/runtime-internalization-wake-once.js.map +1 -0
  126. package/dist/commands/runtime-pain-flood-simulation.d.ts +10 -0
  127. package/dist/commands/runtime-pain-flood-simulation.d.ts.map +1 -0
  128. package/dist/commands/runtime-pain-flood-simulation.js +104 -0
  129. package/dist/commands/runtime-pain-flood-simulation.js.map +1 -0
  130. package/dist/commands/runtime-pruning.d.ts +45 -0
  131. package/dist/commands/runtime-pruning.d.ts.map +1 -0
  132. package/dist/commands/runtime-pruning.js +355 -0
  133. package/dist/commands/runtime-pruning.js.map +1 -0
  134. package/dist/commands/runtime-recovery.d.ts +9 -0
  135. package/dist/commands/runtime-recovery.d.ts.map +1 -0
  136. package/dist/commands/runtime-recovery.js +94 -0
  137. package/dist/commands/runtime-recovery.js.map +1 -0
  138. package/dist/commands/runtime-synthetic-baseline.d.ts +7 -0
  139. package/dist/commands/runtime-synthetic-baseline.d.ts.map +1 -0
  140. package/dist/commands/runtime-synthetic-baseline.js +59 -0
  141. package/dist/commands/runtime-synthetic-baseline.js.map +1 -0
  142. package/dist/commands/runtime-uat.d.ts +52 -0
  143. package/dist/commands/runtime-uat.d.ts.map +1 -0
  144. package/dist/commands/runtime-uat.js +274 -0
  145. package/dist/commands/runtime-uat.js.map +1 -0
  146. package/dist/commands/runtime.d.ts +20 -0
  147. package/dist/commands/runtime.d.ts.map +1 -0
  148. package/dist/commands/runtime.js +256 -0
  149. package/dist/commands/runtime.js.map +1 -0
  150. package/dist/commands/samples-list.d.ts +11 -0
  151. package/dist/commands/samples-list.d.ts.map +1 -0
  152. package/dist/commands/samples-list.js +37 -0
  153. package/dist/commands/samples-list.js.map +1 -0
  154. package/dist/commands/samples-review.d.ts +14 -0
  155. package/dist/commands/samples-review.d.ts.map +1 -0
  156. package/dist/commands/samples-review.js +22 -0
  157. package/dist/commands/samples-review.js.map +1 -0
  158. package/dist/commands/task.d.ts +14 -0
  159. package/dist/commands/task.d.ts.map +1 -0
  160. package/dist/commands/task.js +92 -0
  161. package/dist/commands/task.js.map +1 -0
  162. package/dist/commands/trace.d.ts +19 -0
  163. package/dist/commands/trace.d.ts.map +1 -0
  164. package/dist/commands/trace.js +154 -0
  165. package/dist/commands/trace.js.map +1 -0
  166. package/dist/commands/trajectory.d.ts +11 -0
  167. package/dist/commands/trajectory.d.ts.map +1 -0
  168. package/dist/commands/trajectory.js +47 -0
  169. package/dist/commands/trajectory.js.map +1 -0
  170. package/dist/index.d.ts +9 -0
  171. package/dist/index.d.ts.map +1 -0
  172. package/dist/index.js +736 -0
  173. package/dist/index.js.map +1 -0
  174. package/dist/legacy/legacy-import.d.ts +15 -0
  175. package/dist/legacy/legacy-import.d.ts.map +1 -0
  176. package/dist/legacy/legacy-import.js +141 -0
  177. package/dist/legacy/legacy-import.js.map +1 -0
  178. package/dist/legacy/session-history-import.d.ts +26 -0
  179. package/dist/legacy/session-history-import.d.ts.map +1 -0
  180. package/dist/legacy/session-history-import.js +151 -0
  181. package/dist/legacy/session-history-import.js.map +1 -0
  182. package/dist/principle-tree-ledger-adapter.d.ts +12 -0
  183. package/dist/principle-tree-ledger-adapter.d.ts.map +1 -0
  184. package/dist/principle-tree-ledger-adapter.js +12 -0
  185. package/dist/principle-tree-ledger-adapter.js.map +1 -0
  186. package/dist/resolve-workspace.d.ts +12 -0
  187. package/dist/resolve-workspace.d.ts.map +1 -0
  188. package/dist/resolve-workspace.js +20 -0
  189. package/dist/resolve-workspace.js.map +1 -0
  190. package/dist/services/demo-story-a-runner.d.ts +8 -0
  191. package/dist/services/demo-story-a-runner.d.ts.map +1 -0
  192. package/dist/services/demo-story-a-runner.js +369 -0
  193. package/dist/services/demo-story-a-runner.js.map +1 -0
  194. package/dist/services/feature-flag-loader.d.ts +6 -0
  195. package/dist/services/feature-flag-loader.d.ts.map +1 -0
  196. package/dist/services/feature-flag-loader.js +54 -0
  197. package/dist/services/feature-flag-loader.js.map +1 -0
  198. package/dist/services/pain-flood-simulation-runner.d.ts +10 -0
  199. package/dist/services/pain-flood-simulation-runner.d.ts.map +1 -0
  200. package/dist/services/pain-flood-simulation-runner.js +289 -0
  201. package/dist/services/pain-flood-simulation-runner.js.map +1 -0
  202. package/dist/services/proven-channel-baseline-runner.d.ts +12 -0
  203. package/dist/services/proven-channel-baseline-runner.d.ts.map +1 -0
  204. package/dist/services/proven-channel-baseline-runner.js +114 -0
  205. package/dist/services/proven-channel-baseline-runner.js.map +1 -0
  206. package/dist/services/synthetic-baseline-runner.d.ts +8 -0
  207. package/dist/services/synthetic-baseline-runner.d.ts.map +1 -0
  208. package/dist/services/synthetic-baseline-runner.js +251 -0
  209. package/dist/services/synthetic-baseline-runner.js.map +1 -0
  210. package/package.json +35 -0
  211. package/src/commands/artifact.ts +82 -0
  212. package/src/commands/candidate.ts +1117 -0
  213. package/src/commands/central-sync.ts +44 -0
  214. package/src/commands/console.ts +121 -0
  215. package/src/commands/context.ts +72 -0
  216. package/src/commands/demo-story-a.ts +195 -0
  217. package/src/commands/diagnose.ts +452 -0
  218. package/src/commands/evolution-tasks-list.ts +44 -0
  219. package/src/commands/evolution-tasks-show.ts +60 -0
  220. package/src/commands/flow.ts +60 -0
  221. package/src/commands/health.ts +189 -0
  222. package/src/commands/history.ts +63 -0
  223. package/src/commands/legacy-cleanup.ts +206 -0
  224. package/src/commands/legacy-import.ts +104 -0
  225. package/src/commands/pain-record.ts +167 -0
  226. package/src/commands/proven-channel-baseline.ts +113 -0
  227. package/src/commands/remediation-output.ts +66 -0
  228. package/src/commands/run.ts +89 -0
  229. package/src/commands/runtime-activation.ts +176 -0
  230. package/src/commands/runtime-canary.ts +371 -0
  231. package/src/commands/runtime-diagnostics-export.ts +229 -0
  232. package/src/commands/runtime-features.ts +103 -0
  233. package/src/commands/runtime-gfi-snapshot.ts +135 -0
  234. package/src/commands/runtime-health-snapshot.ts +106 -0
  235. package/src/commands/runtime-internalization-enqueue-successors.ts +479 -0
  236. package/src/commands/runtime-internalization-integrity-repair.ts +69 -0
  237. package/src/commands/runtime-internalization-integrity.ts +63 -0
  238. package/src/commands/runtime-internalization-queue.ts +106 -0
  239. package/src/commands/runtime-internalization-run-once.ts +658 -0
  240. package/src/commands/runtime-internalization-wake-once.ts +87 -0
  241. package/src/commands/runtime-pain-flood-simulation.ts +121 -0
  242. package/src/commands/runtime-pruning.ts +438 -0
  243. package/src/commands/runtime-recovery.ts +107 -0
  244. package/src/commands/runtime-synthetic-baseline.ts +70 -0
  245. package/src/commands/runtime-uat.ts +339 -0
  246. package/src/commands/runtime.ts +281 -0
  247. package/src/commands/samples-list.ts +43 -0
  248. package/src/commands/samples-review.ts +32 -0
  249. package/src/commands/task.ts +130 -0
  250. package/src/commands/trace.ts +174 -0
  251. package/src/commands/trajectory.ts +64 -0
  252. package/src/index.ts +829 -0
  253. package/src/legacy/legacy-import.ts +179 -0
  254. package/src/legacy/session-history-import.ts +231 -0
  255. package/src/principle-tree-ledger-adapter.ts +13 -0
  256. package/src/resolve-workspace.ts +20 -0
  257. package/src/services/demo-story-a-runner.ts +472 -0
  258. package/src/services/feature-flag-loader.ts +73 -0
  259. package/src/services/pain-flood-simulation-runner.ts +354 -0
  260. package/src/services/proven-channel-baseline-runner.ts +150 -0
  261. package/src/services/synthetic-baseline-runner.ts +291 -0
  262. package/tests/commands/candidate-audit-repair.test.ts +338 -0
  263. package/tests/commands/candidate-intake.test.ts +589 -0
  264. package/tests/commands/candidate-internalization-backfill.test.ts +480 -0
  265. package/tests/commands/candidate-internalize.test.ts +272 -0
  266. package/tests/commands/candidate-route.test.ts +328 -0
  267. package/tests/commands/candidate-show.test.ts +95 -0
  268. package/tests/commands/cli-command-tree.test.ts +64 -0
  269. package/tests/commands/context.test.ts +114 -0
  270. package/tests/commands/demo-story-a.test.ts +255 -0
  271. package/tests/commands/diagnose.test.ts +792 -0
  272. package/tests/commands/health.test.ts +330 -0
  273. package/tests/commands/pain-record.test.ts +316 -0
  274. package/tests/commands/plugin-config-resolution-cutover.test.ts +220 -0
  275. package/tests/commands/proven-channel-baseline.test.ts +441 -0
  276. package/tests/commands/runtime-activation.test.ts +168 -0
  277. package/tests/commands/runtime-canary.test.ts +369 -0
  278. package/tests/commands/runtime-diagnostics-export.test.ts +170 -0
  279. package/tests/commands/runtime-features.test.ts +114 -0
  280. package/tests/commands/runtime-health-snapshot.test.ts +357 -0
  281. package/tests/commands/runtime-internalization-enqueue-successors.test.ts +803 -0
  282. package/tests/commands/runtime-internalization-integrity-repair.test.ts +169 -0
  283. package/tests/commands/runtime-internalization-integrity.test.ts +102 -0
  284. package/tests/commands/runtime-internalization-queue.test.ts +252 -0
  285. package/tests/commands/runtime-internalization-run-once.test.ts +1318 -0
  286. package/tests/commands/runtime-internalization-wake-once.test.ts +170 -0
  287. package/tests/commands/runtime-internalization.test.ts +52 -0
  288. package/tests/commands/runtime-pain-flood-simulation.test.ts +418 -0
  289. package/tests/commands/runtime-pruning.test.ts +693 -0
  290. package/tests/commands/runtime-recovery.test.ts +96 -0
  291. package/tests/commands/runtime-synthetic-baseline.test.ts +249 -0
  292. package/tests/commands/runtime-uat.test.ts +397 -0
  293. package/tests/commands/runtime.test.ts +262 -0
  294. package/tests/commands/trace.test.ts +314 -0
  295. package/tests/e2e/candidate-intake-e2e.test.ts +316 -0
  296. package/tests/services/feature-flag-loader.test.ts +207 -0
  297. package/tests/services/proven-channel-baseline-runner.test.ts +30 -0
  298. package/tsconfig.json +26 -0
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Legacy Compatibility Import — OpenClaw → PD Runtime v2
3
+ *
4
+ * ## Purpose
5
+ *
6
+ * This module is a **compatibility import path only**.
7
+ * It is NOT the authoritative retrieval path for M3 queries.
8
+ *
9
+ * It syncs diagnostician task data from OpenClaw's legacy JSON-based stores
10
+ * into the PD Runtime v2 SQLite store so that `pd trajectory`, `pd history`,
11
+ * and `pd context` commands have data to query against.
12
+ *
13
+ * **Authoritative path**: `workspace/.pd/state.db` (PD-owned SQLite)
14
+ * **This module's role**: migrate legacy `.state/diagnostician_tasks.json` →
15
+ * `workspace/.pd/state.db` (one-way sync, idempotent)
16
+ *
17
+ * ## Sync Sources
18
+ *
19
+ * - `.state/diagnostician_tasks.json` → tasks + runs tables
20
+ *
21
+ * ## Non-Goals
22
+ *
23
+ * This module does NOT:
24
+ * - Query raw OpenClaw `.state/` files for primary retrieval
25
+ * - Serve as the main path for trajectory/history/context commands
26
+ * - Own any PD task semantics
27
+ *
28
+ * ## Usage
29
+ *
30
+ * Call `syncOpenClawWorkspace(workspaceDir, connection)` once to import,
31
+ * then use `pd trajectory locate`, `pd history query`, `pd context build`
32
+ * which read from `workspace/.pd/state.db` directly.
33
+ *
34
+ * Idempotent: safe to call multiple times. Re-syncs latest state on every call.
35
+ */
36
+ import * as fs from 'fs';
37
+ import * as path from 'path';
38
+ import type { SqliteConnection } from '@principles/core';
39
+
40
+ interface OpenClawDiagnosticianTask {
41
+ prompt: string;
42
+ createdAt: string;
43
+ status: 'pending' | 'completed';
44
+ reportMissingRetries?: number;
45
+ }
46
+
47
+ interface OpenClawDiagnosticianStore {
48
+ tasks: Record<string, OpenClawDiagnosticianTask>;
49
+ }
50
+
51
+ interface ParsedTaskFields {
52
+ sessionId: string;
53
+ painScore: number;
54
+ painSource: string;
55
+ painReason: string;
56
+ }
57
+
58
+ function readDiagnosticianStore(stateDir: string): OpenClawDiagnosticianStore {
59
+ const filePath = path.join(stateDir, 'diagnostician_tasks.json');
60
+ if (!fs.existsSync(filePath)) {
61
+ return { tasks: {} };
62
+ }
63
+ try {
64
+ const raw = fs.readFileSync(filePath, 'utf-8');
65
+ const parsed = JSON.parse(raw);
66
+ if (parsed && typeof parsed.tasks === 'object' && parsed.tasks !== null && !Array.isArray(parsed.tasks)) {
67
+ return parsed as OpenClawDiagnosticianStore;
68
+ }
69
+ return { tasks: {} };
70
+ } catch {
71
+ return { tasks: {} };
72
+ }
73
+ }
74
+
75
+ function parsePrompt(taskId: string, prompt: string): ParsedTaskFields {
76
+ const sessionId =
77
+ /\*\*Session ID\*\*:\s*([^\n*]+)/.exec(prompt)?.[1]?.trim() ?? taskId;
78
+ const painScore =
79
+ parseInt(/\*\*Pain Score\*\*:\s*(\d+)/.exec(prompt)?.[1] ?? '0', 10);
80
+ const painSource =
81
+ /\*\*Source\*\*:\s*([^\n*]+)/.exec(prompt)?.[1]?.trim() ?? 'unknown';
82
+ const painReason =
83
+ /\*\*Reason\*\*:\s*([^\n*]+)/.exec(prompt)?.[1]?.trim() ?? '';
84
+
85
+ return { sessionId, painScore, painSource, painReason };
86
+ }
87
+
88
+ function painScoreToSeverity(score: number): string {
89
+ if (score >= 80) return 'critical';
90
+ if (score >= 60) return 'high';
91
+ if (score >= 40) return 'medium';
92
+ return 'low';
93
+ }
94
+
95
+ /**
96
+ * Sync all openclaw diagnostician tasks into the PD Runtime v2 SQLite store.
97
+ *
98
+ * For each task in diagnostician_tasks.json:
99
+ * - Upsert into tasks table (base fields + diagnostic_json blob)
100
+ * - Upsert a corresponding synthetic run into runs table
101
+ *
102
+ * Idempotent: existing records are updated, not duplicated.
103
+ */
104
+ export async function syncOpenClawWorkspace(
105
+ workspaceDir: string,
106
+ connection: SqliteConnection,
107
+ ): Promise<{ tasksSynced: number; runsSynced: number }> {
108
+ const stateDir = path.join(workspaceDir, '.state');
109
+ const store = readDiagnosticianStore(stateDir);
110
+
111
+ const db = connection.getDb();
112
+ let tasksSynced = 0;
113
+ let runsSynced = 0;
114
+
115
+ const upsertTask = db.prepare(`
116
+ INSERT INTO tasks (task_id, task_kind, status, created_at, updated_at, attempt_count, max_attempts, diagnostic_json)
117
+ VALUES (@taskId, 'diagnostician', @status, @createdAt, @updatedAt, 0, 3, @diagnosticJson)
118
+ ON CONFLICT(task_id) DO UPDATE SET
119
+ status = @status,
120
+ updated_at = @updatedAt,
121
+ diagnostic_json = @diagnosticJson
122
+ `);
123
+
124
+ const upsertRun = db.prepare(`
125
+ INSERT INTO runs (run_id, task_id, runtime_kind, execution_status, started_at, ended_at, attempt_number, created_at, updated_at)
126
+ VALUES (@runId, @taskId, 'openclaw', @executionStatus, @startedAt, @endedAt, 1, @createdAt, @updatedAt)
127
+ ON CONFLICT(run_id) DO UPDATE SET
128
+ execution_status = @executionStatus,
129
+ ended_at = @endedAt,
130
+ updated_at = @updatedAt
131
+ `);
132
+
133
+ const now = new Date().toISOString();
134
+
135
+ for (const [taskId, task] of Object.entries(store.tasks)) {
136
+ const { sessionId, painScore, painSource, painReason } = parsePrompt(taskId, task.prompt);
137
+
138
+ const status =
139
+ task.status === 'pending'
140
+ ? 'pending'
141
+ : task.status === 'completed'
142
+ ? 'succeeded'
143
+ : 'failed';
144
+
145
+ const severity = painScoreToSeverity(painScore);
146
+ const reasonSummary = painReason.length > 200 ? painReason.substring(0, 197) + '...' : painReason;
147
+
148
+ const diagnosticJson = JSON.stringify({
149
+ workspaceDir,
150
+ reasonSummary,
151
+ source: painSource,
152
+ severity,
153
+ sessionIdHint: sessionId !== taskId ? sessionId : null,
154
+ });
155
+
156
+ upsertTask.run({
157
+ taskId,
158
+ status,
159
+ createdAt: task.createdAt,
160
+ updatedAt: now,
161
+ diagnosticJson,
162
+ });
163
+ tasksSynced++;
164
+
165
+ const runId = `run_${taskId}_1`;
166
+ upsertRun.run({
167
+ runId,
168
+ taskId,
169
+ executionStatus: status === 'pending' ? 'queued' : 'succeeded',
170
+ startedAt: task.createdAt,
171
+ endedAt: status !== 'pending' ? now : null,
172
+ createdAt: task.createdAt,
173
+ updatedAt: now,
174
+ });
175
+ runsSynced++;
176
+ }
177
+
178
+ return { tasksSynced, runsSynced };
179
+ }
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Session History Import — OpenClaw trajectory.db → PD Runtime v2
3
+ *
4
+ * Reads real conversation history from OpenClaw's trajectory.db and imports
5
+ * assistant_turns, user_turns, and tool_calls into PD-owned runtime-v2 runs table
6
+ * so that `pd history query` and `pd context build` return non-empty results.
7
+ *
8
+ * This is a COMPATIBILITY IMPORT — not authoritative retrieval.
9
+ * Primary retrieval always goes through `.pd/state.db` only.
10
+ */
11
+ import Database from 'better-sqlite3';
12
+ import * as path from 'path';
13
+
14
+ interface OpenClawTrajectoryDb {
15
+ getAssistantTurns(sessionId: string): AssistantTurn[];
16
+ getUserTurns(sessionId: string): UserTurn[];
17
+ getToolCalls(sessionId: string): ToolCall[];
18
+ getSessionIds(): string[];
19
+ }
20
+
21
+ interface AssistantTurn {
22
+ id: number;
23
+ session_id: string;
24
+ run_id: string;
25
+ provider: string;
26
+ model: string;
27
+ sanitized_text: string;
28
+ created_at: string;
29
+ }
30
+
31
+ interface UserTurn {
32
+ id: number;
33
+ session_id: string;
34
+ turn_index: number;
35
+ raw_text: string;
36
+ created_at: string;
37
+ }
38
+
39
+ interface ToolCall {
40
+ id: number;
41
+ session_id: string;
42
+ tool_name: string;
43
+ outcome: string;
44
+ duration_ms: number | null;
45
+ exit_code: number | null;
46
+ error_type: string | null;
47
+ error_message: string | null;
48
+ created_at: string;
49
+ }
50
+
51
+ function openTrajectoryDb(dbPath: string): OpenClawTrajectoryDb {
52
+ const db = new Database(dbPath, { readonly: true });
53
+
54
+ return {
55
+ getAssistantTurns(sessionId: string): AssistantTurn[] {
56
+ return db
57
+ .prepare(
58
+ 'SELECT id, session_id, run_id, provider, model, sanitized_text, created_at ' +
59
+ 'FROM assistant_turns WHERE session_id = ? ORDER BY id ASC',
60
+ )
61
+ .all(sessionId) as AssistantTurn[];
62
+ },
63
+
64
+ getUserTurns(sessionId: string): UserTurn[] {
65
+ return db
66
+ .prepare(
67
+ 'SELECT id, session_id, turn_index, raw_text, created_at ' +
68
+ 'FROM user_turns WHERE session_id = ? ORDER BY id ASC',
69
+ )
70
+ .all(sessionId) as UserTurn[];
71
+ },
72
+
73
+ getToolCalls(sessionId: string): ToolCall[] {
74
+ return db
75
+ .prepare(
76
+ 'SELECT id, session_id, tool_name, outcome, duration_ms, exit_code, ' +
77
+ 'error_type, error_message, created_at ' +
78
+ 'FROM tool_calls WHERE session_id = ? ORDER BY id ASC',
79
+ )
80
+ .all(sessionId) as ToolCall[];
81
+ },
82
+
83
+ getSessionIds(): string[] {
84
+ return (
85
+ db.prepare('SELECT session_id FROM sessions ORDER BY started_at DESC').all() as {
86
+ session_id: string;
87
+ }[]
88
+ ).map((r) => r.session_id);
89
+ },
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Import session history from OpenClaw trajectory.db into PD runtime-v2 runs table.
95
+ *
96
+ * For each task that has a sessionIdHint in its diagnostic_json:
97
+ * 1. Look up the session in trajectory.db
98
+ * 2. Import assistant_turns, user_turns, tool_calls as entries
99
+ * 3. Upsert into runs table with full payload (JSON string)
100
+ *
101
+ * Idempotent: updates existing run records, does not duplicate.
102
+ */
103
+ export async function importSessionHistory(
104
+ openclawWorkspaceDir: string,
105
+ pdWorkspaceDir: string,
106
+ getDb: () => Database.Database,
107
+ ): Promise<{ sessionsProcessed: number; entriesImported: number }> {
108
+ const trajectoryPath = path.join(openclawWorkspaceDir, '.state', 'trajectory.db');
109
+ const trajectoryDb = openTrajectoryDb(trajectoryPath);
110
+ const db = getDb();
111
+
112
+ // Find all tasks with a sessionIdHint
113
+ const tasksWithSession = db
114
+ .prepare(
115
+ `SELECT task_id, json_extract(diagnostic_json, '$.sessionIdHint') as session_id
116
+ FROM tasks
117
+ WHERE json_extract(diagnostic_json, '$.sessionIdHint') IS NOT NULL
118
+ AND json_extract(diagnostic_json, '$.sessionIdHint') != ''`,
119
+ )
120
+ .all() as { task_id: string; session_id: string }[];
121
+
122
+ let sessionsProcessed = 0;
123
+ let entriesImported = 0;
124
+
125
+ const upsertRun = db.prepare(`
126
+ INSERT INTO runs (run_id, task_id, runtime_kind, execution_status, started_at, ended_at,
127
+ attempt_number, created_at, updated_at, input_payload, output_payload)
128
+ VALUES (@runId, @taskId, 'openclaw-history', @executionStatus, @startedAt, @endedAt,
129
+ 1, @createdAt, @updatedAt, @inputPayload, @outputPayload)
130
+ ON CONFLICT(run_id) DO UPDATE SET
131
+ input_payload = @inputPayload,
132
+ output_payload = @outputPayload,
133
+ ended_at = @endedAt,
134
+ updated_at = @updatedAt
135
+ `);
136
+
137
+ const now = new Date().toISOString();
138
+
139
+ for (const { task_id, session_id } of tasksWithSession) {
140
+ // Verify session exists in trajectory.db
141
+ const assistantTurns = trajectoryDb.getAssistantTurns(session_id);
142
+ if (assistantTurns.length === 0) continue;
143
+
144
+ const userTurns = trajectoryDb.getUserTurns(session_id);
145
+ const toolCalls = trajectoryDb.getToolCalls(session_id);
146
+
147
+ // Use the latest timestamp from the session as ended_at
148
+ const lastTimestamp =
149
+ assistantTurns.length > 0
150
+ ? assistantTurns[assistantTurns.length - 1].created_at
151
+ : now;
152
+
153
+ // Build input (user turns + tool calls) and output (assistant turns) payloads
154
+ const inputPayload = JSON.stringify({
155
+ type: 'session_history',
156
+ sessionId: session_id,
157
+ userTurns: userTurns.map((t) => ({
158
+ turnIndex: t.turn_index,
159
+ text: t.raw_text,
160
+ ts: t.created_at,
161
+ })),
162
+ toolCalls: toolCalls.map((t) => ({
163
+ toolName: t.tool_name,
164
+ outcome: t.outcome,
165
+ durationMs: t.duration_ms,
166
+ exitCode: t.exit_code,
167
+ errorType: t.error_type,
168
+ errorMessage: t.error_message,
169
+ ts: t.created_at,
170
+ })),
171
+ });
172
+
173
+ const outputPayload = JSON.stringify({
174
+ type: 'assistant_turns',
175
+ sessionId: session_id,
176
+ turns: assistantTurns.map((t) => ({
177
+ provider: t.provider,
178
+ model: t.model,
179
+ text: t.sanitized_text,
180
+ ts: t.created_at,
181
+ })),
182
+ });
183
+
184
+ const runId = `run_${task_id}_history_1`;
185
+
186
+ upsertRun.run({
187
+ runId,
188
+ taskId: task_id,
189
+ executionStatus: 'succeeded',
190
+ startedAt: assistantTurns[0].created_at,
191
+ endedAt: lastTimestamp,
192
+ createdAt: assistantTurns[0].created_at,
193
+ updatedAt: now,
194
+ inputPayload,
195
+ outputPayload,
196
+ });
197
+
198
+ entriesImported += assistantTurns.length + userTurns.length + toolCalls.length;
199
+ sessionsProcessed++;
200
+ }
201
+
202
+ return { sessionsProcessed, entriesImported };
203
+ }
204
+
205
+ function _buildConversationEntries(
206
+ assistantTurns: AssistantTurn[],
207
+ userTurns: UserTurn[],
208
+ toolCalls: ToolCall[],
209
+ ): string {
210
+ // Interleave and sort by timestamp for a unified view
211
+ type Entry = { ts: string; role: string; text: string; toolName?: string };
212
+ const entries: Entry[] = [];
213
+
214
+ for (const t of assistantTurns) {
215
+ entries.push({ ts: t.created_at, role: 'assistant', text: t.sanitized_text });
216
+ }
217
+ for (const t of userTurns) {
218
+ entries.push({ ts: t.created_at, role: 'user', text: t.raw_text ?? '' });
219
+ }
220
+ for (const t of toolCalls) {
221
+ entries.push({
222
+ ts: t.created_at,
223
+ role: 'tool',
224
+ text: `${t.tool_name}: ${t.outcome}${t.error_message ? ` — ${t.error_message}` : ''}`,
225
+ toolName: t.tool_name,
226
+ });
227
+ }
228
+
229
+ entries.sort((a, b) => a.ts.localeCompare(b.ts));
230
+ return JSON.stringify(entries, null, 2);
231
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Re-exports the canonical PrincipleTreeLedgerAdapter from @principles/core/runtime-v2.
3
+ *
4
+ * This adapter uses @principles/core's addPrincipleToLedger/loadLedger, which write to
5
+ * <stateDir>/principle_training_state.json (HybridLedgerStore format), matching the ledger
6
+ * format used by the OpenClaw plugin's pain-signal-bridge.
7
+ *
8
+ * audit/repair commands use this adapter — it ensures consistency between
9
+ * what intake writes and what audit/repair read back.
10
+ */
11
+ export {
12
+ PrincipleTreeLedgerAdapter,
13
+ } from '@principles/core/runtime-v2';
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Resolve the active workspace directory.
3
+ *
4
+ * Requires explicit input — no silent cwd fallback.
5
+ * In openclaw-plugin, this will resolve via plugin config/env vars.
6
+ *
7
+ * @throws Error if no workspace directory can be determined.
8
+ */
9
+ export function resolveWorkspaceDir(workspaceDir?: string): string {
10
+ if (workspaceDir) return workspaceDir;
11
+ const envWorkspace = process.env.PD_WORKSPACE_DIR;
12
+ if (envWorkspace) return envWorkspace;
13
+ throw new Error(
14
+ 'No workspace directory configured. Set --workspace <path>, ' +
15
+ 'PD_WORKSPACE_DIR environment variable, or run from within an initialized workspace.',
16
+ );
17
+ }
18
+
19
+ /** Environment variable name for workspace directory. */
20
+ export const WORKSPACE_ENV = 'PD_WORKSPACE_DIR';