@unbrained/pm-cli 2026.6.11 → 2026.6.12

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 (180) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/cli/commands/completion.js +20 -8
  3. package/dist/cli/commands/completion.js.map +1 -1
  4. package/dist/cli/commands/create.js +6 -3
  5. package/dist/cli/commands/create.js.map +1 -1
  6. package/dist/cli/commands/docs.d.ts +2 -0
  7. package/dist/cli/commands/docs.js +2 -2
  8. package/dist/cli/commands/docs.js.map +1 -1
  9. package/dist/cli/commands/files.d.ts +2 -0
  10. package/dist/cli/commands/files.js +2 -2
  11. package/dist/cli/commands/files.js.map +1 -1
  12. package/dist/cli/commands/health.d.ts +1 -1
  13. package/dist/cli/commands/health.js +77 -2
  14. package/dist/cli/commands/health.js.map +1 -1
  15. package/dist/cli/commands/history-repair.d.ts +36 -0
  16. package/dist/cli/commands/history-repair.js +68 -3
  17. package/dist/cli/commands/history-repair.js.map +1 -1
  18. package/dist/cli/commands/index.d.ts +1 -1
  19. package/dist/cli/commands/index.js +3 -3
  20. package/dist/cli/commands/index.js.map +1 -1
  21. package/dist/cli/commands/linked-artifacts.d.ts +18 -0
  22. package/dist/cli/commands/linked-artifacts.js +26 -3
  23. package/dist/cli/commands/linked-artifacts.js.map +1 -1
  24. package/dist/cli/commands/plan.d.ts +6 -0
  25. package/dist/cli/commands/plan.js +93 -32
  26. package/dist/cli/commands/plan.js.map +1 -1
  27. package/dist/cli/commands/validate.d.ts +20 -0
  28. package/dist/cli/commands/validate.js +292 -28
  29. package/dist/cli/commands/validate.js.map +1 -1
  30. package/dist/cli/help-content.js +7 -3
  31. package/dist/cli/help-content.js.map +1 -1
  32. package/dist/cli/register-mutation.js +47 -16
  33. package/dist/cli/register-mutation.js.map +1 -1
  34. package/dist/cli/register-operations.js +10 -2
  35. package/dist/cli/register-operations.js.map +1 -1
  36. package/dist/cli/register-setup.js +16 -16
  37. package/dist/cli/register-setup.js.map +1 -1
  38. package/dist/cli-bundle/chunks/{chunk-P2PSODAQ.js → chunk-35P4GT6E.js} +110 -9
  39. package/dist/cli-bundle/chunks/chunk-35P4GT6E.js.map +7 -0
  40. package/dist/cli-bundle/chunks/{chunk-B65UUCGQ.js → chunk-37CYVF73.js} +2 -2
  41. package/dist/cli-bundle/chunks/{chunk-J3GD64J2.js → chunk-7AMK6DOW.js} +4 -4
  42. package/dist/cli-bundle/chunks/{chunk-J3GD64J2.js.map → chunk-7AMK6DOW.js.map} +1 -1
  43. package/dist/cli-bundle/chunks/{chunk-IKOH24GZ.js → chunk-AX4GEVQC.js} +3 -3
  44. package/dist/cli-bundle/chunks/{chunk-IKOH24GZ.js.map → chunk-AX4GEVQC.js.map} +2 -2
  45. package/dist/cli-bundle/chunks/chunk-C6SAP27O.js +187 -0
  46. package/dist/cli-bundle/chunks/chunk-C6SAP27O.js.map +1 -0
  47. package/dist/cli-bundle/chunks/chunk-EKS6O2IR.js +217 -0
  48. package/dist/cli-bundle/chunks/chunk-EKS6O2IR.js.map +1 -0
  49. package/dist/cli-bundle/chunks/{chunk-PSD7F7DX.js → chunk-KBPQHXWG.js} +17 -4
  50. package/dist/cli-bundle/chunks/chunk-KBPQHXWG.js.map +1 -0
  51. package/dist/cli-bundle/chunks/{chunk-3SLOMKCJ.js → chunk-L5EPZQIC.js} +2 -2
  52. package/dist/cli-bundle/chunks/chunk-NAWVUHXH.js +220 -0
  53. package/dist/cli-bundle/chunks/chunk-NAWVUHXH.js.map +7 -0
  54. package/dist/cli-bundle/chunks/{chunk-UOO6BYIA.js → chunk-PNYAAB4S.js} +21 -188
  55. package/dist/cli-bundle/chunks/chunk-PNYAAB4S.js.map +1 -0
  56. package/dist/cli-bundle/chunks/chunk-R2OUQVBK.js +190 -0
  57. package/dist/cli-bundle/chunks/chunk-R2OUQVBK.js.map +7 -0
  58. package/dist/cli-bundle/chunks/{chunk-LCSCXBGT.js → chunk-R4VWYWRN.js} +19 -193
  59. package/dist/cli-bundle/chunks/chunk-R4VWYWRN.js.map +7 -0
  60. package/dist/cli-bundle/chunks/{chunk-7RIT3OCD.js → chunk-SO55HRA5.js} +2 -2
  61. package/dist/cli-bundle/chunks/{chunk-FXRU333M.js → chunk-UIG4TW2H.js} +110 -9
  62. package/dist/cli-bundle/chunks/chunk-UIG4TW2H.js.map +1 -0
  63. package/dist/cli-bundle/chunks/{chunk-E5DUIJA4.js → chunk-WPDMBIX6.js} +16 -3
  64. package/dist/cli-bundle/chunks/chunk-WPDMBIX6.js.map +7 -0
  65. package/dist/cli-bundle/chunks/{chunk-IH4MBKK7.js → chunk-XWMF3POR.js} +2 -2
  66. package/dist/cli-bundle/chunks/{contracts-3NKWYKKU.js → contracts-2G66IGIA.js} +2 -2
  67. package/dist/cli-bundle/chunks/{contracts-MIXBWJIB.js → contracts-PJCHYSO5.js} +2 -2
  68. package/dist/cli-bundle/chunks/{create-IFA26O2I.js → create-5433DP3G.js} +2 -2
  69. package/dist/cli-bundle/chunks/{create-JVXYHYH4.js → create-VWLWS34Z.js} +2 -2
  70. package/dist/cli-bundle/chunks/{docs-5WMBVQT2.js → docs-I3BAF5WH.js} +4 -4
  71. package/dist/cli-bundle/chunks/docs-I3BAF5WH.js.map +1 -0
  72. package/dist/cli-bundle/chunks/{docs-MB53UJAJ.js → docs-MXLGZUIT.js} +3 -3
  73. package/dist/cli-bundle/chunks/docs-MXLGZUIT.js.map +7 -0
  74. package/dist/cli-bundle/chunks/{files-GVMNVLCB.js → files-FYP3MDPX.js} +3 -3
  75. package/dist/cli-bundle/chunks/files-FYP3MDPX.js.map +7 -0
  76. package/dist/cli-bundle/chunks/{files-DLB5LJEP.js → files-GUXUM2MB.js} +4 -4
  77. package/dist/cli-bundle/chunks/files-GUXUM2MB.js.map +1 -0
  78. package/dist/cli-bundle/chunks/{gc-2WEPW6D6.js → gc-FENB2ESG.js} +12 -174
  79. package/dist/cli-bundle/chunks/gc-FENB2ESG.js.map +1 -0
  80. package/dist/cli-bundle/chunks/{gc-4Z3IKHAZ.js → gc-KGQG66SA.js} +10 -179
  81. package/dist/cli-bundle/chunks/gc-KGQG66SA.js.map +7 -0
  82. package/dist/cli-bundle/chunks/{health-YO5LRWN4.js → health-7MTXAVR2.js} +71 -4
  83. package/dist/cli-bundle/chunks/health-7MTXAVR2.js.map +7 -0
  84. package/dist/cli-bundle/chunks/{health-4ZYB3IYQ.js → health-E4D7KGHD.js} +72 -5
  85. package/dist/cli-bundle/chunks/health-E4D7KGHD.js.map +1 -0
  86. package/dist/cli-bundle/chunks/{history-repair-KVPFJKOS.js → history-repair-OSQOKJ3E.js} +61 -3
  87. package/dist/cli-bundle/chunks/history-repair-OSQOKJ3E.js.map +7 -0
  88. package/dist/cli-bundle/chunks/{history-repair-RUGKD3YR.js → history-repair-SBK7P34V.js} +62 -4
  89. package/dist/cli-bundle/chunks/history-repair-SBK7P34V.js.map +1 -0
  90. package/dist/cli-bundle/chunks/{plan-VNUG3WZZ.js → plan-2YTQYWGM.js} +52 -12
  91. package/dist/cli-bundle/chunks/plan-2YTQYWGM.js.map +1 -0
  92. package/dist/cli-bundle/chunks/{plan-FQLMJRLZ.js → plan-7IVSICR6.js} +51 -11
  93. package/dist/cli-bundle/chunks/plan-7IVSICR6.js.map +7 -0
  94. package/dist/cli-bundle/chunks/{register-list-query-VHDXWEPP.js → register-list-query-4UPMHONX.js} +3 -3
  95. package/dist/cli-bundle/chunks/{register-list-query-NPE3ECJQ.js → register-list-query-7VOW2C3W.js} +3 -3
  96. package/dist/cli-bundle/chunks/{register-mutation-EAYNLGOS.js → register-mutation-FARSGYRD.js} +43 -26
  97. package/dist/cli-bundle/chunks/{register-mutation-EAYNLGOS.js.map → register-mutation-FARSGYRD.js.map} +2 -2
  98. package/dist/cli-bundle/chunks/{register-mutation-DG53FCBV.js → register-mutation-LJDNVREU.js} +44 -27
  99. package/dist/cli-bundle/chunks/{register-mutation-DG53FCBV.js.map → register-mutation-LJDNVREU.js.map} +1 -1
  100. package/dist/cli-bundle/chunks/{register-operations-AM6KTWB6.js → register-operations-FFTYAL42.js} +17 -13
  101. package/dist/cli-bundle/chunks/register-operations-FFTYAL42.js.map +1 -0
  102. package/dist/cli-bundle/chunks/{register-operations-FWFE64JG.js → register-operations-HCJKDUA6.js} +16 -12
  103. package/dist/cli-bundle/chunks/{register-operations-FWFE64JG.js.map → register-operations-HCJKDUA6.js.map} +2 -2
  104. package/dist/cli-bundle/chunks/{register-setup-IKX5524L.js → register-setup-6AVIUOCC.js} +19 -19
  105. package/dist/cli-bundle/chunks/register-setup-6AVIUOCC.js.map +1 -0
  106. package/dist/cli-bundle/chunks/{register-setup-G4QYI3RX.js → register-setup-KVNLO5OJ.js} +18 -18
  107. package/dist/cli-bundle/chunks/register-setup-KVNLO5OJ.js.map +7 -0
  108. package/dist/cli-bundle/chunks/{update-2EVXOC7V.js → update-36JM7YZT.js} +3 -3
  109. package/dist/cli-bundle/chunks/{update-5A2B6QYB.js → update-I246PCLO.js} +3 -3
  110. package/dist/cli-bundle/chunks/{update-many-V4LA3C4H.js → update-many-F4IKDWZB.js} +3 -3
  111. package/dist/cli-bundle/chunks/{update-many-TUGU5YXQ.js → update-many-NTWZ5YT3.js} +3 -3
  112. package/dist/cli-bundle/chunks/{validate-EQTT6WVX.js → validate-46KCRHL7.js} +448 -36
  113. package/dist/cli-bundle/chunks/validate-46KCRHL7.js.map +1 -0
  114. package/dist/cli-bundle/chunks/{validate-XN4I4DPL.js → validate-CRFMPTYD.js} +468 -35
  115. package/dist/cli-bundle/chunks/validate-CRFMPTYD.js.map +7 -0
  116. package/dist/cli-bundle/main.js +24 -10
  117. package/dist/cli-bundle/main.js.map +2 -2
  118. package/dist/core/diagnostics/remediation.js +19 -6
  119. package/dist/core/diagnostics/remediation.js.map +1 -1
  120. package/dist/core/lock/lock-gc.d.ts +31 -0
  121. package/dist/core/lock/lock-gc.js +120 -62
  122. package/dist/core/lock/lock-gc.js.map +1 -1
  123. package/dist/core/telemetry/consent.js +18 -3
  124. package/dist/core/telemetry/consent.js.map +1 -1
  125. package/dist/core/validate/fix-planning.d.ts +130 -0
  126. package/dist/core/validate/fix-planning.js +202 -0
  127. package/dist/core/validate/fix-planning.js.map +1 -0
  128. package/dist/core/validate/missing-by-type.d.ts +21 -0
  129. package/dist/core/validate/missing-by-type.js +39 -0
  130. package/dist/core/validate/missing-by-type.js.map +1 -0
  131. package/dist/core/validate/stale-file-classification.d.ts +41 -0
  132. package/dist/core/validate/stale-file-classification.js +73 -0
  133. package/dist/core/validate/stale-file-classification.js.map +1 -0
  134. package/dist/mcp/server.js +41 -8
  135. package/dist/mcp/server.js.map +1 -1
  136. package/dist/sdk/cli-contracts/tool-parameter-tables.js +38 -2
  137. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
  138. package/dist/sdk/cli-contracts.d.ts +6 -1
  139. package/dist/sdk/cli-contracts.js +74 -7
  140. package/dist/sdk/cli-contracts.js.map +1 -1
  141. package/docs/AGENT_GUIDE.md +6 -1
  142. package/docs/COMMANDS.md +23 -1
  143. package/package.json +1 -1
  144. package/dist/cli-bundle/chunks/chunk-E5DUIJA4.js.map +0 -7
  145. package/dist/cli-bundle/chunks/chunk-FXRU333M.js.map +0 -1
  146. package/dist/cli-bundle/chunks/chunk-LCSCXBGT.js.map +0 -7
  147. package/dist/cli-bundle/chunks/chunk-P2PSODAQ.js.map +0 -7
  148. package/dist/cli-bundle/chunks/chunk-PSD7F7DX.js.map +0 -1
  149. package/dist/cli-bundle/chunks/chunk-UOO6BYIA.js.map +0 -1
  150. package/dist/cli-bundle/chunks/docs-5WMBVQT2.js.map +0 -1
  151. package/dist/cli-bundle/chunks/docs-MB53UJAJ.js.map +0 -7
  152. package/dist/cli-bundle/chunks/files-DLB5LJEP.js.map +0 -1
  153. package/dist/cli-bundle/chunks/files-GVMNVLCB.js.map +0 -7
  154. package/dist/cli-bundle/chunks/gc-2WEPW6D6.js.map +0 -1
  155. package/dist/cli-bundle/chunks/gc-4Z3IKHAZ.js.map +0 -7
  156. package/dist/cli-bundle/chunks/health-4ZYB3IYQ.js.map +0 -1
  157. package/dist/cli-bundle/chunks/health-YO5LRWN4.js.map +0 -7
  158. package/dist/cli-bundle/chunks/history-repair-KVPFJKOS.js.map +0 -7
  159. package/dist/cli-bundle/chunks/history-repair-RUGKD3YR.js.map +0 -1
  160. package/dist/cli-bundle/chunks/plan-FQLMJRLZ.js.map +0 -7
  161. package/dist/cli-bundle/chunks/plan-VNUG3WZZ.js.map +0 -1
  162. package/dist/cli-bundle/chunks/register-operations-AM6KTWB6.js.map +0 -1
  163. package/dist/cli-bundle/chunks/register-setup-G4QYI3RX.js.map +0 -7
  164. package/dist/cli-bundle/chunks/register-setup-IKX5524L.js.map +0 -1
  165. package/dist/cli-bundle/chunks/validate-EQTT6WVX.js.map +0 -1
  166. package/dist/cli-bundle/chunks/validate-XN4I4DPL.js.map +0 -7
  167. /package/dist/cli-bundle/chunks/{chunk-B65UUCGQ.js.map → chunk-37CYVF73.js.map} +0 -0
  168. /package/dist/cli-bundle/chunks/{chunk-3SLOMKCJ.js.map → chunk-L5EPZQIC.js.map} +0 -0
  169. /package/dist/cli-bundle/chunks/{chunk-7RIT3OCD.js.map → chunk-SO55HRA5.js.map} +0 -0
  170. /package/dist/cli-bundle/chunks/{chunk-IH4MBKK7.js.map → chunk-XWMF3POR.js.map} +0 -0
  171. /package/dist/cli-bundle/chunks/{contracts-3NKWYKKU.js.map → contracts-2G66IGIA.js.map} +0 -0
  172. /package/dist/cli-bundle/chunks/{contracts-MIXBWJIB.js.map → contracts-PJCHYSO5.js.map} +0 -0
  173. /package/dist/cli-bundle/chunks/{create-IFA26O2I.js.map → create-5433DP3G.js.map} +0 -0
  174. /package/dist/cli-bundle/chunks/{create-JVXYHYH4.js.map → create-VWLWS34Z.js.map} +0 -0
  175. /package/dist/cli-bundle/chunks/{register-list-query-VHDXWEPP.js.map → register-list-query-4UPMHONX.js.map} +0 -0
  176. /package/dist/cli-bundle/chunks/{register-list-query-NPE3ECJQ.js.map → register-list-query-7VOW2C3W.js.map} +0 -0
  177. /package/dist/cli-bundle/chunks/{update-2EVXOC7V.js.map → update-36JM7YZT.js.map} +0 -0
  178. /package/dist/cli-bundle/chunks/{update-5A2B6QYB.js.map → update-I246PCLO.js.map} +0 -0
  179. /package/dist/cli-bundle/chunks/{update-many-V4LA3C4H.js.map → update-many-F4IKDWZB.js.map} +0 -0
  180. /package/dist/cli-bundle/chunks/{update-many-TUGU5YXQ.js.map → update-many-NTWZ5YT3.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../cli/commands/gc.ts"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { runActiveOnIndexHooks, runActiveOnReadHooks, runActiveOnWriteHooks } from \"../../core/extensions/index.js\";\nimport { pathExists } from \"../../core/fs/fs-utils.js\";\nimport { runLockGc } from \"../../core/lock/lock-gc.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\n\nconst GC_SCOPE_VALUES = [\"index\", \"embeddings\", \"runtime\", \"locks\"] as const;\ntype GcScope = (typeof GC_SCOPE_VALUES)[number];\n\ninterface GcTarget {\n scope: GcScope;\n relativePath: string;\n kind: \"file\" | \"directory\";\n}\n\nconst GC_TARGETS: readonly GcTarget[] = [\n {\n scope: \"index\",\n relativePath: \"index/manifest.json\",\n kind: \"file\",\n },\n {\n scope: \"embeddings\",\n relativePath: \"search/embeddings.jsonl\",\n kind: \"file\",\n },\n {\n scope: \"embeddings\",\n relativePath: \"search/vectorization-status.json\",\n kind: \"file\",\n },\n {\n scope: \"embeddings\",\n relativePath: \"search/lancedb\",\n kind: \"directory\",\n },\n {\n scope: \"runtime\",\n relativePath: \"runtime/test-runs\",\n kind: \"directory\",\n },\n {\n scope: \"runtime\",\n relativePath: \"runtime/history-drift-cache.json\",\n kind: \"file\",\n },\n] as const;\n\nexport interface GcCommandOptions {\n dryRun?: boolean;\n scope?: string[];\n}\n\nexport interface GcLocksSummary {\n scanned: number;\n removed: number;\n retained: number;\n}\n\nexport interface GcResult {\n ok: boolean;\n dry_run: boolean;\n scope: GcScope[];\n removed: string[];\n retained: string[];\n warnings: string[];\n guidance: string[];\n /** Present only when the locks scope was selected. Summarizes the stale-lock sweep. */\n locks?: GcLocksSummary;\n generated_at: string;\n}\n\nfunction isErrno(error: unknown, code: string): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code?: string }).code === code;\n}\n\nasync function removeCacheFile(\n pmRoot: string,\n target: GcTarget,\n dryRun: boolean,\n): Promise<{ removed: boolean; warnings: string[] }> {\n const relativePath = target.relativePath;\n const absolutePath = path.join(pmRoot, relativePath);\n const warnings = await runActiveOnReadHooks({\n path: absolutePath,\n scope: \"project\",\n });\n try {\n const stats = await fs.stat(absolutePath);\n if (target.kind === \"file\" && !stats.isFile()) {\n return {\n removed: false,\n warnings: [...warnings, `not_a_file:${relativePath}`],\n };\n }\n if (target.kind === \"directory\" && !stats.isDirectory()) {\n return {\n removed: false,\n warnings: [...warnings, `not_a_directory:${relativePath}`],\n };\n }\n if (dryRun) {\n return {\n removed: true,\n warnings,\n };\n }\n if (target.kind === \"file\") {\n await fs.unlink(absolutePath);\n } else {\n await fs.rm(absolutePath, { recursive: true, force: true });\n }\n const writeWarnings = await runActiveOnWriteHooks({\n path: absolutePath,\n scope: \"project\",\n op: \"gc:remove\",\n });\n return {\n removed: true,\n warnings: [...warnings, ...writeWarnings],\n };\n } catch (error: unknown) {\n if (isErrno(error, \"ENOENT\")) {\n return {\n removed: false,\n warnings,\n };\n }\n throw error;\n }\n}\n\nfunction parseScopes(raw: string[] | undefined): GcScope[] {\n if (!raw || raw.length === 0) {\n return [...GC_SCOPE_VALUES];\n }\n const tokens = raw\n .flatMap((entry) => entry.split(\",\"))\n .map((entry) => entry.trim().toLowerCase())\n .filter((entry) => entry.length > 0);\n if (tokens.length === 0) {\n throw new PmCliError(`--scope requires at least one value (${GC_SCOPE_VALUES.join(\",\")})`, EXIT_CODE.USAGE);\n }\n const resolved = new Set<GcScope>();\n for (const token of tokens) {\n if (!(GC_SCOPE_VALUES as readonly string[]).includes(token)) {\n throw new PmCliError(\n `Invalid --scope value \"${token}\". Expected one or more of: ${GC_SCOPE_VALUES.join(\", \")}`,\n EXIT_CODE.USAGE,\n );\n }\n resolved.add(token as GcScope);\n }\n return GC_SCOPE_VALUES.filter((scope) => resolved.has(scope));\n}\n\nfunction buildGcGuidance(params: {\n dryRun: boolean;\n scopes: GcScope[];\n removed: string[];\n}): string[] {\n const guidance: string[] = [];\n if (params.dryRun) {\n guidance.push(\"Dry-run preview only: no cache artifacts were deleted.\");\n }\n const searchScopeSelected = params.scopes.includes(\"index\") || params.scopes.includes(\"embeddings\");\n const searchArtifactsAffected = params.removed.some(\n (entry) =>\n entry === \"index/manifest.json\" ||\n entry === \"search/embeddings.jsonl\" ||\n entry === \"search/vectorization-status.json\" ||\n entry === \"search/lancedb\",\n );\n if (searchScopeSelected && searchArtifactsAffected) {\n guidance.push(\n 'Search artifacts were removed; run \"pm install search-advanced --project\" if reindex is unavailable, then \"pm reindex --mode keyword\" (and \"--mode semantic\" when semantic search is enabled) before search-heavy workflows.',\n );\n }\n if (params.removed.includes(\"runtime/history-drift-cache.json\")) {\n guidance.push('History drift cache was removed; the next \"pm health\" run performs a full history-drift re-scan.');\n }\n return guidance;\n}\n\nexport async function runGc(global: GlobalOptions, options: GcCommandOptions = {}): Promise<GcResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);\n }\n\n await readSettings(pmRoot);\n const dryRun = options.dryRun === true;\n const scopes = parseScopes(options.scope);\n const selectedTargets = GC_TARGETS.filter((target) => scopes.includes(target.scope));\n\n const removed: string[] = [];\n const retained: string[] = [];\n const warnings: string[] = [];\n\n for (const target of selectedTargets) {\n const result = await removeCacheFile(pmRoot, target, dryRun);\n if (result.removed) {\n removed.push(target.relativePath);\n } else {\n retained.push(target.relativePath);\n }\n warnings.push(...result.warnings);\n }\n\n // The locks scope is not a path-based GC_TARGET: it sweeps the locks/ directory\n // and removes only locks whose own embedded ttl has expired (crashed-process\n // debris), retaining active and unparseable locks. See core/lock/lock-gc.ts.\n let locksSummary: GcLocksSummary | undefined;\n if (scopes.includes(\"locks\")) {\n const lockResult = await runLockGc(pmRoot, {\n dryRun,\n hooks: {\n onRead: (lockPath) => runActiveOnReadHooks({ path: lockPath, scope: \"project\" }),\n onWrite: (lockPath) => runActiveOnWriteHooks({ path: lockPath, scope: \"project\", op: \"gc:lock_remove\" }),\n },\n });\n removed.push(...lockResult.removed);\n retained.push(...lockResult.retained);\n warnings.push(...lockResult.warnings);\n locksSummary = {\n scanned: lockResult.scanned,\n removed: lockResult.removed.length,\n retained: lockResult.retained.length,\n };\n }\n\n warnings.push(\n ...(await runActiveOnIndexHooks({\n mode: dryRun ? \"gc:dry-run\" : \"gc\",\n total_items: selectedTargets.length,\n })),\n );\n const guidance = buildGcGuidance({\n dryRun,\n scopes,\n removed,\n });\n\n return {\n ok: warnings.length === 0,\n dry_run: dryRun,\n scope: scopes,\n removed,\n retained,\n warnings,\n ...(locksSummary ? { locks: locksSummary } : {}),\n guidance,\n generated_at: nowIso(),\n };\n}\n"],"names":[],"mappings":"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","debugId":"53de24e8-b5be-5de6-93ad-bdaa9f3015b0"}
