@planu/cli 1.0.10 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/config/domain-bundles.json +134 -0
  2. package/dist/config/license-plans.json +7 -1
  3. package/dist/engine/bundle-installer.d.ts +24 -0
  4. package/dist/engine/bundle-installer.d.ts.map +1 -0
  5. package/dist/engine/bundle-installer.js +131 -0
  6. package/dist/engine/bundle-installer.js.map +1 -0
  7. package/dist/engine/git-hook-injector.d.ts +5 -0
  8. package/dist/engine/git-hook-injector.d.ts.map +1 -0
  9. package/dist/engine/git-hook-injector.js +86 -0
  10. package/dist/engine/git-hook-injector.js.map +1 -0
  11. package/dist/engine/merge-risk-assessor/analyzers.d.ts +22 -0
  12. package/dist/engine/merge-risk-assessor/analyzers.d.ts.map +1 -0
  13. package/dist/engine/merge-risk-assessor/analyzers.js +150 -0
  14. package/dist/engine/merge-risk-assessor/analyzers.js.map +1 -0
  15. package/dist/engine/merge-risk-assessor/git-diff-parser.d.ts +16 -0
  16. package/dist/engine/merge-risk-assessor/git-diff-parser.d.ts.map +1 -0
  17. package/dist/engine/merge-risk-assessor/git-diff-parser.js +48 -0
  18. package/dist/engine/merge-risk-assessor/git-diff-parser.js.map +1 -0
  19. package/dist/engine/merge-risk-assessor/index.d.ts +7 -0
  20. package/dist/engine/merge-risk-assessor/index.d.ts.map +1 -0
  21. package/dist/engine/merge-risk-assessor/index.js +98 -0
  22. package/dist/engine/merge-risk-assessor/index.js.map +1 -0
  23. package/dist/engine/pdf/browser-finder.d.ts.map +1 -1
  24. package/dist/engine/pdf/browser-finder.js +46 -4
  25. package/dist/engine/pdf/browser-finder.js.map +1 -1
  26. package/dist/engine/pdf/html-to-pdf.d.ts.map +1 -1
  27. package/dist/engine/pdf/html-to-pdf.js +18 -13
  28. package/dist/engine/pdf/html-to-pdf.js.map +1 -1
  29. package/dist/engine/spec-prompt-generator.d.ts +12 -0
  30. package/dist/engine/spec-prompt-generator.d.ts.map +1 -0
  31. package/dist/engine/spec-prompt-generator.js +69 -0
  32. package/dist/engine/spec-prompt-generator.js.map +1 -0
  33. package/dist/engine/telemetry/health-checker.d.ts +5 -0
  34. package/dist/engine/telemetry/health-checker.d.ts.map +1 -0
  35. package/dist/engine/telemetry/health-checker.js +297 -0
  36. package/dist/engine/telemetry/health-checker.js.map +1 -0
  37. package/dist/engine/telemetry/index.d.ts +1 -0
  38. package/dist/engine/telemetry/index.d.ts.map +1 -1
  39. package/dist/engine/telemetry/index.js +1 -0
  40. package/dist/engine/telemetry/index.js.map +1 -1
  41. package/dist/index.js +12 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/tools/domain-bundle-handler.d.ts +37 -0
  44. package/dist/tools/domain-bundle-handler.d.ts.map +1 -0
  45. package/dist/tools/domain-bundle-handler.js +84 -0
  46. package/dist/tools/domain-bundle-handler.js.map +1 -0
  47. package/dist/tools/init-project/handler.d.ts.map +1 -1
  48. package/dist/tools/init-project/handler.js +2 -1
  49. package/dist/tools/init-project/handler.js.map +1 -1
  50. package/dist/tools/init-project/scaffold-writer.d.ts +1 -0
  51. package/dist/tools/init-project/scaffold-writer.d.ts.map +1 -1
  52. package/dist/tools/init-project/scaffold-writer.js +11 -0
  53. package/dist/tools/init-project/scaffold-writer.js.map +1 -1
  54. package/dist/tools/merge-risk-handler.d.ts +3 -0
  55. package/dist/tools/merge-risk-handler.d.ts.map +1 -0
  56. package/dist/tools/merge-risk-handler.js +83 -0
  57. package/dist/tools/merge-risk-handler.js.map +1 -0
  58. package/dist/tools/register-domain-bundle-tools.d.ts +3 -0
  59. package/dist/tools/register-domain-bundle-tools.d.ts.map +1 -0
  60. package/dist/tools/register-domain-bundle-tools.js +27 -0
  61. package/dist/tools/register-domain-bundle-tools.js.map +1 -0
  62. package/dist/tools/register-merge-risk-tools.d.ts +5 -0
  63. package/dist/tools/register-merge-risk-tools.d.ts.map +1 -0
  64. package/dist/tools/register-merge-risk-tools.js +6 -0
  65. package/dist/tools/register-merge-risk-tools.js.map +1 -0
  66. package/dist/tools/register-spec-prompt-tools.d.ts +3 -0
  67. package/dist/tools/register-spec-prompt-tools.d.ts.map +1 -0
  68. package/dist/tools/register-spec-prompt-tools.js +5 -0
  69. package/dist/tools/register-spec-prompt-tools.js.map +1 -0
  70. package/dist/tools/register-telemetry-health-tools.d.ts +3 -0
  71. package/dist/tools/register-telemetry-health-tools.d.ts.map +1 -0
  72. package/dist/tools/register-telemetry-health-tools.js +27 -0
  73. package/dist/tools/register-telemetry-health-tools.js.map +1 -0
  74. package/dist/tools/spec-prompt-handler.d.ts +5 -0
  75. package/dist/tools/spec-prompt-handler.d.ts.map +1 -0
  76. package/dist/tools/spec-prompt-handler.js +142 -0
  77. package/dist/tools/spec-prompt-handler.js.map +1 -0
  78. package/dist/tools/telemetry-health-handler.d.ts +3 -0
  79. package/dist/tools/telemetry-health-handler.d.ts.map +1 -0
  80. package/dist/tools/telemetry-health-handler.js +49 -0
  81. package/dist/tools/telemetry-health-handler.js.map +1 -0
  82. package/dist/types/git.d.ts +58 -0
  83. package/dist/types/git.d.ts.map +1 -1
  84. package/dist/types/mcp.d.ts +29 -0
  85. package/dist/types/mcp.d.ts.map +1 -1
  86. package/dist/types/project/planu-config.d.ts +2 -0
  87. package/dist/types/project/planu-config.d.ts.map +1 -1
  88. package/dist/types/telemetry.d.ts +15 -0
  89. package/dist/types/telemetry.d.ts.map +1 -1
  90. package/dist/types/tooling/bundles.d.ts +34 -0
  91. package/dist/types/tooling/bundles.d.ts.map +1 -0
  92. package/dist/types/tooling/bundles.js +3 -0
  93. package/dist/types/tooling/bundles.js.map +1 -0
  94. package/dist/types/tooling/index.d.ts +1 -0
  95. package/dist/types/tooling/index.d.ts.map +1 -1
  96. package/dist/types/tooling.d.ts +1 -1
  97. package/dist/types/tooling.d.ts.map +1 -1
  98. package/package.json +1 -1
  99. package/src/config/domain-bundles.json +134 -0
  100. package/src/config/license-plans.json +7 -1
