@unbrained/pm-cli 2026.5.10 → 2026.5.11

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 (124) hide show
  1. package/.claude-plugin/marketplace.json +4 -4
  2. package/.pi/README.md +10 -1
  3. package/.pi/agents/pm-triage-agent.md +19 -0
  4. package/.pi/agents/pm-verification-agent.md +21 -0
  5. package/.pi/chains/pm-native-delivery.chain.md +11 -0
  6. package/.pi/extensions/pm-cli/index.js +276 -36
  7. package/.pi/skills/pm-native/SKILL.md +6 -2
  8. package/CHANGELOG.md +7 -0
  9. package/README.md +9 -1
  10. package/dist/cli/argv-utils.d.ts +5 -0
  11. package/dist/cli/argv-utils.js +34 -0
  12. package/dist/cli/argv-utils.js.map +1 -0
  13. package/dist/cli/bootstrap-args.d.ts +15 -0
  14. package/dist/cli/bootstrap-args.js +211 -0
  15. package/dist/cli/bootstrap-args.js.map +1 -1
  16. package/dist/cli/commander-usage.js +109 -3
  17. package/dist/cli/commander-usage.js.map +1 -1
  18. package/dist/cli/commands/completion.js +7 -3
  19. package/dist/cli/commands/completion.js.map +1 -1
  20. package/dist/cli/commands/contracts.d.ts +19 -0
  21. package/dist/cli/commands/contracts.js +33 -1
  22. package/dist/cli/commands/contracts.js.map +1 -1
  23. package/dist/cli/commands/create.js +112 -51
  24. package/dist/cli/commands/create.js.map +1 -1
  25. package/dist/cli/commands/docs.js +9 -2
  26. package/dist/cli/commands/docs.js.map +1 -1
  27. package/dist/cli/commands/extension.d.ts +3 -1
  28. package/dist/cli/commands/extension.js +174 -2
  29. package/dist/cli/commands/extension.js.map +1 -1
  30. package/dist/cli/commands/files.js +9 -2
  31. package/dist/cli/commands/files.js.map +1 -1
  32. package/dist/cli/commands/init.d.ts +2 -0
  33. package/dist/cli/commands/init.js +21 -1
  34. package/dist/cli/commands/init.js.map +1 -1
  35. package/dist/cli/commands/metadata-normalizers.d.ts +4 -0
  36. package/dist/cli/commands/metadata-normalizers.js +37 -0
  37. package/dist/cli/commands/metadata-normalizers.js.map +1 -0
  38. package/dist/cli/commands/reindex.js +173 -135
  39. package/dist/cli/commands/reindex.js.map +1 -1
  40. package/dist/cli/commands/search.js +16 -6
  41. package/dist/cli/commands/search.js.map +1 -1
  42. package/dist/cli/commands/test.js +9 -2
  43. package/dist/cli/commands/test.js.map +1 -1
  44. package/dist/cli/commands/update.js +70 -39
  45. package/dist/cli/commands/update.js.map +1 -1
  46. package/dist/cli/error-guidance.d.ts +9 -1
  47. package/dist/cli/error-guidance.js +147 -6
  48. package/dist/cli/error-guidance.js.map +1 -1
  49. package/dist/cli/help-json-payload.js +11 -1
  50. package/dist/cli/help-json-payload.js.map +1 -1
  51. package/dist/cli/main.js +69 -6
  52. package/dist/cli/main.js.map +1 -1
  53. package/dist/cli/register-setup.js +14 -0
  54. package/dist/cli/register-setup.js.map +1 -1
  55. package/dist/cli/telemetry-flush.d.ts +2 -0
  56. package/dist/cli/telemetry-flush.js +4 -0
  57. package/dist/cli/telemetry-flush.js.map +1 -0
  58. package/dist/cli.js +1 -2
  59. package/dist/cli.js.map +1 -1
  60. package/dist/core/extensions/extension-types.d.ts +72 -0
  61. package/dist/core/extensions/extension-types.js +24 -0
  62. package/dist/core/extensions/extension-types.js.map +1 -1
  63. package/dist/core/extensions/loader.d.ts +1 -0
  64. package/dist/core/extensions/loader.js +766 -7
  65. package/dist/core/extensions/loader.js.map +1 -1
  66. package/dist/core/lock/lock.js +2 -0
  67. package/dist/core/lock/lock.js.map +1 -1
  68. package/dist/core/sentry/instrument.d.ts +15 -0
  69. package/dist/core/sentry/instrument.js +35 -3
  70. package/dist/core/sentry/instrument.js.map +1 -1
  71. package/dist/core/shared/constants.js +20 -0
  72. package/dist/core/shared/constants.js.map +1 -1
  73. package/dist/core/shared/errors.d.ts +8 -0
  74. package/dist/core/shared/errors.js.map +1 -1
  75. package/dist/core/shared/levenshtein.d.ts +1 -0
  76. package/dist/core/shared/levenshtein.js +37 -0
  77. package/dist/core/shared/levenshtein.js.map +1 -0
  78. package/dist/core/store/paths.js +34 -1
  79. package/dist/core/store/paths.js.map +1 -1
  80. package/dist/core/store/settings.js +210 -1
  81. package/dist/core/store/settings.js.map +1 -1
  82. package/dist/core/telemetry/runtime.d.ts +1 -0
  83. package/dist/core/telemetry/runtime.js +102 -3
  84. package/dist/core/telemetry/runtime.js.map +1 -1
  85. package/dist/mcp/server.js +3 -1
  86. package/dist/mcp/server.js.map +1 -1
  87. package/dist/pi/native.js +57 -4
  88. package/dist/pi/native.js.map +1 -1
  89. package/dist/sdk/cli-contracts.d.ts +21 -1
  90. package/dist/sdk/cli-contracts.js +250 -0
  91. package/dist/sdk/cli-contracts.js.map +1 -1
  92. package/dist/sdk/index.d.ts +12 -1
  93. package/dist/sdk/index.js +8 -1
  94. package/dist/sdk/index.js.map +1 -1
  95. package/dist/types.d.ts +41 -0
  96. package/dist/types.js.map +1 -1
  97. package/docs/CLAUDE_CODE_PLUGIN.md +39 -0
  98. package/docs/EXTENSIONS.md +687 -0
  99. package/docs/MIGRATION_CLI_SIMPLIFICATION.md +64 -0
  100. package/docs/PI_PACKAGE.md +95 -10
  101. package/docs/SDK.md +441 -0
  102. package/docs/examples/ci/github-actions-pm-extension-gate.yml +53 -0
  103. package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +41 -0
  104. package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +45 -0
  105. package/docs/examples/policy-restricted-extension/README.md +74 -0
  106. package/docs/examples/policy-restricted-extension/index.js +21 -0
  107. package/docs/examples/policy-restricted-extension/manifest.json +21 -0
  108. package/docs/examples/policy-restricted-extension/package.json +8 -0
  109. package/docs/examples/sdk-app-embedding/README.md +39 -0
  110. package/docs/examples/sdk-app-embedding/package.json +9 -0
  111. package/docs/examples/sdk-app-embedding/run-embedded-pm.mjs +61 -0
  112. package/docs/examples/sdk-contract-consumer/README.md +57 -0
  113. package/docs/examples/sdk-contract-consumer/inspect-contracts.mjs +47 -0
  114. package/docs/examples/sdk-contract-consumer/package.json +10 -0
  115. package/docs/examples/starter-extension/README.md +57 -42
  116. package/docs/examples/starter-extension/manifest.json +15 -0
  117. package/marketplace.json +3 -3
  118. package/package.json +1 -1
  119. package/plugins/pm-cli-claude/.claude-plugin/plugin.json +2 -2
  120. package/plugins/pm-cli-claude/README.md +55 -14
  121. package/plugins/pm-cli-claude/agents/pm-delivery-chain.md +88 -0
  122. package/plugins/pm-cli-claude/agents/pm-triage-agent.md +83 -0
  123. package/plugins/pm-cli-claude/agents/pm-verification-agent.md +88 -0
  124. package/plugins/pm-cli-claude/hooks/session-start.mjs +87 -22
@@ -1,4 +1,5 @@
1
1
  import fs from "node:fs/promises";
2
+ import path from "node:path";
2
3
  import { runActiveOnReadHooks, runActiveOnWriteHooks, runActiveServiceOverride } from "../extensions/index.js";
3
4
  import { EXIT_CODE } from "../shared/constants.js";
4
5
  import { PmCliError } from "../shared/errors.js";
@@ -93,6 +94,7 @@ function buildLockPayload(id, owner, ttlSeconds) {
93
94
  };
94
95
  }