@@ -1,3 +1,6 @@
1
+ import {
2
+ runLockGc
3
+ } from "./chunk-NAWVUHXH.js";
1
4
  import {
2
5
  nowIso
3
6
  } from "./chunk-IUKD4W6Z.js";
@@ -14,180 +17,8 @@ import {
14
17
  } from "./chunk-FY4SPXSC.js";
15
18
 
16
19
  // dist/cli/commands/gc.js
17
- import fs2 from "node:fs/promises";
18
- import path2 from "node:path";
19
-
20
- // dist/core/lock/lock-gc.js
21
20
  import fs from "node:fs/promises";
22
21
  import path from "node:path";
23
- !(function() {
24
- try {
25
- var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
26
- n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "1a412027-5c73-58d4-b696-4a909dde88a8");
27
- } catch (e2) {
28
- }
29
- })();
30
- function parseLock(raw) {
31
- let parsed;
32
- try {
33
- parsed = JSON.parse(raw);
34
- } catch {
35
- return null;
36
- }
37
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
38
- return null;
39
- }
40
- const candidate = parsed;
41
- const { id, owner, created_at, ttl_seconds } = candidate;
42
- if (typeof id !== "string" || typeof owner !== "string" || typeof created_at !== "string" || typeof ttl_seconds !== "number" || !Number.isFinite(ttl_seconds)) {
43
- return null;
44
- }
45
- return { id, owner, created_at, ttl_seconds };
46
- }
47
- function isErrno(error, code) {
48
- return typeof error === "object" && error !== null && "code" in error && error.code === code;
49
- }
50
- async function runLockGc(pmRoot, options) {
51
- const { dryRun, hooks } = options;
52
- const nowMs = options.now ?? Date.now();
53
- const locksDir = path.join(pmRoot, "locks");
54
- const result = {
55
- scanned: 0,
56
- removed: [],
57
- retained: [],
58
- warnings: [],
59
- entries: []
60
- };
61
- let dirEntries;
62
- try {
63
- const raw = await fs.readdir(locksDir);
64
- dirEntries = raw.filter((f) => f.endsWith(".lock")).sort();
65
- } catch (error) {
66
- if (isErrno(error, "ENOENT")) {
67
- return result;
68
- }
69
- throw error;
70
- }
71
- for (const file of dirEntries) {
72
- result.scanned += 1;
73
- const absPath = path.join(locksDir, file);
74
- const relPath = `locks/${file}`;
75
- if (hooks?.onRead) {
76
- const hookWarnings = await hooks.onRead(absPath);
77
- result.warnings.push(...hookWarnings);
78
- }
79
- let raw;
80
- try {
81
- raw = await fs.readFile(absPath, "utf8");
82
- } catch (readError) {
83
- if (isErrno(readError, "ENOENT")) {
84
- result.scanned -= 1;
85
- continue;
86
- }
87
- result.warnings.push(`lock_unreadable:${file}`);
88
- result.retained.push(relPath);
89
- result.entries.push({
90
- file,
91
- id: null,
92
- owner: null,
93
- created_at: null,
94
- ttl_seconds: null,
95
- age_seconds: null,
96
- stale: false,
97
- reason: "unparseable"
98
- });
99
- continue;
100
- }
101
- const lock = parseLock(raw);
102
- if (lock === null) {
103
- result.warnings.push(`lock_unparseable:${file}`);
104
- result.retained.push(relPath);
105
- result.entries.push({
106
- file,
107
- id: null,
108
- owner: null,
109
- created_at: null,
110
- ttl_seconds: null,
111
- age_seconds: null,
112
- stale: false,
113
- reason: "unparseable"
114
- });
115
- continue;
116
- }
117
- const createdAtMs = Date.parse(lock.created_at);
118
- if (!Number.isFinite(createdAtMs)) {
119
- result.warnings.push(`lock_invalid_timestamp:${file}`);
120
- result.retained.push(relPath);
121
- result.entries.push({
122
- file,
123
- id: lock.id,
124
- owner: lock.owner,
125
- created_at: lock.created_at,
126
- ttl_seconds: lock.ttl_seconds,
127
- age_seconds: null,
128
- stale: false,
129
- reason: "unparseable"
130
- });
131
- continue;
132
- }
133
- const ageMs = nowMs - createdAtMs;
134
- const age_seconds = Math.floor(ageMs / 1e3);
135
- const stale = ageMs > lock.ttl_seconds * 1e3;
136
- if (!stale) {
137
- result.retained.push(relPath);
138
- result.entries.push({
139
- file,
140
- id: lock.id,
141
- owner: lock.owner,
142
- created_at: lock.created_at,
143
- ttl_seconds: lock.ttl_seconds,
144
- age_seconds,
145
- stale: false,
146
- reason: "active"
147
- });
148
- continue;
149
- }
150
- if (!dryRun) {
151
- try {
152
- await fs.unlink(absPath);
153
- } catch (unlinkError) {
154
- if (!isErrno(unlinkError, "ENOENT")) {
155
- result.warnings.push(`lock_remove_failed:${file}`);
156
- result.retained.push(relPath);
157
- result.entries.push({
158
- file,
159
- id: lock.id,
160
- owner: lock.owner,
161
- created_at: lock.created_at,
162
- ttl_seconds: lock.ttl_seconds,
163
- age_seconds,
164
- stale: true,
165
- reason: "expired"
166
- });
167
- continue;
168
- }
169
- }
170
- if (hooks?.onWrite) {
171
- const hookWarnings = await hooks.onWrite(absPath);
172
- result.warnings.push(...hookWarnings);
173
- }
174
- }
175
- result.removed.push(relPath);
176
- result.entries.push({
177
- file,
178
- id: lock.id,
179
- owner: lock.owner,
180
- created_at: lock.created_at,
181
- ttl_seconds: lock.ttl_seconds,
182
- age_seconds,
183
- stale: true,
184
- reason: "expired"
185
- });
186
- }
187
- return result;
188
- }
189
-
190
- // dist/cli/commands/gc.js
191
22
  !(function() {
192
23
  try {
193
24
  var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
@@ -228,18 +59,18 @@ var GC_TARGETS = [
228
59
  kind: "file"
229
60
  }
230
61
  ];
231
- function isErrno2(error, code) {
62
+ function isErrno(error, code) {
232
63
  return typeof error === "object" && error !== null && "code" in error && error.code === code;
233
64
  }
234
65
  async function removeCacheFile(pmRoot, target, dryRun) {
235
66
  const relativePath = target.relativePath;
236
- const absolutePath = path2.join(pmRoot, relativePath);
67
+ const absolutePath = path.join(pmRoot, relativePath);
237
68
  const warnings = await runActiveOnReadHooks({
238
69
  path: absolutePath,
239
70
  scope: "project"
240
71
  });
241
72
  try {
242
- const stats = await fs2.stat(absolutePath);
73
+ const stats = await fs.stat(absolutePath);
243
74
  if (target.kind === "file" && !stats.isFile()) {
244
75
  return {
245
76
  removed: false,
@@ -259,9 +90,9 @@ async function removeCacheFile(pmRoot, target, dryRun) {
259
90
  };
260
91
  }
261
92
  if (target.kind === "file") {
262
- await fs2.unlink(absolutePath);
93
+ await fs.unlink(absolutePath);
263
94
  } else {
264
- await fs2.rm(absolutePath, { recursive: true, force: true });
95
+ await fs.rm(absolutePath, { recursive: true, force: true });
265
96
  }
266
97
  const writeWarnings = await runActiveOnWriteHooks({
267
98
  path: absolutePath,
@@ -273,7 +104,7 @@ async function removeCacheFile(pmRoot, target, dryRun) {
273
104
  warnings: [...warnings, ...writeWarnings]
274
105
  };
275
106
  } catch (error) {
276
- if (isErrno2(error, "ENOENT")) {
107
+ if (isErrno(error, "ENOENT")) {
277
108
  return {
278
109
  removed: false,
279
110
  warnings
@@ -377,4 +208,4 @@ async function runGc(global2, options = {}) {
377
208
  export {
378
209
  runGc
379
210
  };
380
- //# sourceMappingURL=gc-4Z3IKHAZ.js.map
211
+ //# sourceMappingURL=gc-KGQG66SA.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../../cli/commands/gc.ts"],
4
+ "sourcesContent": ["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { runActiveOnIndexHooks, runActiveOnReadHooks, runActiveOnWriteHooks } from \"../../core/extensions/index.js\";\nimport { pathExists } from \"../../core/fs/fs-utils.js\";\nimport { runLockGc } from \"../../core/lock/lock-gc.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\n\nconst GC_SCOPE_VALUES = [\"index\", \"embeddings\", \"runtime\", \"locks\"] as const;\ntype GcScope = (typeof GC_SCOPE_VALUES)[number];\n\ninterface GcTarget {\n scope: GcScope;\n relativePath: string;\n kind: \"file\" | \"directory\";\n}\n\nconst GC_TARGETS: readonly GcTarget[] = [\n {\n scope: \"index\",\n relativePath: \"index/manifest.json\",\n kind: \"file\",\n },\n {\n scope: \"embeddings\",\n relativePath: \"search/embeddings.jsonl\",\n kind: \"file\",\n },\n {\n scope: \"embeddings\",\n relativePath: \"search/vectorization-status.json\",\n kind: \"file\",\n },\n {\n scope: \"embeddings\",\n relativePath: \"search/lancedb\",\n kind: \"directory\",\n },\n {\n scope: \"runtime\",\n relativePath: \"runtime/test-runs\",\n kind: \"directory\",\n },\n {\n scope: \"runtime\",\n relativePath: \"runtime/history-drift-cache.json\",\n kind: \"file\",\n },\n] as const;\n\nexport interface GcCommandOptions {\n dryRun?: boolean;\n scope?: string[];\n}\n\nexport interface GcLocksSummary {\n scanned: number;\n removed: number;\n retained: number;\n}\n\nexport interface GcResult {\n ok: boolean;\n dry_run: boolean;\n scope: GcScope[];\n removed: string[];\n retained: string[];\n warnings: string[];\n guidance: string[];\n /** Present only when the locks scope was selected. Summarizes the stale-lock sweep. */\n locks?: GcLocksSummary;\n generated_at: string;\n}\n\nfunction isErrno(error: unknown, code: string): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code?: string }).code === code;\n}\n\nasync function removeCacheFile(\n pmRoot: string,\n target: GcTarget,\n dryRun: boolean,\n): Promise<{ removed: boolean; warnings: string[] }> {\n const relativePath = target.relativePath;\n const absolutePath = path.join(pmRoot, relativePath);\n const warnings = await runActiveOnReadHooks({\n path: absolutePath,\n scope: \"project\",\n });\n try {\n const stats = await fs.stat(absolutePath);\n if (target.kind === \"file\" && !stats.isFile()) {\n return {\n removed: false,\n warnings: [...warnings, `not_a_file:${relativePath}`],\n };\n }\n if (target.kind === \"directory\" && !stats.isDirectory()) {\n return {\n removed: false,\n warnings: [...warnings, `not_a_directory:${relativePath}`],\n };\n }\n if (dryRun) {\n return {\n removed: true,\n warnings,\n };\n }\n if (target.kind === \"file\") {\n await fs.unlink(absolutePath);\n } else {\n await fs.rm(absolutePath, { recursive: true, force: true });\n }\n const writeWarnings = await runActiveOnWriteHooks({\n path: absolutePath,\n scope: \"project\",\n op: \"gc:remove\",\n });\n return {\n removed: true,\n warnings: [...warnings, ...writeWarnings],\n };\n } catch (error: unknown) {\n if (isErrno(error, \"ENOENT\")) {\n return {\n removed: false,\n warnings,\n };\n }\n throw error;\n }\n}\n\nfunction parseScopes(raw: string[] | undefined): GcScope[] {\n if (!raw || raw.length === 0) {\n return [...GC_SCOPE_VALUES];\n }\n const tokens = raw\n .flatMap((entry) => entry.split(\",\"))\n .map((entry) => entry.trim().toLowerCase())\n .filter((entry) => entry.length > 0);\n if (tokens.length === 0) {\n throw new PmCliError(`--scope requires at least one value (${GC_SCOPE_VALUES.join(\",\")})`, EXIT_CODE.USAGE);\n }\n const resolved = new Set<GcScope>();\n for (const token of tokens) {\n if (!(GC_SCOPE_VALUES as readonly string[]).includes(token)) {\n throw new PmCliError(\n `Invalid --scope value \"${token}\". Expected one or more of: ${GC_SCOPE_VALUES.join(\", \")}`,\n EXIT_CODE.USAGE,\n );\n }\n resolved.add(token as GcScope);\n }\n return GC_SCOPE_VALUES.filter((scope) => resolved.has(scope));\n}\n\nfunction buildGcGuidance(params: {\n dryRun: boolean;\n scopes: GcScope[];\n removed: string[];\n}): string[] {\n const guidance: string[] = [];\n if (params.dryRun) {\n guidance.push(\"Dry-run preview only: no cache artifacts were deleted.\");\n }\n const searchScopeSelected = params.scopes.includes(\"index\") || params.scopes.includes(\"embeddings\");\n const searchArtifactsAffected = params.removed.some(\n (entry) =>\n entry === \"index/manifest.json\" ||\n entry === \"search/embeddings.jsonl\" ||\n entry === \"search/vectorization-status.json\" ||\n entry === \"search/lancedb\",\n );\n if (searchScopeSelected && searchArtifactsAffected) {\n guidance.push(\n 'Search artifacts were removed; run \"pm install search-advanced --project\" if reindex is unavailable, then \"pm reindex --mode keyword\" (and \"--mode semantic\" when semantic search is enabled) before search-heavy workflows.',\n );\n }\n if (params.removed.includes(\"runtime/history-drift-cache.json\")) {\n guidance.push('History drift cache was removed; the next \"pm health\" run performs a full history-drift re-scan.');\n }\n return guidance;\n}\n\nexport async function runGc(global: GlobalOptions, options: GcCommandOptions = {}): Promise<GcResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);\n }\n\n await readSettings(pmRoot);\n const dryRun = options.dryRun === true;\n const scopes = parseScopes(options.scope);\n const selectedTargets = GC_TARGETS.filter((target) => scopes.includes(target.scope));\n\n const removed: string[] = [];\n const retained: string[] = [];\n const warnings: string[] = [];\n\n for (const target of selectedTargets) {\n const result = await removeCacheFile(pmRoot, target, dryRun);\n if (result.removed) {\n removed.push(target.relativePath);\n } else {\n retained.push(target.relativePath);\n }\n warnings.push(...result.warnings);\n }\n\n // The locks scope is not a path-based GC_TARGET: it sweeps the locks/ directory\n // and removes only locks whose own embedded ttl has expired (crashed-process\n // debris), retaining active and unparseable locks. See core/lock/lock-gc.ts.\n let locksSummary: GcLocksSummary | undefined;\n if (scopes.includes(\"locks\")) {\n const lockResult = await runLockGc(pmRoot, {\n dryRun,\n hooks: {\n onRead: (lockPath) => runActiveOnReadHooks({ path: lockPath, scope: \"project\" }),\n onWrite: (lockPath) => runActiveOnWriteHooks({ path: lockPath, scope: \"project\", op: \"gc:lock_remove\" }),\n },\n });\n removed.push(...lockResult.removed);\n retained.push(...lockResult.retained);\n warnings.push(...lockResult.warnings);\n locksSummary = {\n scanned: lockResult.scanned,\n removed: lockResult.removed.length,\n retained: lockResult.retained.length,\n };\n }\n\n warnings.push(\n ...(await runActiveOnIndexHooks({\n mode: dryRun ? \"gc:dry-run\" : \"gc\",\n total_items: selectedTargets.length,\n })),\n );\n const guidance = buildGcGuidance({\n dryRun,\n scopes,\n removed,\n });\n\n return {\n ok: warnings.length === 0,\n dry_run: dryRun,\n scope: scopes,\n removed,\n retained,\n warnings,\n ...(locksSummary ? { locks: locksSummary } : {}),\n guidance,\n generated_at: nowIso(),\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["global"]
7
+ }
@@ -1,7 +1,12 @@
1
1
  import {
2
- buildRemediationMap,
2
+ buildRemediationMap
3
+ } from "./chunk-R4VWYWRN.js";
4
+ import {
5
+ scanLockHealth
6
+ } from "./chunk-NAWVUHXH.js";
7
+ import {
3
8
  scanHistoryDrift
4
- } from "./chunk-LCSCXBGT.js";
9
+ } from "./chunk-R2OUQVBK.js";
5
10
  import {
6
11
  collectStaleVectorizationIds
7
12
  } from "./chunk-QAJBIGRA.js";
@@ -72,7 +77,7 @@ import path from "node:path";
72
77
  !(function() {
73
78
  try {
74
79
  var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
75
- n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "aa444802-31ea-5656-a3d6-8ed0ea39244f");
80
+ n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "aea76476-f15d-5223-8832-76e396aceb72");
76
81
  } catch (e2) {
77
82
  }
78
83
  })();
@@ -710,6 +715,14 @@ function summarizeHealthCheckDetails(check, limit) {
710
715
  if (check.name === "storage") {
711
716
  return details;
712
717
  }
718
+ if (check.name === "locks") {
719
+ return {
720
+ active_lock_count: details.active_lock_count,
721
+ stale_lock_count: details.stale_lock_count,
722
+ unreadable_lock_count: details.unreadable_lock_count,
723
+ unparseable_lock_count: details.unparseable_lock_count
724
+ };
725
+ }
713
726
  if (check.name === "integrity") {
714
727
  return {
715
728
  checked_item_files: details.checked_item_files,
@@ -1014,6 +1027,50 @@ async function buildTelemetryCheck(settings, options) {
1014
1027
  warnings
1015
1028
  };
1016
1029
  }
1030
+ async function buildLocksCheck(pmRoot) {
1031
+ let scan;
1032
+ try {
1033
+ scan = await scanLockHealth(pmRoot);
1034
+ } catch (error) {
1035
+ const message = error instanceof Error ? error.message : String(error);
1036
+ return {
1037
+ check: {
1038
+ name: "locks",
1039
+ status: "warn",
1040
+ details: {
1041
+ active_lock_count: 0,
1042
+ stale_lock_count: 0,
1043
+ unreadable_lock_count: 0,
1044
+ unparseable_lock_count: 0,
1045
+ scan_failed: true,
1046
+ error: message,
1047
+ pm_root: pmRoot
1048
+ }
1049
+ },
1050
+ warnings: [`locks_scan_failed:${message}`]
1051
+ };
1052
+ }
1053
+ const warnings = [];
1054
+ if (scan.stale_lock_count > 0) {
1055
+ warnings.push(`locks_stale_count:${scan.stale_lock_count}`);
1056
+ }
1057
+ if (scan.unreadable_lock_count > 0) {
1058
+ warnings.push(`locks_unreadable:${scan.unreadable_lock_count}`);
1059
+ }
1060
+ return {
1061
+ check: {
1062
+ name: "locks",
1063
+ status: warnings.length === 0 ? "ok" : "warn",
1064
+ details: {
1065
+ active_lock_count: scan.active_lock_count,
1066
+ stale_lock_count: scan.stale_lock_count,
1067
+ unreadable_lock_count: scan.unreadable_lock_count,
1068
+ unparseable_lock_count: scan.unparseable_lock_count
1069
+ }
1070
+ },
1071
+ warnings
1072
+ };
1073
+ }
1017
1074
  async function buildHistoryDriftCheck(pmRoot, items) {
1018
1075
  const { missingStreams, unreadableStreams, hashMismatches, chainMismatches, driftedItems } = await scanHistoryDrift(pmRoot, items);
1019
1076
  const warnings = [
@@ -1210,6 +1267,7 @@ async function runHealth(global2, options = {}) {
1210
1267
  commandLabel: "health"
1211
1268
  });
1212
1269
  const historySummary = await countHistoryStreams(pmRoot);
1270
+ const locksCheck = await buildLocksCheck(pmRoot);
1213
1271
  const integrityCheck = skipIntegrity ? { check: { name: "integrity", status: "ok", details: { skipped: true } }, warnings: [] } : await buildIntegrityCheck(pmRoot, typeRegistry.type_to_folder, settings.schema);
1214
1272
  const historyDriftCheck = skipDrift ? { check: { name: "history_drift", status: "ok", details: { skipped: true } }, warnings: [] } : await buildHistoryDriftCheck(pmRoot, itemsWithBody);
1215
1273
  const vectorizationCheck = skipVectors ? { check: { name: "vectorization", status: "ok", details: { skipped: true } }, warnings: [] } : await buildVectorizationCheck(pmRoot, settings, itemsWithBody, refreshPolicy, options.verboseStaleItems === true);
@@ -1254,6 +1312,7 @@ async function runHealth(global2, options = {}) {
1254
1312
  history_streams: historySummary.count
1255
1313
  }
1256
1314
  },
1315
+ locksCheck.check,
1257
1316
  integrityCheck.check,
1258
1317
  historyDriftCheck.check,
1259
1318
  vectorizationCheck.check
@@ -1267,6 +1326,7 @@ async function runHealth(global2, options = {}) {
1267
1326
  ...extensionCheck.warnings,
1268
1327
  ...historyPolicy.warnings,
1269
1328
  ...historySummary.warnings,
1329
+ ...locksCheck.warnings,
1270
1330
  ...integrityCheck.warnings,
1271
1331
  ...historyDriftCheck.warnings,
1272
1332
  ...vectorizationCheck.warnings,
@@ -1278,16 +1338,23 @@ async function runHealth(global2, options = {}) {
1278
1338
  directories: missingDirs.map((dir) => `missing_directory:${dir}`),
1279
1339
  settings_values: settingWarnings,
1280
1340
  telemetry: telemetryCheck.warnings,
1341
+ locks: locksCheck.warnings,
1281
1342
  integrity: integrityCheck.warnings,
1282
1343
  history_drift: historyDriftCheck.warnings,
1283
1344
  vectorization: vectorizationCheck.warnings
1284
1345
  };
1346
+ const historyDriftedCount = typeof historyDriftCheck.check.details.counts?.drifted === "number" ? historyDriftCheck.check.details.counts.drifted : 0;
1285
1347
  for (const check of checks) {
1286
1348
  const sources = checkRemediationSources[check.name];
1287
1349
  if (sources === void 0) {
1288
1350
  continue;
1289
1351
  }
1290
1352
  const remediationMap = buildRemediationMap(sources);
1353
+ if (check.name === "history_drift" && historyDriftedCount > 1) {
1354
+ for (const code of Object.keys(remediationMap)) {
1355
+ remediationMap[code] = "pm history-repair --all";
1356
+ }
1357
+ }
1291
1358
  if (Object.keys(remediationMap).length > 0) {
1292
1359
  check.details = { ...check.details, remediation_map: remediationMap };
1293
1360
  }
@@ -1307,4 +1374,4 @@ async function runHealth(global2, options = {}) {
1307
1374
  export {
1308
1375
  runHealth
1309
1376
  };
1310
- //# sourceMappingURL=health-YO5LRWN4.js.map
1377
+ //# sourceMappingURL=health-7MTXAVR2.js.map