@@ -0,0 +1,48 @@
1
+ // Planu — git diff parser for merge risk assessor
2
+ import { execFile } from 'node:child_process';
3
+ import { promisify } from 'node:util';
4
+ const execFileAsync = promisify(execFile);
5
+ /**
6
+ * Runs `git diff --stat {baseBranch}...{branch}` and parses the output.
7
+ * Uses execFile (not exec) to prevent shell injection.
8
+ */
9
+ export async function getDiffStats(projectPath, branch, baseBranch) {
10
+ const { stdout } = await execFileAsync('git', ['diff', '--stat', `${baseBranch}...${branch}`], { cwd: projectPath });
11
+ return parseDiffStatOutput(stdout);
12
+ }
13
+ /**
14
+ * Parses the output of `git diff --stat` into structured stats.
15
+ * Example output:
16
+ * src/foo.ts | 10 +++--
17
+ * src/bar.ts | 4 +
18
+ * 2 files changed, 11 insertions(+), 4 deletions(-)
19
+ */
20
+ export function parseDiffStatOutput(output) {
21
+ const lines = output.trim().split('\n').filter(Boolean);
22
+ if (lines.length === 0) {
23
+ return { filesChanged: 0, linesAdded: 0, linesRemoved: 0, files: [] };
24
+ }
25
+ const files = [];
26
+ for (const line of lines) {
27
+ // File lines contain a pipe character
28
+ if (line.includes('|')) {
29
+ const filePart = line.split('|')[0];
30
+ if (filePart !== undefined) {
31
+ const fileName = filePart.trim();
32
+ if (fileName) {
33
+ files.push(fileName);
34
+ }
35
+ }
36
+ }
37
+ }
38
+ // Summary line: "N files changed, X insertions(+), Y deletions(-)"
39
+ const summaryLine = lines[lines.length - 1] ?? '';
40
+ const filesMatch = /(\d+) files? changed/.exec(summaryLine);
41
+ const insertionsMatch = /(\d+) insertions?/.exec(summaryLine);
42
+ const deletionsMatch = /(\d+) deletions?/.exec(summaryLine);
43
+ const filesChanged = filesMatch?.[1] ? parseInt(filesMatch[1], 10) : files.length;
44
+ const linesAdded = insertionsMatch?.[1] ? parseInt(insertionsMatch[1], 10) : 0;
45
+ const linesRemoved = deletionsMatch?.[1] ? parseInt(deletionsMatch[1], 10) : 0;
46
+ return { filesChanged, linesAdded, linesRemoved, files };
47
+ }
48
+ //# sourceMappingURL=git-diff-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-diff-parser.js","sourceRoot":"","sources":["../../../src/engine/merge-risk-assessor/git-diff-parser.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAKtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAAmB,EACnB,MAAc,EACd,UAAkB;IAElB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,KAAK,EACL,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,MAAM,MAAM,EAAE,CAAC,EAC/C,EAAE,GAAG,EAAE,WAAW,EAAE,CACrB,CAAC;IAEF,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAExD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACxE,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,sCAAsC;QACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACjC,IAAI,QAAQ,EAAE,CAAC;oBACb,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,eAAe,GAAG,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE5D,MAAM,YAAY,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IAClF,MAAM,UAAU,GAAG,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,YAAY,GAAG,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { MergeRiskResult, AssessMergeRiskOptions } from '../../types/index.js';
2
+ /**
3
+ * Main orchestrator: runs all analyzers, computes weighted risk score,
4
+ * and returns a structured MergeRiskResult.
5
+ */
6
+ export declare function assessMergeRisk(projectPath: string, options: AssessMergeRiskOptions): Promise<MergeRiskResult>;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/merge-risk-assessor/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,eAAe,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAyDnG;;;GAGG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAyE1B"}
@@ -0,0 +1,98 @@
1
+ import { getDiffStats } from './git-diff-parser.js';
2
+ import { analyzeSecuritySurface, analyzeCoverageDelta, analyzeBlastRadius, analyzeReversibility, analyzeSpecCompliance, } from './analyzers.js';
3
+ import { execFile } from 'node:child_process';
4
+ import { promisify } from 'node:util';
5
+ const execFileAsync = promisify(execFile);
6
+ async function getCurrentBranch(projectPath) {
7
+ const { stdout } = await execFileAsync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
8
+ cwd: projectPath,
9
+ });
10
+ return stdout.trim();
11
+ }
12
+ async function getDiff(projectPath, branch, baseBranch) {
13
+ const { stdout } = await execFileAsync('git', ['diff', `${baseBranch}...${branch}`], { cwd: projectPath });
14
+ return stdout;
15
+ }
16
+ function buildRecommendation(score) {
17
+ if (score <= 30) {
18
+ return 'auto-merge';
19
+ }
20
+ if (score <= 70) {
21
+ return 'human-review';
22
+ }
23
+ return 'block';
24
+ }
25
+ function buildHumanSummary(score, recommendation, topReason) {
26
+ const recommendationLabel = recommendation === 'auto-merge'
27
+ ? 'Safe to auto-merge'
28
+ : recommendation === 'human-review'
29
+ ? 'Human review required'
30
+ : 'Blocked — high risk';
31
+ return `Risk score ${score}/100 — ${recommendationLabel}. ${topReason}`;
32
+ }
33
+ /**
34
+ * Main orchestrator: runs all analyzers, computes weighted risk score,
35
+ * and returns a structured MergeRiskResult.
36
+ */
37
+ export async function assessMergeRisk(projectPath, options) {
38
+ const baseBranch = options.baseBranch ?? 'main';
39
+ const branch = options.branch ?? (await getCurrentBranch(projectPath));
40
+ const [diffStats, diff] = await Promise.all([
41
+ getDiffStats(projectPath, branch, baseBranch),
42
+ getDiff(projectPath, branch, baseBranch),
43
+ ]);
44
+ const { filesChanged, linesAdded, linesRemoved, files } = diffStats;
45
+ const securityResult = analyzeSecuritySurface(files, diff);
46
+ const coverageResult = analyzeCoverageDelta(linesAdded, files);
47
+ const blastResult = analyzeBlastRadius(filesChanged, files);
48
+ const reversibilityResult = analyzeReversibility(files, diff);
49
+ const complianceResult = analyzeSpecCompliance(files, options.context);
50
+ const breakdown = [
51
+ {
52
+ category: 'Security Surface',
53
+ score: securityResult.score,
54
+ weight: 0.3,
55
+ reason: securityResult.reason,
56
+ },
57
+ {
58
+ category: 'Coverage Delta',
59
+ score: coverageResult.score,
60
+ weight: 0.25,
61
+ reason: coverageResult.reason,
62
+ },
63
+ {
64
+ category: 'Blast Radius',
65
+ score: blastResult.score,
66
+ weight: 0.2,
67
+ reason: blastResult.reason,
68
+ },
69
+ {
70
+ category: 'Reversibility',
71
+ score: reversibilityResult.score,
72
+ weight: 0.15,
73
+ reason: reversibilityResult.reason,
74
+ },
75
+ {
76
+ category: 'Spec Compliance',
77
+ score: complianceResult.score,
78
+ weight: 0.1,
79
+ reason: complianceResult.reason,
80
+ },
81
+ ];
82
+ const riskScore = Math.round(breakdown.reduce((acc, b) => acc + b.score * b.weight, 0));
83
+ const recommendation = buildRecommendation(riskScore);
84
+ // Top reason = highest weighted contribution
85
+ const topBreakdown = [...breakdown].sort((a, b) => b.score * b.weight - a.score * a.weight)[0];
86
+ const topReason = topBreakdown?.reason ?? 'No significant risk factors';
87
+ const humanSummary = buildHumanSummary(riskScore, recommendation, topReason);
88
+ return {
89
+ riskScore,
90
+ recommendation,
91
+ breakdown,
92
+ filesChanged,
93
+ linesAdded,
94
+ linesRemoved,
95
+ humanSummary,
96
+ };
97
+ }
98
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/merge-risk-assessor/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"browser-finder.d.ts","sourceRoot":"","sources":["../../../src/engine/pdf/browser-finder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,YAAY,EAAE,WAAW,EAAE,CAAC;AA0J5B,wBAAsB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAsCxD;AAED,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAEpD"}
1
+ {"version":3,"file":"browser-finder.d.ts","sourceRoot":"","sources":["../../../src/engine/pdf/browser-finder.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,YAAY,EAAE,WAAW,EAAE,CAAC;AA+L5B,wBAAsB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CA4CxD;AAED,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAEpD"}
@@ -1,6 +1,7 @@
1
1
  import { existsSync } from 'fs';
2
2
  import { execFile } from 'child_process';
3
3
  import { promisify } from 'util';
4
+ import { createRequire } from 'module';
4
5
  const execFileAsync = promisify(execFile);
5
6
  const MACOS_PATHS = [
6
7
  {
@@ -63,6 +64,7 @@ const LINUX_PATHS = [
63
64
  ];
64
65
  function buildBrowserNotFoundMessage() {
65
66
  const platform = process.platform;
67
+ const isHeadlessServer = platform === 'linux' && !process.env.DISPLAY && !process.env.WAYLAND_DISPLAY;
66
68
  const installHints = platform === 'darwin'
67
69
  ? [
68
70
  ' brew install --cask google-chrome',
@@ -76,18 +78,29 @@ function buildBrowserNotFoundMessage() {
76
78
  ' # Snap: sudo snap install chromium',
77
79
  ]
78
80
  : [' winget install Google.Chrome', ' # or: winget install Microsoft.Edge'];
81
+ const serverHint = isHeadlessServer
82
+ ? [
83
+ '',
84
+ ' Detected: headless server environment (no DISPLAY)',
85
+ ' Recommended for servers:',
86
+ ' sudo apt-get install -y chromium-browser',
87
+ ' # or use puppeteer for a self-contained setup:',
88
+ ' npm install puppeteer # includes bundled Chromium',
89
+ ]
90
+ : [];
79
91
  return [
80
92
  'No Chromium-based browser found for PDF generation.',
81
93
  '',
82
94
  'Planu needs Chrome, Chromium, Edge, or Brave to convert HTML to PDF.',
83
95
  '',
84
- 'How to fix:',
96
+ 'Quick fix — set PLANU_CHROME_PATH to your browser executable:',
97
+ ' export PLANU_CHROME_PATH="/path/to/chrome"',
85
98
  '',
86
- ' Option 1 — Install a supported browser:',
99
+ 'Or install a supported browser:',
87
100
  ...installHints,
101
+ ...serverHint,
88
102
  '',
89
- ' Option 2 Set PLANU_CHROME_PATH to your browser executable:',
90
- ' export PLANU_CHROME_PATH="/path/to/chrome"',
103
+ 'Tip: if puppeteer is installed in your project, Planu will use its bundled Chromium automatically.',
91
104
  ].join('\n');
92
105
  }
93
106
  async function getBrowserVersion(browserPath) {
@@ -99,6 +112,30 @@ async function getBrowserVersion(browserPath) {
99
112
  return undefined;
100
113
  }
101
114
  }
115
+ // Fix 2: Try puppeteer/puppeteer-core as optional peer dep fallback
116
+ function tryPuppeteerBrowser() {
117
+ try {
118
+ const require = createRequire(import.meta.url);
119
+ let chromePath;
120
+ for (const pkg of ['puppeteer', 'puppeteer-core']) {
121
+ try {
122
+ const p = require(pkg);
123
+ chromePath = p.executablePath();
124
+ break;
125
+ }
126
+ catch {
127
+ // not installed — try next
128
+ }
129
+ }
130
+ if (!chromePath || !existsSync(chromePath)) {
131
+ return null;
132
+ }
133
+ return { path: chromePath, name: 'chromium' };
134
+ }
135
+ catch {
136
+ return null;
137
+ }
138
+ }
102
139
  async function resolveLinuxBinary(bin) {
103
140
  try {
104
141
  const { stdout } = await execFileAsync('which', [bin], { timeout: 3000 });
@@ -170,6 +207,11 @@ export async function findBrowser() {
170
207
  }
171
208
  }
172
209
  }
210
+ // Fix 2: Puppeteer bundled Chromium as last-resort fallback (peer dep, not required)
211
+ const puppeteerBrowser = tryPuppeteerBrowser();
212
+ if (puppeteerBrowser) {
213
+ return puppeteerBrowser;
214
+ }
173
215
  throw new Error(buildBrowserNotFoundMessage());
174
216
  }
175
217
  export function findBrowserSync() {
@@ -1 +1 @@
1
- {"version":3,"file":"browser-finder.js","sourceRoot":"","sources":["../../../src/engine/pdf/browser-finder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browser-finder.js","sourceRoot":"","sources":["../../../src/engine/pdf/browser-finder.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"html-to-pdf.d.ts","sourceRoot":"","sources":["../../../src/engine/pdf/html-to-pdf.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAoFhE,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAC5B,OAAO,CAAC,SAAS,CAAC,CA8EpB"}
1
+ {"version":3,"file":"html-to-pdf.d.ts","sourceRoot":"","sources":["../../../src/engine/pdf/html-to-pdf.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAoFhE,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAC5B,OAAO,CAAC,SAAS,CAAC,CAuFpB"}
@@ -82,6 +82,19 @@ function buildChromeArgs(tempHtmlPath, outputPath) {
82
82
  export async function htmlToPdf(htmlPath, options) {
83
83
  const opts = { ...DEFAULT_PDF_OPTIONS, ...options };
84
84
  const absoluteHtmlPath = resolve(htmlPath);
85
+ // Fix 1: Validate HTML path BEFORE browser detection — clear ENOENT message early
86
+ let htmlContent;
87
+ try {
88
+ htmlContent = await readFile(absoluteHtmlPath, 'utf-8');
89
+ }
90
+ catch (err) {
91
+ const e = err;
92
+ if (e.code === 'ENOENT') {
93
+ throw new Error(`HTML file not found: ${absoluteHtmlPath}\n` +
94
+ `Tip: make sure the path is absolute or relative to the project root.`, { cause: err });
95
+ }
96
+ throw new Error(`Cannot read HTML file: ${absoluteHtmlPath} — ${e.message}`, { cause: err });
97
+ }
85
98
  const browser = await findBrowser();
86
99
  const outputPath = resolveOutputPath(absoluteHtmlPath, opts.outputPath);
87
100
  // Ensure output directory exists before launching Chrome
@@ -93,18 +106,6 @@ export async function htmlToPdf(htmlPath, options) {
93
106
  const e = err;
94
107
  throw new Error(`Cannot create output directory: ${outputDir} — ${e.message}`, { cause: err });
95
108
  }
96
- // Read HTML — single operation replacing stat+readFile (eliminates TOCTOU race)
97
- let htmlContent;
98
- try {
99
- htmlContent = await readFile(absoluteHtmlPath, 'utf-8');
100
- }
101
- catch (err) {
102
- const e = err;
103
- if (e.code === 'ENOENT') {
104
- throw new Error(`HTML file not found: ${absoluteHtmlPath}`, { cause: err });
105
- }
106
- throw new Error(`Cannot read HTML file: ${absoluteHtmlPath} — ${e.message}`, { cause: err });
107
- }
108
109
  const enhancedHtml = injectCssIntoHtml(htmlContent, buildPrintEnhancementCSS(opts));
109
110
  const tempHtmlPath = join(dirname(absoluteHtmlPath), `.print-temp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.html`);
110
111
  await writeFile(tempHtmlPath, enhancedHtml, 'utf-8');
@@ -123,8 +124,12 @@ export async function htmlToPdf(htmlPath, options) {
123
124
  throw new Error(`PDF generation failed: ${stderr}`, { cause: err });
124
125
  }
125
126
  finally {
127
+ // Fix 4: Silence ENOENT on temp file cleanup — file may already be gone on timeout
126
128
  await unlink(tempHtmlPath).catch((err) => {
127
- console.error('[Planu] Failed to clean up temp HTML file:', err);
129
+ const e = err;
130
+ if (e.code !== 'ENOENT') {
131
+ console.error('[Planu] Failed to clean up temp HTML file:', err);
132
+ }
128
133
  });
129
134
  }
130
135
  let pdfStat;
@@ -1 +1 @@
1
- {"version":3,"file":"html-to-pdf.js","sourceRoot":"","sources":["../../../src/engine/pdf/html-to-pdf.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"html-to-pdf.js","sourceRoot":"","sources":["../../../src/engine/pdf/html-to-pdf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { SpecPromptDefinition, SpecPromptInput } from '../types/index.js';
2
+ /**
3
+ * Builds the prompt name from spec id and slug, truncated to MAX_NAME_LENGTH.
4
+ * Format: `planu:{id}-{slug}` (e.g. `planu:SPEC-342-export-pdf`)
5
+ */
6
+ export declare function buildPromptName(id: string, slug: string): string;
7
+ /**
8
+ * Generates a SpecPromptDefinition from a Planu spec.
9
+ * The resulting definition can be registered as an MCP prompt via server.prompt().
10
+ */
11
+ export declare function generatePromptFromSpec(spec: SpecPromptInput): SpecPromptDefinition;
12
+ //# sourceMappingURL=spec-prompt-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-prompt-generator.d.ts","sourceRoot":"","sources":["../../src/engine/spec-prompt-generator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AA8B/E;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhE;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,eAAe,GAAG,oBAAoB,CAgClF"}
@@ -0,0 +1,69 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Constants
3
+ // ---------------------------------------------------------------------------
4
+ const MAX_NAME_LENGTH = 64;
5
+ const CONTEXT_ARGUMENT = {
6
+ name: 'context',
7
+ description: 'Additional context for this spec execution',
8
+ required: false,
9
+ };
10
+ // ---------------------------------------------------------------------------
11
+ // Helpers
12
+ // ---------------------------------------------------------------------------
13
+ /**
14
+ * Sanitizes a string into a valid MCP prompt name segment.
15
+ * Lowercases, replaces non-alphanumeric chars with hyphens,
16
+ * collapses repeated hyphens, and strips leading/trailing hyphens.
17
+ */
18
+ function sanitizeSegment(value) {
19
+ return value
20
+ .toLowerCase()
21
+ .replace(/[^a-z0-9-]/g, '-')
22
+ .replace(/-{2,}/g, '-')
23
+ .replace(/^-+|-+$/g, '');
24
+ }
25
+ /**
26
+ * Builds the prompt name from spec id and slug, truncated to MAX_NAME_LENGTH.
27
+ * Format: `planu:{id}-{slug}` (e.g. `planu:SPEC-342-export-pdf`)
28
+ */
29
+ export function buildPromptName(id, slug) {
30
+ const idPart = sanitizeSegment(id);
31
+ const slugPart = sanitizeSegment(slug);
32
+ const full = `planu:${idPart}-${slugPart}`;
33
+ return full.slice(0, MAX_NAME_LENGTH);
34
+ }
35
+ // ---------------------------------------------------------------------------
36
+ // Public API
37
+ // ---------------------------------------------------------------------------
38
+ /**
39
+ * Generates a SpecPromptDefinition from a Planu spec.
40
+ * The resulting definition can be registered as an MCP prompt via server.prompt().
41
+ */
42
+ export function generatePromptFromSpec(spec) {
43
+ const name = buildPromptName(spec.id, spec.slug);
44
+ const firstCriterion = spec.criteria?.[0];
45
+ const descriptionHint = firstCriterion !== undefined ? ` | ${firstCriterion}` : '';
46
+ const description = `${spec.title}${descriptionHint}`;
47
+ const criteriaLines = spec.criteria !== undefined && spec.criteria.length > 0
48
+ ? spec.criteria.map((c, i) => `${i + 1}. ${c}`).join('\n')
49
+ : 'No acceptance criteria defined.';
50
+ const summarySection = spec.summary !== undefined ? `\n\nSummary: ${spec.summary}` : '';
51
+ const template = [
52
+ `You are implementing spec ${spec.id}: ${spec.title}.`,
53
+ summarySection,
54
+ '',
55
+ 'Acceptance criteria:',
56
+ criteriaLines,
57
+ '',
58
+ 'Follow each criterion exactly. When done, run validate to confirm compliance.',
59
+ ]
60
+ .join('\n')
61
+ .trim();
62
+ return {
63
+ name,
64
+ description,
65
+ arguments: [{ ...CONTEXT_ARGUMENT }],
66
+ template,
67
+ };
68
+ }
69
+ //# sourceMappingURL=spec-prompt-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-prompt-generator.js","sourceRoot":"","sources":["../../src/engine/spec-prompt-generator.ts"],"names":[],"mappings":"AAIA,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,4CAA4C;IACzD,QAAQ,EAAE,KAAK;CACP,CAAC;AAEX,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;GAIG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAAU,EAAE,IAAY;IACtD,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,SAAS,MAAM,IAAI,QAAQ,EAAE,CAAC;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;AACxC,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAqB;IAC1D,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEjD,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,eAAe,GAAG,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,eAAe,EAAE,CAAC;IAEtD,MAAM,aAAa,GACjB,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;QACrD,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1D,CAAC,CAAC,iCAAiC,CAAC;IAExC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAExF,MAAM,QAAQ,GAAG;QACf,6BAA6B,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK,GAAG;QACtD,cAAc;QACd,EAAE;QACF,sBAAsB;QACtB,aAAa;QACb,EAAE;QACF,+EAA+E;KAChF;SACE,IAAI,CAAC,IAAI,CAAC;SACV,IAAI,EAAE,CAAC;IAEV,OAAO;QACL,IAAI;QACJ,WAAW;QACX,SAAS,EAAE,CAAC,EAAE,GAAG,gBAAgB,EAAE,CAAC;QACpC,QAAQ;KACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { TelemetryHealthResult } from '../../types/index.js';
2
+ export declare function checkTelemetryHealth(projectPath: string, options?: {
3
+ sendTestEvent?: boolean;
4
+ }): Promise<TelemetryHealthResult>;
5
+ //# sourceMappingURL=health-checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-checker.d.ts","sourceRoot":"","sources":["../../../src/engine/telemetry/health-checker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAkB,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AA2SlF,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACpC,OAAO,CAAC,qBAAqB,CAAC,CAkDhC"}