95
96
  async function createLockFile(lockPath, id, owner, ttlSeconds) {
97
+ await fs.mkdir(path.dirname(lockPath), { recursive: true });
96
98
  const handle = await fs.open(lockPath, "wx");
97
99
  try {
98
100
  await handle.writeFile(`${JSON.stringify(buildLockPayload(id, owner, ttlSeconds), null, 2)}\n`, "utf8");
@@ -1 +1 @@
1
- {"version":3,"file":"lock.js","sourceRoot":"/","sources":["core/lock/lock.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport { runActiveOnReadHooks, runActiveOnWriteHooks, runActiveServiceOverride } from \"../extensions/index.js\";\nimport { EXIT_CODE } from \"../shared/constants.js\";\nimport { PmCliError } from \"../shared/errors.js\";\nimport { toErrorMessage } from \"../shared/primitives.js\";\nimport { getLockPath } from \"../store/paths.js\";\nimport { nowIso } from \"../shared/time.js\";\n\ninterface LockInfo {\n id: string;\n pid: number;\n owner: string;\n created_at: string;\n ttl_seconds: number;\n}\n\ntype LockWriteOp = \"lock:create\" | \"lock:release\" | \"lock:stale_remove\";\n\ninterface LockReadResult {\n info: LockInfo | null;\n warnings: string[];\n}\n\nfunction parseLockInfo(raw: string): LockReadResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw) as unknown;\n } catch {\n return {\n info: null,\n warnings: [\"lock_info_invalid_json\"],\n };\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return {\n info: null,\n warnings: [\"lock_info_invalid_shape\"],\n };\n }\n const candidate = parsed as Record<string, unknown>;\n const id = candidate.id;\n const pid = candidate.pid;\n const owner = candidate.owner;\n const createdAt = candidate.created_at;\n const ttlSeconds = candidate.ttl_seconds;\n if (\n typeof id !== \"string\" ||\n typeof pid !== \"number\" ||\n !Number.isFinite(pid) ||\n typeof owner !== \"string\" ||\n typeof createdAt !== \"string\" ||\n typeof ttlSeconds !== \"number\" ||\n !Number.isFinite(ttlSeconds)\n ) {\n return {\n info: null,\n warnings: [\"lock_info_invalid_shape\"],\n };\n }\n return {\n info: {\n id,\n pid,\n owner,\n created_at: createdAt,\n ttl_seconds: ttlSeconds,\n },\n warnings: [],\n };\n}\n\nasync function readLockInfo(lockPath: string): Promise<LockReadResult> {\n try {\n const raw = await fs.readFile(lockPath, \"utf8\");\n await runActiveOnReadHooks({\n path: lockPath,\n scope: \"project\",\n });\n return parseLockInfo(raw);\n } catch (error: unknown) {\n if (isErrno(error, \"ENOENT\")) {\n return {\n info: null,\n warnings: [],\n };\n }\n return {\n info: null,\n warnings: [\"lock_info_read_failed\"],\n };\n }\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 emitLockWriteHook(lockPath: string, op: LockWriteOp): Promise<void> {\n await runActiveOnWriteHooks({\n path: lockPath,\n scope: \"project\",\n op,\n });\n}\n\nfunction buildLockPayload(id: string, owner: string, ttlSeconds: number): LockInfo {\n return {\n id,\n pid: process.pid,\n owner,\n created_at: nowIso(),\n ttl_seconds: ttlSeconds,\n };\n}\n\nasync function createLockFile(lockPath: string, id: string, owner: string, ttlSeconds: number): Promise<void> {\n const handle = await fs.open(lockPath, \"wx\");\n try {\n await handle.writeFile(`${JSON.stringify(buildLockPayload(id, owner, ttlSeconds), null, 2)}\\n`, \"utf8\");\n } finally {\n await handle.close();\n }\n await emitLockWriteHook(lockPath, \"lock:create\");\n}\n\nasync function unlinkLockWithHook(lockPath: string, op: \"lock:release\" | \"lock:stale_remove\"): Promise<void> {\n try {\n await fs.unlink(lockPath);\n await emitLockWriteHook(lockPath, op);\n } catch {\n // Lock cleanup is best-effort.\n }\n}\n\nfunction isStaleLock(info: LockInfo | null, ttlSeconds: number): boolean {\n const createdAtMs = info?.created_at ? Date.parse(info.created_at) : Number.NaN;\n const ageMs = Number.isFinite(createdAtMs) ? Date.now() - createdAtMs : Number.POSITIVE_INFINITY;\n return ageMs > ttlSeconds * 1000;\n}\n\nfunction lockOwnerSuffix(info: LockInfo | null): string {\n return info?.owner ? ` (owner ${info.owner})` : \"\";\n}\n\nasync function handleExistingLock(\n lockPath: string,\n id: string,\n ttlSeconds: number,\n force: boolean,\n forceRequiredForStaleLock: boolean,\n): Promise<void> {\n const lockInfo = await readLockInfo(lockPath);\n if (!isStaleLock(lockInfo.info, ttlSeconds)) {\n throw new PmCliError(`Item ${id} is locked${lockOwnerSuffix(lockInfo.info)}`, EXIT_CODE.CONFLICT);\n }\n\n if (!force && forceRequiredForStaleLock) {\n const warningSuffix = lockInfo.warnings.length > 0 ? ` (${lockInfo.warnings.join(\",\")})` : \"\";\n throw new PmCliError(\n `Item ${id} lock is stale${warningSuffix}; rerun with --force when supported for this command`,\n EXIT_CODE.CONFLICT,\n );\n }\n\n await unlinkLockWithHook(lockPath, \"lock:stale_remove\");\n}\n\n\nexport async function acquireLock(\n pmRoot: string,\n id: string,\n ttlSeconds: number,\n owner: string,\n force = false,\n forceRequiredForStaleLock = true,\n): Promise<() => Promise<void>> {\n const lockOverride = await runActiveServiceOverride(\"lock_acquire\", {\n pm_root: pmRoot,\n id,\n ttl_seconds: ttlSeconds,\n owner,\n force,\n force_required_for_stale_lock: forceRequiredForStaleLock,\n });\n if (lockOverride.handled) {\n const releaseFromFunction = typeof lockOverride.result === \"function\" ? lockOverride.result : null;\n const releaseFromObject =\n typeof lockOverride.result === \"object\" &&\n lockOverride.result !== null &&\n \"release\" in lockOverride.result &&\n typeof (lockOverride.result as { release?: unknown }).release === \"function\"\n ? ((lockOverride.result as { release: () => Promise<void> | void }).release as () => Promise<void> | void)\n : null;\n const release = releaseFromFunction ?? releaseFromObject;\n if (release) {\n return async () => {\n await Promise.resolve(release());\n await runActiveServiceOverride(\"lock_release\", {\n pm_root: pmRoot,\n id,\n owner,\n });\n };\n }\n }\n\n const lockPath = getLockPath(pmRoot, id);\n\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n await createLockFile(lockPath, id, owner, ttlSeconds);\n return async () => {\n await unlinkLockWithHook(lockPath, \"lock:release\");\n await runActiveServiceOverride(\"lock_release\", {\n pm_root: pmRoot,\n id,\n owner,\n });\n };\n } catch (error: unknown) {\n if (!isErrno(error, \"EEXIST\")) {\n throw new PmCliError(`Failed to acquire lock for ${id}: ${toErrorMessage(error)}`, EXIT_CODE.GENERIC_FAILURE);\n }\n await handleExistingLock(lockPath, id, ttlSeconds, force, forceRequiredForStaleLock);\n }\n }\n\n throw new PmCliError(`Failed to acquire lock for ${id}`, EXIT_CODE.CONFLICT);\n}\n"]}
1
+ {"version":3,"file":"lock.js","sourceRoot":"/","sources":["core/lock/lock.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { runActiveOnReadHooks, runActiveOnWriteHooks, runActiveServiceOverride } from \"../extensions/index.js\";\nimport { EXIT_CODE } from \"../shared/constants.js\";\nimport { PmCliError } from \"../shared/errors.js\";\nimport { toErrorMessage } from \"../shared/primitives.js\";\nimport { getLockPath } from \"../store/paths.js\";\nimport { nowIso } from \"../shared/time.js\";\n\ninterface LockInfo {\n id: string;\n pid: number;\n owner: string;\n created_at: string;\n ttl_seconds: number;\n}\n\ntype LockWriteOp = \"lock:create\" | \"lock:release\" | \"lock:stale_remove\";\n\ninterface LockReadResult {\n info: LockInfo | null;\n warnings: string[];\n}\n\nfunction parseLockInfo(raw: string): LockReadResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw) as unknown;\n } catch {\n return {\n info: null,\n warnings: [\"lock_info_invalid_json\"],\n };\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return {\n info: null,\n warnings: [\"lock_info_invalid_shape\"],\n };\n }\n const candidate = parsed as Record<string, unknown>;\n const id = candidate.id;\n const pid = candidate.pid;\n const owner = candidate.owner;\n const createdAt = candidate.created_at;\n const ttlSeconds = candidate.ttl_seconds;\n if (\n typeof id !== \"string\" ||\n typeof pid !== \"number\" ||\n !Number.isFinite(pid) ||\n typeof owner !== \"string\" ||\n typeof createdAt !== \"string\" ||\n typeof ttlSeconds !== \"number\" ||\n !Number.isFinite(ttlSeconds)\n ) {\n return {\n info: null,\n warnings: [\"lock_info_invalid_shape\"],\n };\n }\n return {\n info: {\n id,\n pid,\n owner,\n created_at: createdAt,\n ttl_seconds: ttlSeconds,\n },\n warnings: [],\n };\n}\n\nasync function readLockInfo(lockPath: string): Promise<LockReadResult> {\n try {\n const raw = await fs.readFile(lockPath, \"utf8\");\n await runActiveOnReadHooks({\n path: lockPath,\n scope: \"project\",\n });\n return parseLockInfo(raw);\n } catch (error: unknown) {\n if (isErrno(error, \"ENOENT\")) {\n return {\n info: null,\n warnings: [],\n };\n }\n return {\n info: null,\n warnings: [\"lock_info_read_failed\"],\n };\n }\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 emitLockWriteHook(lockPath: string, op: LockWriteOp): Promise<void> {\n await runActiveOnWriteHooks({\n path: lockPath,\n scope: \"project\",\n op,\n });\n}\n\nfunction buildLockPayload(id: string, owner: string, ttlSeconds: number): LockInfo {\n return {\n id,\n pid: process.pid,\n owner,\n created_at: nowIso(),\n ttl_seconds: ttlSeconds,\n };\n}\n\nasync function createLockFile(lockPath: string, id: string, owner: string, ttlSeconds: number): Promise<void> {\n await fs.mkdir(path.dirname(lockPath), { recursive: true });\n const handle = await fs.open(lockPath, \"wx\");\n try {\n await handle.writeFile(`${JSON.stringify(buildLockPayload(id, owner, ttlSeconds), null, 2)}\\n`, \"utf8\");\n } finally {\n await handle.close();\n }\n await emitLockWriteHook(lockPath, \"lock:create\");\n}\n\nasync function unlinkLockWithHook(lockPath: string, op: \"lock:release\" | \"lock:stale_remove\"): Promise<void> {\n try {\n await fs.unlink(lockPath);\n await emitLockWriteHook(lockPath, op);\n } catch {\n // Lock cleanup is best-effort.\n }\n}\n\nfunction isStaleLock(info: LockInfo | null, ttlSeconds: number): boolean {\n const createdAtMs = info?.created_at ? Date.parse(info.created_at) : Number.NaN;\n const ageMs = Number.isFinite(createdAtMs) ? Date.now() - createdAtMs : Number.POSITIVE_INFINITY;\n return ageMs > ttlSeconds * 1000;\n}\n\nfunction lockOwnerSuffix(info: LockInfo | null): string {\n return info?.owner ? ` (owner ${info.owner})` : \"\";\n}\n\nasync function handleExistingLock(\n lockPath: string,\n id: string,\n ttlSeconds: number,\n force: boolean,\n forceRequiredForStaleLock: boolean,\n): Promise<void> {\n const lockInfo = await readLockInfo(lockPath);\n if (!isStaleLock(lockInfo.info, ttlSeconds)) {\n throw new PmCliError(`Item ${id} is locked${lockOwnerSuffix(lockInfo.info)}`, EXIT_CODE.CONFLICT);\n }\n\n if (!force && forceRequiredForStaleLock) {\n const warningSuffix = lockInfo.warnings.length > 0 ? ` (${lockInfo.warnings.join(\",\")})` : \"\";\n throw new PmCliError(\n `Item ${id} lock is stale${warningSuffix}; rerun with --force when supported for this command`,\n EXIT_CODE.CONFLICT,\n );\n }\n\n await unlinkLockWithHook(lockPath, \"lock:stale_remove\");\n}\n\n\nexport async function acquireLock(\n pmRoot: string,\n id: string,\n ttlSeconds: number,\n owner: string,\n force = false,\n forceRequiredForStaleLock = true,\n): Promise<() => Promise<void>> {\n const lockOverride = await runActiveServiceOverride(\"lock_acquire\", {\n pm_root: pmRoot,\n id,\n ttl_seconds: ttlSeconds,\n owner,\n force,\n force_required_for_stale_lock: forceRequiredForStaleLock,\n });\n if (lockOverride.handled) {\n const releaseFromFunction = typeof lockOverride.result === \"function\" ? lockOverride.result : null;\n const releaseFromObject =\n typeof lockOverride.result === \"object\" &&\n lockOverride.result !== null &&\n \"release\" in lockOverride.result &&\n typeof (lockOverride.result as { release?: unknown }).release === \"function\"\n ? ((lockOverride.result as { release: () => Promise<void> | void }).release as () => Promise<void> | void)\n : null;\n const release = releaseFromFunction ?? releaseFromObject;\n if (release) {\n return async () => {\n await Promise.resolve(release());\n await runActiveServiceOverride(\"lock_release\", {\n pm_root: pmRoot,\n id,\n owner,\n });\n };\n }\n }\n\n const lockPath = getLockPath(pmRoot, id);\n\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n await createLockFile(lockPath, id, owner, ttlSeconds);\n return async () => {\n await unlinkLockWithHook(lockPath, \"lock:release\");\n await runActiveServiceOverride(\"lock_release\", {\n pm_root: pmRoot,\n id,\n owner,\n });\n };\n } catch (error: unknown) {\n if (!isErrno(error, \"EEXIST\")) {\n throw new PmCliError(`Failed to acquire lock for ${id}: ${toErrorMessage(error)}`, EXIT_CODE.GENERIC_FAILURE);\n }\n await handleExistingLock(lockPath, id, ttlSeconds, force, forceRequiredForStaleLock);\n }\n }\n\n throw new PmCliError(`Failed to acquire lock for ${id}`, EXIT_CODE.CONFLICT);\n}\n"]}
@@ -1,6 +1,15 @@
1
1
  declare function scrubString(value: string, keyHint?: string): string;
2
2
  declare function scrubEventData(obj: Record<string, unknown>): Record<string, unknown>;
3
3
  type SentryLike = typeof import("@sentry/node");
4
+ declare function isKnownNoisyConsoleEvent(event: {
5
+ logger?: string;
6
+ message?: string;
7
+ exception?: {
8
+ values?: Array<{
9
+ value?: string;
10
+ }>;
11
+ };
12
+ }): boolean;
4
13
  declare function isExpectedCliErrorEvent(event: {
5
14
  exception?: {
6
15
  values?: Array<{
@@ -16,11 +25,17 @@ declare function isPmCliErrorBreadcrumb(breadcrumb: {
16
25
  category?: string;
17
26
  message?: string;
18
27
  }): boolean;
28
+ declare function isKnownNoisyConsoleBreadcrumb(breadcrumb: {
29
+ category?: string;
30
+ message?: string;
31
+ }): boolean;
19
32
  export declare function ensureSentryInit(): Promise<SentryLike | undefined>;
20
33
  export declare function getSentry(): SentryLike | undefined;
21
34
  export declare const _testOnly: {
22
35
  isExpectedCliErrorEvent: typeof isExpectedCliErrorEvent;
36
+ isKnownNoisyConsoleEvent: typeof isKnownNoisyConsoleEvent;
23
37
  isPmCliErrorBreadcrumb: typeof isPmCliErrorBreadcrumb;
38
+ isKnownNoisyConsoleBreadcrumb: typeof isKnownNoisyConsoleBreadcrumb;
24
39
  scrubString: typeof scrubString;
25
40
  scrubEventData: typeof scrubEventData;
26
41
  };
@@ -18,6 +18,16 @@ const FILE_URL_PATH_RE = /file:\/\/\/?[^\s"'`),;]+/giu;
18
18
  const WINDOWS_PATH_TOKEN_RE = /\b[A-Za-z]:\\[^\s"'`),;]+/g;
19
19
  const PRIVATE_IP_RE = /\b(?:10\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|172\.(?:1[6-9]|2\d|3[01])\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|192\.168\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d))\b/g;
20
20
  const PATH_FIELD_KEY_PATTERN = /(?:^|[_-])(path|filename|file|module|cwd|dir|directory|location|source|script)s?$/i;
21
+ const KNOWN_NOISY_CONSOLE_MESSAGE_PATTERNS = [
22
+ "[starter-extension] activating",
23
+ "[starter-extension] all 8 capabilities registered.",
24
+ "[starter-extension] commands:",
25
+ "[starter] preflight check for workspace",
26
+ "[starter] output_format service override active",
27
+ "[pm-ext-ts-starter] activating",
28
+ "[pm-ext-ts-starter] all capabilities registered.",
29
+ "run `pm init` first to initialise a pm workspace",
30
+ ];
21
31
  function looksLikeFilesystemPath(value) {
22
32
  const normalized = value.trim();
23
33
  if (normalized.length === 0) {
@@ -109,6 +119,23 @@ const PM_CLI_SENTRY_DSN = "https://bf7ad2ec76c0051c2ee94e48e8bd6868@o45106034777
109
119
  function hasPmCliErrorPrefix(value) {
110
120
  return /^\s*PmCliError:/.test(value);
111
121
  }
122
+ function isKnownNoisyConsoleMessage(value) {
123
+ const normalized = value.trim().toLowerCase();
124
+ if (normalized.length === 0) {
125
+ return false;
126
+ }
127
+ return KNOWN_NOISY_CONSOLE_MESSAGE_PATTERNS.some((pattern) => normalized.includes(pattern));
128
+ }
129
+ function isKnownNoisyConsoleEvent(event) {
130
+ if (event.logger !== "console") {
131
+ return false;
132
+ }
133
+ if (typeof event.message === "string" && isKnownNoisyConsoleMessage(event.message)) {
134
+ return true;
135
+ }
136
+ return (Array.isArray(event.exception?.values) &&
137
+ event.exception.values.some((entry) => typeof entry.value === "string" && isKnownNoisyConsoleMessage(entry.value)));
138
+ }
112
139
  function isExpectedCliErrorEvent(event) {
113
140
  if (event.exception?.values?.some((ex) => ex.type === "PmCliError"))
114
141
  return true;
@@ -123,6 +150,9 @@ function isPmCliErrorBreadcrumb(breadcrumb) {
123
150
  typeof breadcrumb.message === "string" &&
124
151
  hasPmCliErrorPrefix(breadcrumb.message));
125
152
  }
153
+ function isKnownNoisyConsoleBreadcrumb(breadcrumb) {
154
+ return breadcrumb.category === "console" && typeof breadcrumb.message === "string" && isKnownNoisyConsoleMessage(breadcrumb.message);
155
+ }
126
156
  function resolveCliVersion() {
127
157
  try {
128
158
  const thisFile = fileURLToPath(import.meta.url);
@@ -188,7 +218,7 @@ export async function ensureSentryInit() {
188
218
  },
189
219
  },
190
220
  beforeSend(event) {
191
- if (isExpectedCliErrorEvent(event)) {
221
+ if (isExpectedCliErrorEvent(event) || isKnownNoisyConsoleEvent(event)) {
192
222
  return null;
193
223
  }
194
224
  if (event.message) {
@@ -242,7 +272,7 @@ export async function ensureSentryInit() {
242
272
  },
243
273
  beforeSendTransaction(event) {
244
274
  if (event.breadcrumbs) {
245
- event.breadcrumbs = event.breadcrumbs.filter((bc) => !isPmCliErrorBreadcrumb(bc));
275
+ event.breadcrumbs = event.breadcrumbs.filter((bc) => !isPmCliErrorBreadcrumb(bc) && !isKnownNoisyConsoleBreadcrumb(bc));
246
276
  for (const breadcrumb of event.breadcrumbs) {
247
277
  if (breadcrumb.message) {
248
278
  breadcrumb.message = scrubString(breadcrumb.message, "message");
@@ -262,7 +292,7 @@ export async function ensureSentryInit() {
262
292
  return event;
263
293
  },
264
294
  beforeBreadcrumb(breadcrumb) {
265
- if (isPmCliErrorBreadcrumb(breadcrumb)) {
295
+ if (isPmCliErrorBreadcrumb(breadcrumb) || isKnownNoisyConsoleBreadcrumb(breadcrumb)) {
266
296
  return null;
267
297
  }
268
298
  if (breadcrumb.message) {
@@ -281,7 +311,9 @@ export function getSentry() {
281
311
  }
282
312
  export const _testOnly = {
283
313
  isExpectedCliErrorEvent,
314
+ isKnownNoisyConsoleEvent,
284
315
  isPmCliErrorBreadcrumb,
316
+ isKnownNoisyConsoleBreadcrumb,
285
317
  scrubString,
286
318
  scrubEventData,
287
319
  };
@@ -1 +1 @@
1
- {"version":3,"file":"instrument.js","sourceRoot":"/","sources":["core/sentry/instrument.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst OPT_OUT_VALUES = new Set([\"1\", \"true\", \"yes\", \"on\"]);\n\nfunction isSentryDisabled(): boolean {\n if (OPT_OUT_VALUES.has((process.env.PM_SENTRY_DISABLED ?? \"\").trim().toLowerCase())) return true;\n if (OPT_OUT_VALUES.has((process.env.PM_TELEMETRY_DISABLED ?? \"\").trim().toLowerCase())) return true;\n if (process.env.VITEST || process.env.VITEST_WORKER_ID) return true;\n return false;\n}\n\nconst SENSITIVE_KEY_PATTERN =\n /(?:token|secret|password|passwd|api[_-]?key|apikey|authorization|cookie|credentials|bearer|dsn)/i;\n\nconst INLINE_SENSITIVE_ASSIGNMENT_RE = new RegExp(\n `\\\\b(${SENSITIVE_KEY_PATTERN.source})\\\\s*[:=]\\\\s*([^\\\\s,;]+)`,\n \"giu\",\n);\nconst ABSOLUTE_PATH_TOKEN_RE = /(^|[\\s\"'`(=])\\/(?:[^\\s\"'`),;]+)/g;\nconst FILE_URL_PATH_RE = /file:\\/\\/\\/?[^\\s\"'`),;]+/giu;\nconst WINDOWS_PATH_TOKEN_RE = /\\b[A-Za-z]:\\\\[^\\s\"'`),;]+/g;\nconst PRIVATE_IP_RE =\n /\\b(?:10\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)|172\\.(?:1[6-9]|2\\d|3[01])\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)|192\\.168\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))\\b/g;\nconst PATH_FIELD_KEY_PATTERN = /(?:^|[_-])(path|filename|file|module|cwd|dir|directory|location|source|script)s?$/i;\n\nfunction looksLikeFilesystemPath(value: string): boolean {\n const normalized = value.trim();\n if (normalized.length === 0) {\n return false;\n }\n if (normalized.startsWith(\"/\") || normalized.startsWith(\"file://\")) {\n return true;\n }\n if (/^[A-Za-z]:\\\\/.test(normalized) || normalized.startsWith(\"\\\\\\\\\")) {\n return true;\n }\n return normalized.includes(\"/home/\");\n}\n\nfunction scrubString(value: string, keyHint?: string): string {\n if (keyHint && PATH_FIELD_KEY_PATTERN.test(keyHint) && looksLikeFilesystemPath(value)) {\n return \"[scrubbed_path]\";\n }\n const scrubbed = value\n .replaceAll(INLINE_SENSITIVE_ASSIGNMENT_RE, (_m, key: string) => `${key}=[scrubbed]`)\n .replaceAll(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/giu, \"[scrubbed_email]\")\n .replaceAll(/bearer\\s+[a-z0-9._=-]+/giu, \"bearer [scrubbed]\")\n .replaceAll(/sntr[ysu]_[A-Za-z0-9_-]+/g, \"[scrubbed_sentry_token]\")\n .replaceAll(PRIVATE_IP_RE, \"[scrubbed_ip]\")\n .replaceAll(FILE_URL_PATH_RE, \"[scrubbed_path]\")\n .replaceAll(WINDOWS_PATH_TOKEN_RE, \"[scrubbed_path]\")\n .replaceAll(ABSOLUTE_PATH_TOKEN_RE, (_match: string, prefix: string) => `${prefix}[scrubbed_path]`);\n if (looksLikeFilesystemPath(scrubbed)) {\n return \"[scrubbed_path]\";\n }\n return scrubbed;\n}\n\nfunction scrubEventData(obj: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (SENSITIVE_KEY_PATTERN.test(key)) {\n result[key] = \"[scrubbed]\";\n } else if (typeof value === \"string\") {\n result[key] = scrubString(value, key);\n } else if (Array.isArray(value)) {\n result[key] = value.map((entry) => {\n if (typeof entry === \"string\") {\n return scrubString(entry, key);\n }\n if (entry && typeof entry === \"object\") {\n return scrubEventData(entry as Record<string, unknown>);\n }\n return entry;\n });\n } else if (value && typeof value === \"object\") {\n result[key] = scrubEventData(value as Record<string, unknown>);\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction scrubStackFrame(frame: Record<string, unknown>): void {\n for (const key of [\"filename\", \"absPath\", \"abs_path\", \"module\"]) {\n const rawValue = frame[key];\n if (typeof rawValue === \"string\") {\n frame[key] = scrubString(rawValue, key);\n }\n }\n const contextLine = frame.context_line;\n if (typeof contextLine === \"string\") {\n frame.context_line = scrubString(contextLine, \"context_line\");\n }\n for (const key of [\"pre_context\", \"post_context\"]) {\n const context = frame[key];\n if (!Array.isArray(context)) {\n continue;\n }\n frame[key] = context.map((entry) => (typeof entry === \"string\" ? scrubString(entry, key) : entry));\n }\n if (frame.vars && typeof frame.vars === \"object\") {\n frame.vars = scrubEventData(frame.vars as Record<string, unknown>);\n }\n if (frame.data && typeof frame.data === \"object\") {\n frame.data = scrubEventData(frame.data as Record<string, unknown>);\n }\n}\n\ntype SentryLike = typeof import(\"@sentry/node\");\n\nlet _sentry: SentryLike | undefined;\nlet _initDone = false;\n\nconst PM_CLI_SENTRY_DSN =\n \"https://bf7ad2ec76c0051c2ee94e48e8bd6868@o4510603477712896.ingest.de.sentry.io/4511316775338064\";\n\nfunction hasPmCliErrorPrefix(value: string): boolean {\n return /^\\s*PmCliError:/.test(value);\n}\n\nfunction isExpectedCliErrorEvent(event: {\n exception?: { values?: Array<{ type?: string; value?: string }> };\n message?: string;\n extra?: Record<string, unknown>;\n logger?: string;\n}): boolean {\n if (event.exception?.values?.some((ex) => ex.type === \"PmCliError\")) return true;\n\n if (event.exception?.values?.some((ex) => typeof ex.value === \"string\" && hasPmCliErrorPrefix(ex.value)))\n return true;\n\n if (event.logger === \"console\" && typeof event.message === \"string\" && hasPmCliErrorPrefix(event.message))\n return true;\n\n return false;\n}\n\nfunction isPmCliErrorBreadcrumb(breadcrumb: { category?: string; message?: string }): boolean {\n return (\n breadcrumb.category === \"console\" &&\n typeof breadcrumb.message === \"string\" &&\n hasPmCliErrorPrefix(breadcrumb.message)\n );\n}\n\nfunction resolveCliVersion(): string {\n try {\n const thisFile = fileURLToPath(import.meta.url);\n const candidates = [\n path.resolve(thisFile, \"../../../../package.json\"),\n path.resolve(thisFile, \"../../../package.json\"),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n const parsed = JSON.parse(fs.readFileSync(candidate, \"utf8\")) as { version?: string };\n if (typeof parsed.version === \"string\") return parsed.version;\n }\n }\n } catch {\n // Version resolution must never block startup.\n }\n return \"0.0.0\";\n}\n\nfunction resolveEnvironment(): string {\n const explicit = process.env.SENTRY_ENVIRONMENT?.trim();\n if (explicit && explicit.length > 0) return explicit;\n if (process.env.VITEST || process.env.VITEST_WORKER_ID || process.env.NODE_ENV === \"test\") return \"test\";\n if (process.env.CI) return \"ci\";\n return \"production\";\n}\n\nexport async function ensureSentryInit(): Promise<SentryLike | undefined> {\n if (_initDone) return _sentry;\n _initDone = true;\n\n if (isSentryDisabled()) return undefined;\n\n const SentryModule = await import(\"@sentry/node\");\n _sentry = SentryModule;\n\n const dsn = process.env.SENTRY_DSN?.trim() || PM_CLI_SENTRY_DSN;\n const release = resolveCliVersion();\n\n SentryModule.init({\n dsn,\n release: `pm-cli@${release}`,\n environment: resolveEnvironment(),\n\n tracesSampleRate: 0.2,\n enableLogs: true,\n attachStacktrace: true,\n normalizeDepth: 6,\n shutdownTimeout: 3000,\n sendDefaultPii: false,\n serverName: undefined,\n\n integrations: [\n SentryModule.extraErrorDataIntegration({ depth: 4 }),\n SentryModule.captureConsoleIntegration({ levels: [\"warn\", \"error\"] }),\n ],\n\n initialScope: {\n tags: {\n \"cli.name\": \"pm-cli\",\n \"cli.version\": release,\n \"runtime.node\": process.version,\n \"runtime.platform\": process.platform,\n \"runtime.arch\": process.arch,\n },\n },\n\n beforeSend(event) {\n if (isExpectedCliErrorEvent(event)) {\n return null;\n }\n if (event.message) {\n event.message = scrubString(event.message, \"message\");\n }\n if (event.transaction) {\n event.transaction = scrubString(event.transaction, \"transaction\");\n }\n\n if (event.exception?.values) {\n for (const exception of event.exception.values) {\n if (exception.value) {\n exception.value = scrubString(exception.value, \"value\");\n }\n if (exception.stacktrace?.frames) {\n for (const frame of exception.stacktrace.frames) {\n scrubStackFrame(frame as unknown as Record<string, unknown>);\n }\n }\n }\n }\n\n if (event.breadcrumbs) {\n for (const breadcrumb of event.breadcrumbs) {\n if (breadcrumb.message) {\n breadcrumb.message = scrubString(breadcrumb.message);\n }\n if (breadcrumb.data && typeof breadcrumb.data === \"object\") {\n breadcrumb.data = scrubEventData(breadcrumb.data as Record<string, unknown>);\n }\n }\n }\n\n if (event.extra && typeof event.extra === \"object\") {\n event.extra = scrubEventData(event.extra as Record<string, unknown>);\n }\n\n if (event.contexts) {\n for (const [ctxKey, ctx] of Object.entries(event.contexts)) {\n if (ctx && typeof ctx === \"object\") {\n event.contexts![ctxKey] = scrubEventData(ctx as Record<string, unknown>);\n }\n }\n }\n if (event.request && typeof event.request === \"object\") {\n event.request = scrubEventData(event.request as Record<string, unknown>) as typeof event.request;\n }\n if (event.user && typeof event.user === \"object\") {\n event.user = scrubEventData(event.user as Record<string, unknown>) as typeof event.user;\n }\n if (event.tags && typeof event.tags === \"object\") {\n event.tags = scrubEventData(event.tags as Record<string, unknown>) as typeof event.tags;\n }\n\n return event;\n },\n\n beforeSendTransaction(event) {\n if (event.breadcrumbs) {\n event.breadcrumbs = event.breadcrumbs.filter((bc) => !isPmCliErrorBreadcrumb(bc));\n for (const breadcrumb of event.breadcrumbs) {\n if (breadcrumb.message) {\n breadcrumb.message = scrubString(breadcrumb.message, \"message\");\n }\n if (breadcrumb.data && typeof breadcrumb.data === \"object\") {\n breadcrumb.data = scrubEventData(breadcrumb.data as Record<string, unknown>);\n }\n }\n }\n if (event.contexts) {\n for (const [ctxKey, ctx] of Object.entries(event.contexts)) {\n if (ctx && typeof ctx === \"object\") {\n event.contexts![ctxKey] = scrubEventData(ctx as Record<string, unknown>);\n }\n }\n }\n return event;\n },\n\n beforeBreadcrumb(breadcrumb) {\n if (isPmCliErrorBreadcrumb(breadcrumb)) {\n return null;\n }\n if (breadcrumb.message) {\n breadcrumb.message = scrubString(breadcrumb.message, \"message\");\n }\n if (breadcrumb.data && typeof breadcrumb.data === \"object\") {\n breadcrumb.data = scrubEventData(breadcrumb.data as Record<string, unknown>);\n }\n return breadcrumb;\n },\n });\n\n return SentryModule;\n}\n\nexport function getSentry(): SentryLike | undefined {\n return _sentry;\n}\n\nexport const _testOnly = {\n isExpectedCliErrorEvent,\n isPmCliErrorBreadcrumb,\n scrubString,\n scrubEventData,\n};\n"]}
1
+ {"version":3,"file":"instrument.js","sourceRoot":"/","sources":["core/sentry/instrument.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst OPT_OUT_VALUES = new Set([\"1\", \"true\", \"yes\", \"on\"]);\n\nfunction isSentryDisabled(): boolean {\n if (OPT_OUT_VALUES.has((process.env.PM_SENTRY_DISABLED ?? \"\").trim().toLowerCase())) return true;\n if (OPT_OUT_VALUES.has((process.env.PM_TELEMETRY_DISABLED ?? \"\").trim().toLowerCase())) return true;\n if (process.env.VITEST || process.env.VITEST_WORKER_ID) return true;\n return false;\n}\n\nconst SENSITIVE_KEY_PATTERN =\n /(?:token|secret|password|passwd|api[_-]?key|apikey|authorization|cookie|credentials|bearer|dsn)/i;\n\nconst INLINE_SENSITIVE_ASSIGNMENT_RE = new RegExp(\n `\\\\b(${SENSITIVE_KEY_PATTERN.source})\\\\s*[:=]\\\\s*([^\\\\s,;]+)`,\n \"giu\",\n);\nconst ABSOLUTE_PATH_TOKEN_RE = /(^|[\\s\"'`(=])\\/(?:[^\\s\"'`),;]+)/g;\nconst FILE_URL_PATH_RE = /file:\\/\\/\\/?[^\\s\"'`),;]+/giu;\nconst WINDOWS_PATH_TOKEN_RE = /\\b[A-Za-z]:\\\\[^\\s\"'`),;]+/g;\nconst PRIVATE_IP_RE =\n /\\b(?:10\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)|172\\.(?:1[6-9]|2\\d|3[01])\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)|192\\.168\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))\\b/g;\nconst PATH_FIELD_KEY_PATTERN = /(?:^|[_-])(path|filename|file|module|cwd|dir|directory|location|source|script)s?$/i;\nconst KNOWN_NOISY_CONSOLE_MESSAGE_PATTERNS = [\n \"[starter-extension] activating\",\n \"[starter-extension] all 8 capabilities registered.\",\n \"[starter-extension] commands:\",\n \"[starter] preflight check for workspace\",\n \"[starter] output_format service override active\",\n \"[pm-ext-ts-starter] activating\",\n \"[pm-ext-ts-starter] all capabilities registered.\",\n \"run `pm init` first to initialise a pm workspace\",\n] as const;\n\nfunction looksLikeFilesystemPath(value: string): boolean {\n const normalized = value.trim();\n if (normalized.length === 0) {\n return false;\n }\n if (normalized.startsWith(\"/\") || normalized.startsWith(\"file://\")) {\n return true;\n }\n if (/^[A-Za-z]:\\\\/.test(normalized) || normalized.startsWith(\"\\\\\\\\\")) {\n return true;\n }\n return normalized.includes(\"/home/\");\n}\n\nfunction scrubString(value: string, keyHint?: string): string {\n if (keyHint && PATH_FIELD_KEY_PATTERN.test(keyHint) && looksLikeFilesystemPath(value)) {\n return \"[scrubbed_path]\";\n }\n const scrubbed = value\n .replaceAll(INLINE_SENSITIVE_ASSIGNMENT_RE, (_m, key: string) => `${key}=[scrubbed]`)\n .replaceAll(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/giu, \"[scrubbed_email]\")\n .replaceAll(/bearer\\s+[a-z0-9._=-]+/giu, \"bearer [scrubbed]\")\n .replaceAll(/sntr[ysu]_[A-Za-z0-9_-]+/g, \"[scrubbed_sentry_token]\")\n .replaceAll(PRIVATE_IP_RE, \"[scrubbed_ip]\")\n .replaceAll(FILE_URL_PATH_RE, \"[scrubbed_path]\")\n .replaceAll(WINDOWS_PATH_TOKEN_RE, \"[scrubbed_path]\")\n .replaceAll(ABSOLUTE_PATH_TOKEN_RE, (_match: string, prefix: string) => `${prefix}[scrubbed_path]`);\n if (looksLikeFilesystemPath(scrubbed)) {\n return \"[scrubbed_path]\";\n }\n return scrubbed;\n}\n\nfunction scrubEventData(obj: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (SENSITIVE_KEY_PATTERN.test(key)) {\n result[key] = \"[scrubbed]\";\n } else if (typeof value === \"string\") {\n result[key] = scrubString(value, key);\n } else if (Array.isArray(value)) {\n result[key] = value.map((entry) => {\n if (typeof entry === \"string\") {\n return scrubString(entry, key);\n }\n if (entry && typeof entry === \"object\") {\n return scrubEventData(entry as Record<string, unknown>);\n }\n return entry;\n });\n } else if (value && typeof value === \"object\") {\n result[key] = scrubEventData(value as Record<string, unknown>);\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction scrubStackFrame(frame: Record<string, unknown>): void {\n for (const key of [\"filename\", \"absPath\", \"abs_path\", \"module\"]) {\n const rawValue = frame[key];\n if (typeof rawValue === \"string\") {\n frame[key] = scrubString(rawValue, key);\n }\n }\n const contextLine = frame.context_line;\n if (typeof contextLine === \"string\") {\n frame.context_line = scrubString(contextLine, \"context_line\");\n }\n for (const key of [\"pre_context\", \"post_context\"]) {\n const context = frame[key];\n if (!Array.isArray(context)) {\n continue;\n }\n frame[key] = context.map((entry) => (typeof entry === \"string\" ? scrubString(entry, key) : entry));\n }\n if (frame.vars && typeof frame.vars === \"object\") {\n frame.vars = scrubEventData(frame.vars as Record<string, unknown>);\n }\n if (frame.data && typeof frame.data === \"object\") {\n frame.data = scrubEventData(frame.data as Record<string, unknown>);\n }\n}\n\ntype SentryLike = typeof import(\"@sentry/node\");\n\nlet _sentry: SentryLike | undefined;\nlet _initDone = false;\n\nconst PM_CLI_SENTRY_DSN =\n \"https://bf7ad2ec76c0051c2ee94e48e8bd6868@o4510603477712896.ingest.de.sentry.io/4511316775338064\";\n\nfunction hasPmCliErrorPrefix(value: string): boolean {\n return /^\\s*PmCliError:/.test(value);\n}\n\nfunction isKnownNoisyConsoleMessage(value: string): boolean {\n const normalized = value.trim().toLowerCase();\n if (normalized.length === 0) {\n return false;\n }\n return KNOWN_NOISY_CONSOLE_MESSAGE_PATTERNS.some((pattern) => normalized.includes(pattern));\n}\n\nfunction isKnownNoisyConsoleEvent(event: {\n logger?: string;\n message?: string;\n exception?: { values?: Array<{ value?: string }> };\n}): boolean {\n if (event.logger !== \"console\") {\n return false;\n }\n if (typeof event.message === \"string\" && isKnownNoisyConsoleMessage(event.message)) {\n return true;\n }\n return (\n Array.isArray(event.exception?.values) &&\n event.exception.values.some((entry) => typeof entry.value === \"string\" && isKnownNoisyConsoleMessage(entry.value))\n );\n}\n\nfunction isExpectedCliErrorEvent(event: {\n exception?: { values?: Array<{ type?: string; value?: string }> };\n message?: string;\n extra?: Record<string, unknown>;\n logger?: string;\n}): boolean {\n if (event.exception?.values?.some((ex) => ex.type === \"PmCliError\")) return true;\n\n if (event.exception?.values?.some((ex) => typeof ex.value === \"string\" && hasPmCliErrorPrefix(ex.value)))\n return true;\n\n if (event.logger === \"console\" && typeof event.message === \"string\" && hasPmCliErrorPrefix(event.message))\n return true;\n\n return false;\n}\n\nfunction isPmCliErrorBreadcrumb(breadcrumb: { category?: string; message?: string }): boolean {\n return (\n breadcrumb.category === \"console\" &&\n typeof breadcrumb.message === \"string\" &&\n hasPmCliErrorPrefix(breadcrumb.message)\n );\n}\n\nfunction isKnownNoisyConsoleBreadcrumb(breadcrumb: { category?: string; message?: string }): boolean {\n return breadcrumb.category === \"console\" && typeof breadcrumb.message === \"string\" && isKnownNoisyConsoleMessage(breadcrumb.message);\n}\n\nfunction resolveCliVersion(): string {\n try {\n const thisFile = fileURLToPath(import.meta.url);\n const candidates = [\n path.resolve(thisFile, \"../../../../package.json\"),\n path.resolve(thisFile, \"../../../package.json\"),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n const parsed = JSON.parse(fs.readFileSync(candidate, \"utf8\")) as { version?: string };\n if (typeof parsed.version === \"string\") return parsed.version;\n }\n }\n } catch {\n // Version resolution must never block startup.\n }\n return \"0.0.0\";\n}\n\nfunction resolveEnvironment(): string {\n const explicit = process.env.SENTRY_ENVIRONMENT?.trim();\n if (explicit && explicit.length > 0) return explicit;\n if (process.env.VITEST || process.env.VITEST_WORKER_ID || process.env.NODE_ENV === \"test\") return \"test\";\n if (process.env.CI) return \"ci\";\n return \"production\";\n}\n\nexport async function ensureSentryInit(): Promise<SentryLike | undefined> {\n if (_initDone) return _sentry;\n _initDone = true;\n\n if (isSentryDisabled()) return undefined;\n\n const SentryModule = await import(\"@sentry/node\");\n _sentry = SentryModule;\n\n const dsn = process.env.SENTRY_DSN?.trim() || PM_CLI_SENTRY_DSN;\n const release = resolveCliVersion();\n\n SentryModule.init({\n dsn,\n release: `pm-cli@${release}`,\n environment: resolveEnvironment(),\n\n tracesSampleRate: 0.2,\n enableLogs: true,\n attachStacktrace: true,\n normalizeDepth: 6,\n shutdownTimeout: 3000,\n sendDefaultPii: false,\n serverName: undefined,\n\n integrations: [\n SentryModule.extraErrorDataIntegration({ depth: 4 }),\n SentryModule.captureConsoleIntegration({ levels: [\"warn\", \"error\"] }),\n ],\n\n initialScope: {\n tags: {\n \"cli.name\": \"pm-cli\",\n \"cli.version\": release,\n \"runtime.node\": process.version,\n \"runtime.platform\": process.platform,\n \"runtime.arch\": process.arch,\n },\n },\n\n beforeSend(event) {\n if (isExpectedCliErrorEvent(event) || isKnownNoisyConsoleEvent(event)) {\n return null;\n }\n if (event.message) {\n event.message = scrubString(event.message, \"message\");\n }\n if (event.transaction) {\n event.transaction = scrubString(event.transaction, \"transaction\");\n }\n\n if (event.exception?.values) {\n for (const exception of event.exception.values) {\n if (exception.value) {\n exception.value = scrubString(exception.value, \"value\");\n }\n if (exception.stacktrace?.frames) {\n for (const frame of exception.stacktrace.frames) {\n scrubStackFrame(frame as unknown as Record<string, unknown>);\n }\n }\n }\n }\n\n if (event.breadcrumbs) {\n for (const breadcrumb of event.breadcrumbs) {\n if (breadcrumb.message) {\n breadcrumb.message = scrubString(breadcrumb.message);\n }\n if (breadcrumb.data && typeof breadcrumb.data === \"object\") {\n breadcrumb.data = scrubEventData(breadcrumb.data as Record<string, unknown>);\n }\n }\n }\n\n if (event.extra && typeof event.extra === \"object\") {\n event.extra = scrubEventData(event.extra as Record<string, unknown>);\n }\n\n if (event.contexts) {\n for (const [ctxKey, ctx] of Object.entries(event.contexts)) {\n if (ctx && typeof ctx === \"object\") {\n event.contexts![ctxKey] = scrubEventData(ctx as Record<string, unknown>);\n }\n }\n }\n if (event.request && typeof event.request === \"object\") {\n event.request = scrubEventData(event.request as Record<string, unknown>) as typeof event.request;\n }\n if (event.user && typeof event.user === \"object\") {\n event.user = scrubEventData(event.user as Record<string, unknown>) as typeof event.user;\n }\n if (event.tags && typeof event.tags === \"object\") {\n event.tags = scrubEventData(event.tags as Record<string, unknown>) as typeof event.tags;\n }\n\n return event;\n },\n\n beforeSendTransaction(event) {\n if (event.breadcrumbs) {\n event.breadcrumbs = event.breadcrumbs.filter(\n (bc) => !isPmCliErrorBreadcrumb(bc) && !isKnownNoisyConsoleBreadcrumb(bc),\n );\n for (const breadcrumb of event.breadcrumbs) {\n if (breadcrumb.message) {\n breadcrumb.message = scrubString(breadcrumb.message, \"message\");\n }\n if (breadcrumb.data && typeof breadcrumb.data === \"object\") {\n breadcrumb.data = scrubEventData(breadcrumb.data as Record<string, unknown>);\n }\n }\n }\n if (event.contexts) {\n for (const [ctxKey, ctx] of Object.entries(event.contexts)) {\n if (ctx && typeof ctx === \"object\") {\n event.contexts![ctxKey] = scrubEventData(ctx as Record<string, unknown>);\n }\n }\n }\n return event;\n },\n\n beforeBreadcrumb(breadcrumb) {\n if (isPmCliErrorBreadcrumb(breadcrumb) || isKnownNoisyConsoleBreadcrumb(breadcrumb)) {\n return null;\n }\n if (breadcrumb.message) {\n breadcrumb.message = scrubString(breadcrumb.message, \"message\");\n }\n if (breadcrumb.data && typeof breadcrumb.data === \"object\") {\n breadcrumb.data = scrubEventData(breadcrumb.data as Record<string, unknown>);\n }\n return breadcrumb;\n },\n });\n\n return SentryModule;\n}\n\nexport function getSentry(): SentryLike | undefined {\n return _sentry;\n}\n\nexport const _testOnly = {\n isExpectedCliErrorEvent,\n isKnownNoisyConsoleEvent,\n isPmCliErrorBreadcrumb,\n isKnownNoisyConsoleBreadcrumb,\n scrubString,\n scrubEventData,\n};\n"]}
@@ -232,6 +232,26 @@ export const SETTINGS_DEFAULTS = {
232
232
  extensions: {
233
233
  enabled: [],
234
234
  disabled: [],
235
+ policy: {
236
+ mode: "off",
237
+ trust_mode: "off",
238
+ require_provenance: false,
239
+ trusted_extensions: [],
240
+ default_sandbox_profile: "none",
241
+ allowed_extensions: [],
242
+ blocked_extensions: [],
243
+ allowed_capabilities: [],
244
+ blocked_capabilities: [],
245
+ allowed_surfaces: [],
246
+ blocked_surfaces: [],
247
+ allowed_commands: [],
248
+ blocked_commands: [],
249
+ allowed_actions: [],
250
+ blocked_actions: [],
251
+ allowed_services: [],
252
+ blocked_services: [],
253
+ extension_overrides: [],
254
+ },
235
255
  },
236
256
  search: {
237
257
  score_threshold: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"/","sources":["core/shared/constants.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BuiltinItemType, GovernancePreset, GovernanceSettings, ItemFrontMatter, PmSettings } from \"../../types/index.js\";\n\nexport const PM_DIRNAME = \".agents/pm\";\nexport const SETTINGS_FILENAME = \"settings.json\";\n\nexport const PM_CORE_REQUIRED_SUBDIRS = [\n \"\",\n \"epics\",\n \"features\",\n \"tasks\",\n \"chores\",\n \"issues\",\n \"schema\",\n \"history\",\n \"index\",\n \"search\",\n \"extensions\",\n \"locks\",\n] as const;\n\nexport const PM_OPTIONAL_TYPE_SUBDIRS = [\n \"decisions\",\n \"events\",\n \"reminders\",\n \"milestones\",\n \"meetings\",\n] as const;\n\nexport const PM_REQUIRED_SUBDIRS = [...PM_CORE_REQUIRED_SUBDIRS, ...PM_OPTIONAL_TYPE_SUBDIRS] as const;\n\nexport const TYPE_TO_FOLDER: Record<BuiltinItemType, string> = {\n Epic: \"epics\",\n Feature: \"features\",\n Task: \"tasks\",\n Chore: \"chores\",\n Issue: \"issues\",\n Decision: \"decisions\",\n Event: \"events\",\n Reminder: \"reminders\",\n Milestone: \"milestones\",\n Meeting: \"meetings\",\n};\n\nexport const FRONT_MATTER_KEY_ORDER: ReadonlyArray<string> = [\n \"id\",\n \"title\",\n \"description\",\n \"type\",\n \"source_type\",\n \"type_options\",\n \"status\",\n \"priority\",\n \"tags\",\n \"created_at\",\n \"updated_at\",\n \"deadline\",\n \"reminders\",\n \"events\",\n \"closed_at\",\n \"assignee\",\n \"source_owner\",\n \"author\",\n \"estimated_minutes\",\n \"acceptance_criteria\",\n \"design\",\n \"external_ref\",\n \"definition_of_ready\",\n \"order\",\n \"goal\",\n \"objective\",\n \"value\",\n \"impact\",\n \"outcome\",\n \"why_now\",\n \"parent\",\n \"reviewer\",\n \"risk\",\n \"confidence\",\n \"sprint\",\n \"release\",\n \"blocked_by\",\n \"blocked_reason\",\n \"unblock_note\",\n \"reporter\",\n \"severity\",\n \"environment\",\n \"repro_steps\",\n \"resolution\",\n \"expected_result\",\n \"actual_result\",\n \"affected_version\",\n \"fixed_version\",\n \"component\",\n \"regression\",\n \"customer_impact\",\n \"dependencies\",\n \"comments\",\n \"notes\",\n \"learnings\",\n \"files\",\n \"tests\",\n \"test_runs\",\n \"docs\",\n \"close_reason\",\n];\n\ntype BuiltinGovernancePreset = Exclude<GovernancePreset, \"custom\">;\n\nexport const GOVERNANCE_PRESET_DEFAULTS: Record<BuiltinGovernancePreset, Omit<GovernanceSettings, \"preset\">> = {\n minimal: {\n ownership_enforcement: \"none\",\n create_mode_default: \"progressive\",\n close_validation_default: \"off\",\n parent_reference: \"warn\",\n metadata_profile: \"core\",\n force_required_for_stale_lock: false,\n },\n default: {\n ownership_enforcement: \"warn\",\n create_mode_default: \"progressive\",\n close_validation_default: \"warn\",\n parent_reference: \"warn\",\n metadata_profile: \"core\",\n force_required_for_stale_lock: true,\n },\n strict: {\n ownership_enforcement: \"strict\",\n create_mode_default: \"strict\",\n close_validation_default: \"strict\",\n parent_reference: \"strict_error\",\n metadata_profile: \"strict\",\n force_required_for_stale_lock: true,\n },\n};\n\nexport const DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS = [\n \"no active blocker\",\n \"ready for planned execution sequencing\",\n \"work completed\",\n \"work is closed\",\n] as const;\n\nexport const DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS = {\n blocked_reason: [\"no active blocker because work is closed\", \"work is closed\"],\n resolution: [\"closed with implementation evidence\", \"closed with verification evidence\", \"work completed and recorded\", \"work is closed\"],\n actual_result: [\"closed and recorded\", \"work completed\", \"work completed and recorded\"],\n} as const;\n\nexport const SETTINGS_DEFAULTS: PmSettings = {\n version: 1,\n id_prefix: \"pm-\",\n author_default: \"\",\n item_format: \"toon\",\n locks: {\n ttl_seconds: 1800,\n },\n output: {\n default_format: \"toon\",\n },\n history: {\n missing_stream: \"auto_create\",\n },\n validation: {\n sprint_release_format: \"warn\",\n parent_reference: \"warn\",\n metadata_profile: \"core\",\n metadata_required_fields: [],\n lifecycle_stale_blocker_reason_patterns: [...DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS],\n lifecycle_closure_like_blocked_reason_patterns: [\n ...DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.blocked_reason,\n ],\n lifecycle_closure_like_resolution_patterns: [...DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.resolution],\n lifecycle_closure_like_actual_result_patterns: [\n ...DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.actual_result,\n ],\n },\n governance: {\n preset: \"minimal\",\n ...GOVERNANCE_PRESET_DEFAULTS.minimal,\n },\n workflow: {\n definition_of_done: [],\n },\n testing: {\n record_results_to_items: false,\n },\n telemetry: {\n enabled: true,\n first_run_prompt_completed: false,\n capture_level: \"redacted\",\n endpoint: \"https://pm-cli.unbrained.dev/v1/events\",\n installation_id: \"\",\n retention_days: 365,\n },\n item_types: {\n definitions: [],\n },\n schema: {\n version: 1,\n files: {\n types: \"schema/types.json\",\n statuses: \"schema/statuses.json\",\n fields: \"schema/fields.json\",\n workflows: \"schema/workflows.json\",\n },\n statuses: [\n {\n id: \"draft\",\n roles: [\"draft\"],\n },\n {\n id: \"open\",\n roles: [\"active\", \"default_open\"],\n },\n {\n id: \"in_progress\",\n aliases: [\"in-progress\"],\n roles: [\"active\"],\n },\n {\n id: \"blocked\",\n roles: [\"blocked\"],\n },\n {\n id: \"closed\",\n roles: [\"terminal\", \"terminal_done\", \"default_close\"],\n },\n {\n id: \"canceled\",\n aliases: [\"cancelled\"],\n roles: [\"terminal\", \"terminal_canceled\", \"default_cancel\"],\n },\n ],\n fields: [],\n workflow: {\n draft_status: \"draft\",\n open_status: \"open\",\n in_progress_status: \"in_progress\",\n blocked_status: \"blocked\",\n close_status: \"closed\",\n canceled_status: \"canceled\",\n },\n unknown_field_policy: \"allow\",\n },\n extensions: {\n enabled: [],\n disabled: [],\n },\n search: {\n score_threshold: 0,\n hybrid_semantic_weight: 0.7,\n max_results: 50,\n embedding_model: \"\",\n embedding_batch_size: 32,\n scanner_max_batch_retries: 3,\n provider: \"\",\n },\n providers: {\n openai: {\n base_url: \"\",\n api_key: \"\",\n model: \"\",\n },\n ollama: {\n base_url: \"\",\n model: \"\",\n },\n },\n context: {\n default_depth: \"brief\",\n activity_limit: 10,\n stale_threshold_days: 7,\n sections: {\n hierarchy: true,\n activity: true,\n progress: true,\n blockers: true,\n files: true,\n workload: true,\n staleness: true,\n tests: true,\n },\n },\n vector_store: {\n adapter: \"\",\n qdrant: {\n url: \"\",\n api_key: \"\",\n },\n lancedb: {\n path: \"\",\n },\n },\n};\n\nexport const EMPTY_CANONICAL_DOCUMENT = {\n metadata: {},\n body: \"\",\n};\n\nexport const EXIT_CODE = {\n SUCCESS: 0,\n GENERIC_FAILURE: 1,\n USAGE: 2,\n NOT_FOUND: 3,\n CONFLICT: 4,\n DEPENDENCY_FAILED: 5,\n} as const;\n\nexport type TelemetryErrorCategory = \"usage\" | \"validation\" | \"conflict\" | \"runtime\" | \"unknown\";\n\nexport const TELEMETRY_ERROR_CATEGORY_BY_CODE: Readonly<Record<string, TelemetryErrorCategory>> = Object.freeze({\n unknown_command: \"usage\",\n unknown_option: \"usage\",\n missing_required_option: \"usage\",\n missing_required_argument: \"usage\",\n invalid_command_usage: \"usage\",\n invalid_argument_value: \"validation\",\n close_through_update: \"validation\",\n no_update_fields: \"validation\",\n unsupported_update_option: \"validation\",\n tracker_not_initialized: \"validation\",\n item_not_found: \"validation\",\n ownership_conflict: \"conflict\",\n lock_conflict: \"conflict\",\n terminal_state_conflict: \"conflict\",\n dependency_failed: \"runtime\",\n command_failed: \"runtime\",\n unknown_error: \"runtime\",\n});\n\nexport function resolveTelemetryErrorCategory(errorCode: string | undefined): TelemetryErrorCategory {\n const normalized = (errorCode ?? \"\").trim().toLowerCase();\n if (normalized.length === 0) {\n return \"unknown\";\n }\n const explicit = TELEMETRY_ERROR_CATEGORY_BY_CODE[normalized];\n if (typeof explicit === \"string\") {\n return explicit;\n }\n if (normalized.includes(\"conflict\") || normalized.includes(\"locked\")) {\n return \"conflict\";\n }\n if (normalized.startsWith(\"unknown_\") || normalized.startsWith(\"missing_required_\")) {\n return \"usage\";\n }\n if (normalized.startsWith(\"invalid_\") || normalized.endsWith(\"_not_found\") || normalized.includes(\"validation\")) {\n return \"validation\";\n }\n if (normalized.endsWith(\"_error\") || normalized.endsWith(\"_failed\")) {\n return \"runtime\";\n }\n return \"unknown\";\n}\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"/","sources":["core/shared/constants.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BuiltinItemType, GovernancePreset, GovernanceSettings, ItemFrontMatter, PmSettings } from \"../../types/index.js\";\n\nexport const PM_DIRNAME = \".agents/pm\";\nexport const SETTINGS_FILENAME = \"settings.json\";\n\nexport const PM_CORE_REQUIRED_SUBDIRS = [\n \"\",\n \"epics\",\n \"features\",\n \"tasks\",\n \"chores\",\n \"issues\",\n \"schema\",\n \"history\",\n \"index\",\n \"search\",\n \"extensions\",\n \"locks\",\n] as const;\n\nexport const PM_OPTIONAL_TYPE_SUBDIRS = [\n \"decisions\",\n \"events\",\n \"reminders\",\n \"milestones\",\n \"meetings\",\n] as const;\n\nexport const PM_REQUIRED_SUBDIRS = [...PM_CORE_REQUIRED_SUBDIRS, ...PM_OPTIONAL_TYPE_SUBDIRS] as const;\n\nexport const TYPE_TO_FOLDER: Record<BuiltinItemType, string> = {\n Epic: \"epics\",\n Feature: \"features\",\n Task: \"tasks\",\n Chore: \"chores\",\n Issue: \"issues\",\n Decision: \"decisions\",\n Event: \"events\",\n Reminder: \"reminders\",\n Milestone: \"milestones\",\n Meeting: \"meetings\",\n};\n\nexport const FRONT_MATTER_KEY_ORDER: ReadonlyArray<string> = [\n \"id\",\n \"title\",\n \"description\",\n \"type\",\n \"source_type\",\n \"type_options\",\n \"status\",\n \"priority\",\n \"tags\",\n \"created_at\",\n \"updated_at\",\n \"deadline\",\n \"reminders\",\n \"events\",\n \"closed_at\",\n \"assignee\",\n \"source_owner\",\n \"author\",\n \"estimated_minutes\",\n \"acceptance_criteria\",\n \"design\",\n \"external_ref\",\n \"definition_of_ready\",\n \"order\",\n \"goal\",\n \"objective\",\n \"value\",\n \"impact\",\n \"outcome\",\n \"why_now\",\n \"parent\",\n \"reviewer\",\n \"risk\",\n \"confidence\",\n \"sprint\",\n \"release\",\n \"blocked_by\",\n \"blocked_reason\",\n \"unblock_note\",\n \"reporter\",\n \"severity\",\n \"environment\",\n \"repro_steps\",\n \"resolution\",\n \"expected_result\",\n \"actual_result\",\n \"affected_version\",\n \"fixed_version\",\n \"component\",\n \"regression\",\n \"customer_impact\",\n \"dependencies\",\n \"comments\",\n \"notes\",\n \"learnings\",\n \"files\",\n \"tests\",\n \"test_runs\",\n \"docs\",\n \"close_reason\",\n];\n\ntype BuiltinGovernancePreset = Exclude<GovernancePreset, \"custom\">;\n\nexport const GOVERNANCE_PRESET_DEFAULTS: Record<BuiltinGovernancePreset, Omit<GovernanceSettings, \"preset\">> = {\n minimal: {\n ownership_enforcement: \"none\",\n create_mode_default: \"progressive\",\n close_validation_default: \"off\",\n parent_reference: \"warn\",\n metadata_profile: \"core\",\n force_required_for_stale_lock: false,\n },\n default: {\n ownership_enforcement: \"warn\",\n create_mode_default: \"progressive\",\n close_validation_default: \"warn\",\n parent_reference: \"warn\",\n metadata_profile: \"core\",\n force_required_for_stale_lock: true,\n },\n strict: {\n ownership_enforcement: \"strict\",\n create_mode_default: \"strict\",\n close_validation_default: \"strict\",\n parent_reference: \"strict_error\",\n metadata_profile: \"strict\",\n force_required_for_stale_lock: true,\n },\n};\n\nexport const DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS = [\n \"no active blocker\",\n \"ready for planned execution sequencing\",\n \"work completed\",\n \"work is closed\",\n] as const;\n\nexport const DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS = {\n blocked_reason: [\"no active blocker because work is closed\", \"work is closed\"],\n resolution: [\"closed with implementation evidence\", \"closed with verification evidence\", \"work completed and recorded\", \"work is closed\"],\n actual_result: [\"closed and recorded\", \"work completed\", \"work completed and recorded\"],\n} as const;\n\nexport const SETTINGS_DEFAULTS: PmSettings = {\n version: 1,\n id_prefix: \"pm-\",\n author_default: \"\",\n item_format: \"toon\",\n locks: {\n ttl_seconds: 1800,\n },\n output: {\n default_format: \"toon\",\n },\n history: {\n missing_stream: \"auto_create\",\n },\n validation: {\n sprint_release_format: \"warn\",\n parent_reference: \"warn\",\n metadata_profile: \"core\",\n metadata_required_fields: [],\n lifecycle_stale_blocker_reason_patterns: [...DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS],\n lifecycle_closure_like_blocked_reason_patterns: [\n ...DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.blocked_reason,\n ],\n lifecycle_closure_like_resolution_patterns: [...DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.resolution],\n lifecycle_closure_like_actual_result_patterns: [\n ...DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.actual_result,\n ],\n },\n governance: {\n preset: \"minimal\",\n ...GOVERNANCE_PRESET_DEFAULTS.minimal,\n },\n workflow: {\n definition_of_done: [],\n },\n testing: {\n record_results_to_items: false,\n },\n telemetry: {\n enabled: true,\n first_run_prompt_completed: false,\n capture_level: \"redacted\",\n endpoint: \"https://pm-cli.unbrained.dev/v1/events\",\n installation_id: \"\",\n retention_days: 365,\n },\n item_types: {\n definitions: [],\n },\n schema: {\n version: 1,\n files: {\n types: \"schema/types.json\",\n statuses: \"schema/statuses.json\",\n fields: \"schema/fields.json\",\n workflows: \"schema/workflows.json\",\n },\n statuses: [\n {\n id: \"draft\",\n roles: [\"draft\"],\n },\n {\n id: \"open\",\n roles: [\"active\", \"default_open\"],\n },\n {\n id: \"in_progress\",\n aliases: [\"in-progress\"],\n roles: [\"active\"],\n },\n {\n id: \"blocked\",\n roles: [\"blocked\"],\n },\n {\n id: \"closed\",\n roles: [\"terminal\", \"terminal_done\", \"default_close\"],\n },\n {\n id: \"canceled\",\n aliases: [\"cancelled\"],\n roles: [\"terminal\", \"terminal_canceled\", \"default_cancel\"],\n },\n ],\n fields: [],\n workflow: {\n draft_status: \"draft\",\n open_status: \"open\",\n in_progress_status: \"in_progress\",\n blocked_status: \"blocked\",\n close_status: \"closed\",\n canceled_status: \"canceled\",\n },\n unknown_field_policy: \"allow\",\n },\n extensions: {\n enabled: [],\n disabled: [],\n policy: {\n mode: \"off\",\n trust_mode: \"off\",\n require_provenance: false,\n trusted_extensions: [],\n default_sandbox_profile: \"none\",\n allowed_extensions: [],\n blocked_extensions: [],\n allowed_capabilities: [],\n blocked_capabilities: [],\n allowed_surfaces: [],\n blocked_surfaces: [],\n allowed_commands: [],\n blocked_commands: [],\n allowed_actions: [],\n blocked_actions: [],\n allowed_services: [],\n blocked_services: [],\n extension_overrides: [],\n },\n },\n search: {\n score_threshold: 0,\n hybrid_semantic_weight: 0.7,\n max_results: 50,\n embedding_model: \"\",\n embedding_batch_size: 32,\n scanner_max_batch_retries: 3,\n provider: \"\",\n },\n providers: {\n openai: {\n base_url: \"\",\n api_key: \"\",\n model: \"\",\n },\n ollama: {\n base_url: \"\",\n model: \"\",\n },\n },\n context: {\n default_depth: \"brief\",\n activity_limit: 10,\n stale_threshold_days: 7,\n sections: {\n hierarchy: true,\n activity: true,\n progress: true,\n blockers: true,\n files: true,\n workload: true,\n staleness: true,\n tests: true,\n },\n },\n vector_store: {\n adapter: \"\",\n qdrant: {\n url: \"\",\n api_key: \"\",\n },\n lancedb: {\n path: \"\",\n },\n },\n};\n\nexport const EMPTY_CANONICAL_DOCUMENT = {\n metadata: {},\n body: \"\",\n};\n\nexport const EXIT_CODE = {\n SUCCESS: 0,\n GENERIC_FAILURE: 1,\n USAGE: 2,\n NOT_FOUND: 3,\n CONFLICT: 4,\n DEPENDENCY_FAILED: 5,\n} as const;\n\nexport type TelemetryErrorCategory = \"usage\" | \"validation\" | \"conflict\" | \"runtime\" | \"unknown\";\n\nexport const TELEMETRY_ERROR_CATEGORY_BY_CODE: Readonly<Record<string, TelemetryErrorCategory>> = Object.freeze({\n unknown_command: \"usage\",\n unknown_option: \"usage\",\n missing_required_option: \"usage\",\n missing_required_argument: \"usage\",\n invalid_command_usage: \"usage\",\n invalid_argument_value: \"validation\",\n close_through_update: \"validation\",\n no_update_fields: \"validation\",\n unsupported_update_option: \"validation\",\n tracker_not_initialized: \"validation\",\n item_not_found: \"validation\",\n ownership_conflict: \"conflict\",\n lock_conflict: \"conflict\",\n terminal_state_conflict: \"conflict\",\n dependency_failed: \"runtime\",\n command_failed: \"runtime\",\n unknown_error: \"runtime\",\n});\n\nexport function resolveTelemetryErrorCategory(errorCode: string | undefined): TelemetryErrorCategory {\n const normalized = (errorCode ?? \"\").trim().toLowerCase();\n if (normalized.length === 0) {\n return \"unknown\";\n }\n const explicit = TELEMETRY_ERROR_CATEGORY_BY_CODE[normalized];\n if (typeof explicit === \"string\") {\n return explicit;\n }\n if (normalized.includes(\"conflict\") || normalized.includes(\"locked\")) {\n return \"conflict\";\n }\n if (normalized.startsWith(\"unknown_\") || normalized.startsWith(\"missing_required_\")) {\n return \"usage\";\n }\n if (normalized.startsWith(\"invalid_\") || normalized.endsWith(\"_not_found\") || normalized.includes(\"validation\")) {\n return \"validation\";\n }\n if (normalized.endsWith(\"_error\") || normalized.endsWith(\"_failed\")) {\n return \"runtime\";\n }\n return \"unknown\";\n}\n"]}
@@ -1,3 +1,10 @@
1
+ export interface PmCliErrorRecoveryPayload {
2
+ attempted_command?: string;
3
+ normalized_args?: string[];
4
+ provided_fields?: string[];
5
+ missing?: string[];
6
+ suggested_retry?: string;
7
+ }
1
8
  export interface PmCliErrorContext {
2
9
  code?: string;
3
10
  type?: string;
@@ -5,6 +12,7 @@ export interface PmCliErrorContext {
5
12
  why?: string;
6
13
  examples?: string[];
7
14
  nextSteps?: string[];
15
+ recovery?: PmCliErrorRecoveryPayload;
8
16
  }
9
17
  export declare class PmCliError extends Error {
10
18
  readonly exitCode: number;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"/","sources":["core/shared/errors.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnB,QAAQ,CAAS;IACjB,OAAO,CAAoB;IAE3C,YAAY,OAAe,EAAE,QAAgB,EAAE,UAA6B,EAAE;QAC5E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF","sourcesContent":["export interface PmCliErrorContext {\n code?: string;\n type?: string;\n required?: string;\n why?: string;\n examples?: string[];\n nextSteps?: string[];\n}\n\nexport class PmCliError extends Error {\n public readonly exitCode: number;\n public readonly context: PmCliErrorContext;\n\n constructor(message: string, exitCode: number, context: PmCliErrorContext = {}) {\n super(message);\n this.name = \"PmCliError\";\n this.exitCode = exitCode;\n this.context = context;\n }\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"/","sources":["core/shared/errors.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnB,QAAQ,CAAS;IACjB,OAAO,CAAoB;IAE3C,YAAY,OAAe,EAAE,QAAgB,EAAE,UAA6B,EAAE;QAC5E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF","sourcesContent":["export interface PmCliErrorRecoveryPayload {\n attempted_command?: string;\n normalized_args?: string[];\n provided_fields?: string[];\n missing?: string[];\n suggested_retry?: string;\n}\n\nexport interface PmCliErrorContext {\n code?: string;\n type?: string;\n required?: string;\n why?: string;\n examples?: string[];\n nextSteps?: string[];\n recovery?: PmCliErrorRecoveryPayload;\n}\n\nexport class PmCliError extends Error {\n public readonly exitCode: number;\n public readonly context: PmCliErrorContext;\n\n constructor(message: string, exitCode: number, context: PmCliErrorContext = {}) {\n super(message);\n this.name = \"PmCliError\";\n this.exitCode = exitCode;\n this.context = context;\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function levenshteinDistanceWithinLimit(left: string, right: string, limit: number): number | null;
@@ -0,0 +1,37 @@
1
+ export function levenshteinDistanceWithinLimit(left, right, limit) {
2
+ if (left === right) {
3
+ return 0;
4
+ }
5
+ if (Math.abs(left.length - right.length) > limit) {
6
+ return null;
7
+ }
8
+ const previous = new Array(right.length + 1);
9
+ const current = new Array(right.length + 1);
10
+ for (let column = 0; column <= right.length; column += 1) {
11
+ previous[column] = column;
12
+ }
13
+ for (let row = 1; row <= left.length; row += 1) {
14
+ current[0] = row;
15
+ let rowMin = current[0];
16
+ for (let column = 1; column <= right.length; column += 1) {
17
+ const cost = left[row - 1] === right[column - 1] ? 0 : 1;
18
+ const substitution = previous[column - 1] + cost;
19
+ const insertion = current[column - 1] + 1;
20
+ const deletion = previous[column] + 1;
21
+ const candidate = Math.min(substitution, insertion, deletion);
22
+ current[column] = candidate;
23
+ if (candidate < rowMin) {
24
+ rowMin = candidate;
25
+ }
26
+ }
27
+ if (rowMin > limit) {
28
+ return null;
29
+ }
30
+ for (let column = 0; column <= right.length; column += 1) {
31
+ previous[column] = current[column];
32
+ }
33
+ }
34
+ const result = previous[right.length];
35
+ return result <= limit ? result : null;
36
+ }
37
+ //# sourceMappingURL=levenshtein.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"levenshtein.js","sourceRoot":"/","sources":["core/shared/levenshtein.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,8BAA8B,CAAC,IAAY,EAAE,KAAa,EAAE,KAAa;IACvF,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAS,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,IAAI,KAAK,CAAS,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACpD,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;QACzD,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC5B,CAAC;IACD,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QACjB,IAAI,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACxB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;YACjD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC9D,OAAO,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;YAC5B,IAAI,SAAS,GAAG,MAAM,EAAE,CAAC;gBACvB,MAAM,GAAG,SAAS,CAAC;YACrB,CAAC;QACH,CAAC;QACD,IAAI,MAAM,GAAG,KAAK,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;YACzD,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,OAAO,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC","sourcesContent":["export function levenshteinDistanceWithinLimit(left: string, right: string, limit: number): number | null {\n if (left === right) {\n return 0;\n }\n if (Math.abs(left.length - right.length) > limit) {\n return null;\n }\n const previous = new Array<number>(right.length + 1);\n const current = new Array<number>(right.length + 1);\n for (let column = 0; column <= right.length; column += 1) {\n previous[column] = column;\n }\n for (let row = 1; row <= left.length; row += 1) {\n current[0] = row;\n let rowMin = current[0];\n for (let column = 1; column <= right.length; column += 1) {\n const cost = left[row - 1] === right[column - 1] ? 0 : 1;\n const substitution = previous[column - 1] + cost;\n const insertion = current[column - 1] + 1;\n const deletion = previous[column] + 1;\n const candidate = Math.min(substitution, insertion, deletion);\n current[column] = candidate;\n if (candidate < rowMin) {\n rowMin = candidate;\n }\n }\n if (rowMin > limit) {\n return null;\n }\n for (let column = 0; column <= right.length; column += 1) {\n previous[column] = current[column];\n }\n }\n const result = previous[right.length];\n return result <= limit ? result : null;\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { statSync } from "node:fs";
1
2
  import os from "node:os";
2
3
  import path from "node:path";
3
4
  import { PM_DIRNAME, SETTINGS_FILENAME, TYPE_TO_FOLDER } from "../shared/constants.js";
@@ -10,9 +11,41 @@ const ITEM_FORMAT_BY_EXTENSION = {
10
11
  ".toon": "toon",
11
12
  };
12
13
  export const ITEM_FILE_EXTENSIONS = [".md", ".toon"];
14
+ function pathExists(pathValue) {
15
+ try {
16
+ statSync(pathValue);
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ function discoverPmRootFromAncestors(cwd) {
24
+ let current = path.resolve(cwd);
25
+ while (true) {
26
+ const candidateRoot = path.join(current, PM_DIRNAME);
27
+ const candidateSettingsPath = path.join(candidateRoot, SETTINGS_FILENAME);
28
+ if (pathExists(candidateSettingsPath)) {
29
+ return candidateRoot;
30
+ }
31
+ const parent = path.dirname(current);
32
+ if (parent === current) {
33
+ return undefined;
34
+ }
35
+ current = parent;
36
+ }
37
+ }
13
38
  export function resolvePmRoot(cwd, cliPath) {
14
39
  const envPath = process.env.PM_PATH;
15
- const selected = cliPath?.trim() || envPath?.trim() || PM_DIRNAME;
40
+ const explicitPath = cliPath?.trim() || envPath?.trim();
41
+ if (explicitPath) {
42
+ return path.resolve(cwd, explicitPath);
43
+ }
44
+ const discoveredRoot = discoverPmRootFromAncestors(cwd);
45
+ if (discoveredRoot) {
46
+ return discoveredRoot;
47
+ }
48
+ const selected = PM_DIRNAME;
16
49
  return path.resolve(cwd, selected);
17
50
  }
18
51
  export function resolveGlobalPmRoot(cwd) {
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"/","sources":["core/store/paths.ts"],"names":[],"mappings":"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","sourcesContent":["import os from \"node:os\";\nimport path from \"node:path\";\nimport { PM_DIRNAME, SETTINGS_FILENAME, TYPE_TO_FOLDER } from \"../shared/constants.js\";\nimport type { ItemFormat, ItemType } from \"../../types/index.js\";\n\nexport const ITEM_FILE_EXTENSION_BY_FORMAT: Record<ItemFormat, \".md\" | \".toon\"> = {\n json_markdown: \".md\",\n toon: \".toon\",\n};\n\nconst ITEM_FORMAT_BY_EXTENSION = {\n \".md\": \"json_markdown\",\n \".toon\": \"toon\",\n} as const satisfies Record<string, ItemFormat>;\n\nexport const ITEM_FILE_EXTENSIONS: Array<keyof typeof ITEM_FORMAT_BY_EXTENSION> = [\".md\", \".toon\"];\n\nexport function resolvePmRoot(cwd: string, cliPath?: string): string {\n const envPath = process.env.PM_PATH;\n const selected = cliPath?.trim() || envPath?.trim() || PM_DIRNAME;\n return path.resolve(cwd, selected);\n}\n\nexport function resolveGlobalPmRoot(cwd: string): string {\n const envPath = process.env.PM_GLOBAL_PATH?.trim();\n const selected = envPath && envPath.length > 0 ? envPath : path.join(os.homedir(), \".pm-cli\");\n return path.resolve(cwd, selected);\n}\n\nexport function getSettingsPath(pmRoot: string): string {\n return path.join(pmRoot, SETTINGS_FILENAME);\n}\n\nfunction deriveDefaultTypeFolder(type: string): string {\n const normalized = type\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n if (normalized.length === 0) {\n return \"items\";\n }\n return normalized.endsWith(\"s\") ? normalized : `${normalized}s`;\n}\n\nexport function getTypeDirPath(pmRoot: string, type: ItemType, typeToFolder: Record<string, string> = TYPE_TO_FOLDER): string {\n const folder = typeToFolder[type] ?? deriveDefaultTypeFolder(type);\n return path.join(pmRoot, folder);\n}\n\nexport function getItemPath(\n pmRoot: string,\n type: ItemType,\n id: string,\n itemFormat: ItemFormat = \"toon\",\n typeToFolder: Record<string, string> = TYPE_TO_FOLDER,\n): string {\n return path.join(getTypeDirPath(pmRoot, type, typeToFolder), `${id}${ITEM_FILE_EXTENSION_BY_FORMAT[itemFormat]}`);\n}\n\nexport function getItemFormatFromPath(itemPath: string): ItemFormat | null {\n const extension = path.extname(itemPath).toLowerCase() as keyof typeof ITEM_FORMAT_BY_EXTENSION;\n return ITEM_FORMAT_BY_EXTENSION[extension] ?? null;\n}\n\nexport function getHistoryPath(pmRoot: string, id: string): string {\n return path.join(pmRoot, \"history\", `${id}.jsonl`);\n}\n\nexport function getLockPath(pmRoot: string, id: string): string {\n return path.join(pmRoot, \"locks\", `${id}.lock`);\n}\n\nexport function getRuntimePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\");\n}\n\nexport function getTestRunsPath(pmRoot: string): string {\n return path.join(getRuntimePath(pmRoot), \"test-runs\");\n}\n\nexport function getTestRunsRecordsPath(pmRoot: string): string {\n return path.join(getTestRunsPath(pmRoot), \"runs\");\n}\n\nexport function getTestRunRecordPath(pmRoot: string, runId: string): string {\n return path.join(getTestRunsRecordsPath(pmRoot), `${runId}.json`);\n}\n\nexport function getTestRunsStdoutPath(pmRoot: string): string {\n return path.join(getTestRunsPath(pmRoot), \"stdout\");\n}\n\nexport function getTestRunsStderrPath(pmRoot: string): string {\n return path.join(getTestRunsPath(pmRoot), \"stderr\");\n}\n\nexport function getTestRunStdoutPath(pmRoot: string, runId: string): string {\n return path.join(getTestRunsStdoutPath(pmRoot), `${runId}.log`);\n}\n\nexport function getTestRunStderrPath(pmRoot: string, runId: string): string {\n return path.join(getTestRunsStderrPath(pmRoot), `${runId}.log`);\n}\n\nexport function getTestRunsResultsPath(pmRoot: string): string {\n return path.join(getTestRunsPath(pmRoot), \"results\");\n}\n\nexport function getTestRunResultPath(pmRoot: string, runId: string): string {\n return path.join(getTestRunsResultsPath(pmRoot), `${runId}.json`);\n}\n"]}
1
+ {"version":3,"file":"paths.js","sourceRoot":"/","sources":["core/store/paths.ts"],"names":[],"mappings":"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","sourcesContent":["import { statSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { PM_DIRNAME, SETTINGS_FILENAME, TYPE_TO_FOLDER } from \"../shared/constants.js\";\nimport type { ItemFormat, ItemType } from \"../../types/index.js\";\n\nexport const ITEM_FILE_EXTENSION_BY_FORMAT: Record<ItemFormat, \".md\" | \".toon\"> = {\n json_markdown: \".md\",\n toon: \".toon\",\n};\n\nconst ITEM_FORMAT_BY_EXTENSION = {\n \".md\": \"json_markdown\",\n \".toon\": \"toon\",\n} as const satisfies Record<string, ItemFormat>;\n\nexport const ITEM_FILE_EXTENSIONS: Array<keyof typeof ITEM_FORMAT_BY_EXTENSION> = [\".md\", \".toon\"];\n\nfunction pathExists(pathValue: string): boolean {\n try {\n statSync(pathValue);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction discoverPmRootFromAncestors(cwd: string): string | undefined {\n let current = path.resolve(cwd);\n while (true) {\n const candidateRoot = path.join(current, PM_DIRNAME);\n const candidateSettingsPath = path.join(candidateRoot, SETTINGS_FILENAME);\n if (pathExists(candidateSettingsPath)) {\n return candidateRoot;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n return undefined;\n }\n current = parent;\n }\n}\n\nexport function resolvePmRoot(cwd: string, cliPath?: string): string {\n const envPath = process.env.PM_PATH;\n const explicitPath = cliPath?.trim() || envPath?.trim();\n if (explicitPath) {\n return path.resolve(cwd, explicitPath);\n }\n const discoveredRoot = discoverPmRootFromAncestors(cwd);\n if (discoveredRoot) {\n return discoveredRoot;\n }\n const selected = PM_DIRNAME;\n return path.resolve(cwd, selected);\n}\n\nexport function resolveGlobalPmRoot(cwd: string): string {\n const envPath = process.env.PM_GLOBAL_PATH?.trim();\n const selected = envPath && envPath.length > 0 ? envPath : path.join(os.homedir(), \".pm-cli\");\n return path.resolve(cwd, selected);\n}\n\nexport function getSettingsPath(pmRoot: string): string {\n return path.join(pmRoot, SETTINGS_FILENAME);\n}\n\nfunction deriveDefaultTypeFolder(type: string): string {\n const normalized = type\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n if (normalized.length === 0) {\n return \"items\";\n }\n return normalized.endsWith(\"s\") ? normalized : `${normalized}s`;\n}\n\nexport function getTypeDirPath(pmRoot: string, type: ItemType, typeToFolder: Record<string, string> = TYPE_TO_FOLDER): string {\n const folder = typeToFolder[type] ?? deriveDefaultTypeFolder(type);\n return path.join(pmRoot, folder);\n}\n\nexport function getItemPath(\n pmRoot: string,\n type: ItemType,\n id: string,\n itemFormat: ItemFormat = \"toon\",\n typeToFolder: Record<string, string> = TYPE_TO_FOLDER,\n): string {\n return path.join(getTypeDirPath(pmRoot, type, typeToFolder), `${id}${ITEM_FILE_EXTENSION_BY_FORMAT[itemFormat]}`);\n}\n\nexport function getItemFormatFromPath(itemPath: string): ItemFormat | null {\n const extension = path.extname(itemPath).toLowerCase() as keyof typeof ITEM_FORMAT_BY_EXTENSION;\n return ITEM_FORMAT_BY_EXTENSION[extension] ?? null;\n}\n\nexport function getHistoryPath(pmRoot: string, id: string): string {\n return path.join(pmRoot, \"history\", `${id}.jsonl`);\n}\n\nexport function getLockPath(pmRoot: string, id: string): string {\n return path.join(pmRoot, \"locks\", `${id}.lock`);\n}\n\nexport function getRuntimePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\");\n}\n\nexport function getTestRunsPath(pmRoot: string): string {\n return path.join(getRuntimePath(pmRoot), \"test-runs\");\n}\n\nexport function getTestRunsRecordsPath(pmRoot: string): string {\n return path.join(getTestRunsPath(pmRoot), \"runs\");\n}\n\nexport function getTestRunRecordPath(pmRoot: string, runId: string): string {\n return path.join(getTestRunsRecordsPath(pmRoot), `${runId}.json`);\n}\n\nexport function getTestRunsStdoutPath(pmRoot: string): string {\n return path.join(getTestRunsPath(pmRoot), \"stdout\");\n}\n\nexport function getTestRunsStderrPath(pmRoot: string): string {\n return path.join(getTestRunsPath(pmRoot), \"stderr\");\n}\n\nexport function getTestRunStdoutPath(pmRoot: string, runId: string): string {\n return path.join(getTestRunsStdoutPath(pmRoot), `${runId}.log`);\n}\n\nexport function getTestRunStderrPath(pmRoot: string, runId: string): string {\n return path.join(getTestRunsStderrPath(pmRoot), `${runId}.log`);\n}\n\nexport function getTestRunsResultsPath(pmRoot: string): string {\n return path.join(getTestRunsPath(pmRoot), \"results\");\n}\n\nexport function getTestRunResultPath(pmRoot: string, runId: string): string {\n return path.join(getTestRunsResultsPath(pmRoot), `${runId}.json`);\n}\n"]}