@planu/cli 1.0.11 → 1.1.1
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.
- package/dist/config/domain-bundles.json +134 -0
- package/dist/config/license-plans.json +7 -1
- package/dist/engine/bundle-installer.d.ts +24 -0
- package/dist/engine/bundle-installer.d.ts.map +1 -0
- package/dist/engine/bundle-installer.js +131 -0
- package/dist/engine/bundle-installer.js.map +1 -0
- package/dist/engine/git-hook-injector.d.ts +5 -0
- package/dist/engine/git-hook-injector.d.ts.map +1 -0
- package/dist/engine/git-hook-injector.js +86 -0
- package/dist/engine/git-hook-injector.js.map +1 -0
- package/dist/engine/merge-risk-assessor/analyzers.d.ts +22 -0
- package/dist/engine/merge-risk-assessor/analyzers.d.ts.map +1 -0
- package/dist/engine/merge-risk-assessor/analyzers.js +150 -0
- package/dist/engine/merge-risk-assessor/analyzers.js.map +1 -0
- package/dist/engine/merge-risk-assessor/git-diff-parser.d.ts +16 -0
- package/dist/engine/merge-risk-assessor/git-diff-parser.d.ts.map +1 -0
- package/dist/engine/merge-risk-assessor/git-diff-parser.js +48 -0
- package/dist/engine/merge-risk-assessor/git-diff-parser.js.map +1 -0
- package/dist/engine/merge-risk-assessor/index.d.ts +7 -0
- package/dist/engine/merge-risk-assessor/index.d.ts.map +1 -0
- package/dist/engine/merge-risk-assessor/index.js +98 -0
- package/dist/engine/merge-risk-assessor/index.js.map +1 -0
- package/dist/engine/spec-prompt-generator.d.ts +12 -0
- package/dist/engine/spec-prompt-generator.d.ts.map +1 -0
- package/dist/engine/spec-prompt-generator.js +69 -0
- package/dist/engine/spec-prompt-generator.js.map +1 -0
- package/dist/engine/telemetry/health-checker.d.ts +5 -0
- package/dist/engine/telemetry/health-checker.d.ts.map +1 -0
- package/dist/engine/telemetry/health-checker.js +297 -0
- package/dist/engine/telemetry/health-checker.js.map +1 -0
- package/dist/engine/telemetry/index.d.ts +1 -0
- package/dist/engine/telemetry/index.d.ts.map +1 -1
- package/dist/engine/telemetry/index.js +1 -0
- package/dist/engine/telemetry/index.js.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/domain-bundle-handler.d.ts +37 -0
- package/dist/tools/domain-bundle-handler.d.ts.map +1 -0
- package/dist/tools/domain-bundle-handler.js +84 -0
- package/dist/tools/domain-bundle-handler.js.map +1 -0
- package/dist/tools/generate-docs-site.d.ts.map +1 -1
- package/dist/tools/generate-docs-site.js +15 -1
- package/dist/tools/generate-docs-site.js.map +1 -1
- package/dist/tools/init-project/handler.d.ts.map +1 -1
- package/dist/tools/init-project/handler.js +2 -1
- package/dist/tools/init-project/handler.js.map +1 -1
- package/dist/tools/init-project/scaffold-writer.d.ts +1 -0
- package/dist/tools/init-project/scaffold-writer.d.ts.map +1 -1
- package/dist/tools/init-project/scaffold-writer.js +11 -0
- package/dist/tools/init-project/scaffold-writer.js.map +1 -1
- package/dist/tools/merge-risk-handler.d.ts +3 -0
- package/dist/tools/merge-risk-handler.d.ts.map +1 -0
- package/dist/tools/merge-risk-handler.js +83 -0
- package/dist/tools/merge-risk-handler.js.map +1 -0
- package/dist/tools/register-domain-bundle-tools.d.ts +3 -0
- package/dist/tools/register-domain-bundle-tools.d.ts.map +1 -0
- package/dist/tools/register-domain-bundle-tools.js +27 -0
- package/dist/tools/register-domain-bundle-tools.js.map +1 -0
- package/dist/tools/register-merge-risk-tools.d.ts +5 -0
- package/dist/tools/register-merge-risk-tools.d.ts.map +1 -0
- package/dist/tools/register-merge-risk-tools.js +6 -0
- package/dist/tools/register-merge-risk-tools.js.map +1 -0
- package/dist/tools/register-spec-prompt-tools.d.ts +3 -0
- package/dist/tools/register-spec-prompt-tools.d.ts.map +1 -0
- package/dist/tools/register-spec-prompt-tools.js +5 -0
- package/dist/tools/register-spec-prompt-tools.js.map +1 -0
- package/dist/tools/register-telemetry-health-tools.d.ts +3 -0
- package/dist/tools/register-telemetry-health-tools.d.ts.map +1 -0
- package/dist/tools/register-telemetry-health-tools.js +27 -0
- package/dist/tools/register-telemetry-health-tools.js.map +1 -0
- package/dist/tools/register-workspace-tools.d.ts.map +1 -1
- package/dist/tools/register-workspace-tools.js +0 -5
- package/dist/tools/register-workspace-tools.js.map +1 -1
- package/dist/tools/spec-prompt-handler.d.ts +5 -0
- package/dist/tools/spec-prompt-handler.d.ts.map +1 -0
- package/dist/tools/spec-prompt-handler.js +142 -0
- package/dist/tools/spec-prompt-handler.js.map +1 -0
- package/dist/tools/telemetry-health-handler.d.ts +3 -0
- package/dist/tools/telemetry-health-handler.d.ts.map +1 -0
- package/dist/tools/telemetry-health-handler.js +49 -0
- package/dist/tools/telemetry-health-handler.js.map +1 -0
- package/dist/types/docs.d.ts +0 -1
- package/dist/types/docs.d.ts.map +1 -1
- package/dist/types/git.d.ts +58 -0
- package/dist/types/git.d.ts.map +1 -1
- package/dist/types/mcp.d.ts +29 -0
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/project/planu-config.d.ts +2 -0
- package/dist/types/project/planu-config.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +15 -0
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/types/tooling/bundles.d.ts +34 -0
- package/dist/types/tooling/bundles.d.ts.map +1 -0
- package/dist/types/tooling/bundles.js +3 -0
- package/dist/types/tooling/bundles.js.map +1 -0
- package/dist/types/tooling/index.d.ts +1 -0
- package/dist/types/tooling/index.d.ts.map +1 -1
- package/dist/types/tooling.d.ts +1 -1
- package/dist/types/tooling.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/config/domain-bundles.json +134 -0
- 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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"}
|
|
@@ -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 @@
|
|
|
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"}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
// engine/telemetry/health-checker.ts — SPEC-346: Diagnose why telemetry data is not reaching the dashboard.
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { readTelemetryConfig } from './telemetry-store.js';
|
|
5
|
+
import { sendTelemetryEvent } from './telemetry-client.js';
|
|
6
|
+
const NETWORK_TIMEOUT_MS = 5_000;
|
|
7
|
+
const RECENT_EVENT_THRESHOLD_DAYS = 7;
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Individual checks
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
async function checkConfigEnabled() {
|
|
12
|
+
const config = await readTelemetryConfig();
|
|
13
|
+
if (!config?.enabled) {
|
|
14
|
+
return {
|
|
15
|
+
check: {
|
|
16
|
+
name: 'config-enabled',
|
|
17
|
+
status: 'fail',
|
|
18
|
+
detail: 'Telemetry is disabled in ~/.planu/telemetry.json',
|
|
19
|
+
},
|
|
20
|
+
enabled: false,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
check: {
|
|
25
|
+
name: 'config-enabled',
|
|
26
|
+
status: 'ok',
|
|
27
|
+
detail: 'Telemetry is enabled',
|
|
28
|
+
},
|
|
29
|
+
enabled: true,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function checkEndpointConfigured(endpoint) {
|
|
33
|
+
if (!endpoint || endpoint.trim() === '') {
|
|
34
|
+
return {
|
|
35
|
+
name: 'endpoint-configured',
|
|
36
|
+
status: 'fail',
|
|
37
|
+
detail: 'No telemetry endpoint configured. Set PLANU_TELEMETRY_ENDPOINT env var.',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
name: 'endpoint-configured',
|
|
42
|
+
status: 'ok',
|
|
43
|
+
detail: `Endpoint: ${endpoint}`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async function checkNetworkReachable(endpoint) {
|
|
47
|
+
if (!endpoint) {
|
|
48
|
+
return {
|
|
49
|
+
name: 'network-reachable',
|
|
50
|
+
status: 'skip',
|
|
51
|
+
detail: 'Skipped — no endpoint to test',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetch(endpoint, {
|
|
56
|
+
method: 'GET',
|
|
57
|
+
signal: AbortSignal.timeout(NETWORK_TIMEOUT_MS),
|
|
58
|
+
});
|
|
59
|
+
if (response.ok || response.status < 500) {
|
|
60
|
+
return {
|
|
61
|
+
name: 'network-reachable',
|
|
62
|
+
status: 'ok',
|
|
63
|
+
detail: `Endpoint responded with HTTP ${response.status}`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
name: 'network-reachable',
|
|
68
|
+
status: 'warn',
|
|
69
|
+
detail: `Endpoint returned HTTP ${response.status} — server may be experiencing issues`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
74
|
+
return {
|
|
75
|
+
name: 'network-reachable',
|
|
76
|
+
status: 'warn',
|
|
77
|
+
detail: `Could not reach endpoint: ${message}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function checkLastEvent(projectPath) {
|
|
82
|
+
const candidates = [
|
|
83
|
+
join(projectPath, 'data', 'telemetry-events.json'),
|
|
84
|
+
join(projectPath, '.planu', 'telemetry-events.json'),
|
|
85
|
+
join(projectPath, 'data', 'telemetry.json'),
|
|
86
|
+
];
|
|
87
|
+
for (const candidate of candidates) {
|
|
88
|
+
try {
|
|
89
|
+
const raw = await readFile(candidate, 'utf-8');
|
|
90
|
+
const parsed = JSON.parse(raw);
|
|
91
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const last = parsed[parsed.length - 1];
|
|
95
|
+
const ts = typeof last.timestamp === 'string' ? last.timestamp : undefined;
|
|
96
|
+
if (!ts) {
|
|
97
|
+
return {
|
|
98
|
+
name: 'last-event',
|
|
99
|
+
status: 'warn',
|
|
100
|
+
detail: `Found event log at ${candidate} but last event has no timestamp`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const daysAgo = (Date.now() - new Date(ts).getTime()) / (1000 * 60 * 60 * 24);
|
|
104
|
+
if (daysAgo > RECENT_EVENT_THRESHOLD_DAYS) {
|
|
105
|
+
return {
|
|
106
|
+
name: 'last-event',
|
|
107
|
+
status: 'warn',
|
|
108
|
+
detail: `Last event was ${Math.floor(daysAgo)} days ago (${ts})`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
name: 'last-event',
|
|
113
|
+
status: 'ok',
|
|
114
|
+
detail: `Last event: ${ts} (${Math.floor(daysAgo)} days ago)`,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// try next candidate
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
name: 'last-event',
|
|
123
|
+
status: 'warn',
|
|
124
|
+
detail: 'No event log found — no events have been sent yet',
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async function checkErrorLog(projectPath) {
|
|
128
|
+
const candidates = [
|
|
129
|
+
join(projectPath, 'data', 'telemetry-errors.json'),
|
|
130
|
+
join(projectPath, '.planu', 'telemetry-errors.json'),
|
|
131
|
+
];
|
|
132
|
+
for (const candidate of candidates) {
|
|
133
|
+
try {
|
|
134
|
+
const raw = await readFile(candidate, 'utf-8');
|
|
135
|
+
const parsed = JSON.parse(raw);
|
|
136
|
+
if (!Array.isArray(parsed)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const recent = parsed.slice(-5);
|
|
140
|
+
if (recent.length === 0) {
|
|
141
|
+
return {
|
|
142
|
+
name: 'error-log',
|
|
143
|
+
status: 'ok',
|
|
144
|
+
detail: 'No telemetry errors recorded',
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const summary = recent
|
|
148
|
+
.map((e) => {
|
|
149
|
+
if (typeof e.message === 'string') {
|
|
150
|
+
return e.message;
|
|
151
|
+
}
|
|
152
|
+
if (typeof e.error === 'string') {
|
|
153
|
+
return e.error;
|
|
154
|
+
}
|
|
155
|
+
return '[unknown error]';
|
|
156
|
+
})
|
|
157
|
+
.join('; ');
|
|
158
|
+
return {
|
|
159
|
+
name: 'error-log',
|
|
160
|
+
status: 'warn',
|
|
161
|
+
detail: `${recent.length} recent error(s): ${summary}`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// try next candidate
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
name: 'error-log',
|
|
170
|
+
status: 'ok',
|
|
171
|
+
detail: 'No error log found',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
async function checkClientVersion(projectPath) {
|
|
175
|
+
const pkgPath = join(projectPath, 'package.json');
|
|
176
|
+
try {
|
|
177
|
+
const raw = await readFile(pkgPath, 'utf-8');
|
|
178
|
+
const pkg = JSON.parse(raw);
|
|
179
|
+
const version = typeof pkg.version === 'string' ? pkg.version : 'unknown';
|
|
180
|
+
const name = typeof pkg.name === 'string' ? pkg.name : 'unknown';
|
|
181
|
+
return {
|
|
182
|
+
name: 'version',
|
|
183
|
+
status: 'ok',
|
|
184
|
+
detail: `Client: ${name}@${version}`,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return {
|
|
189
|
+
name: 'version',
|
|
190
|
+
status: 'warn',
|
|
191
|
+
detail: `Could not read package.json at ${pkgPath}`,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
// Test event
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
function sendTestDiagnosticEvent(installationId) {
|
|
199
|
+
sendTelemetryEvent({
|
|
200
|
+
event: 'tool_used',
|
|
201
|
+
properties: {
|
|
202
|
+
tool: 'telemetry_health',
|
|
203
|
+
diagnostic: true,
|
|
204
|
+
timestamp: new Date().toISOString(),
|
|
205
|
+
},
|
|
206
|
+
installationId,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
// Status helpers
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
function buildRecommendation(status) {
|
|
213
|
+
switch (status) {
|
|
214
|
+
case 'disabled':
|
|
215
|
+
return 'Run configure_telemetry to enable usage tracking';
|
|
216
|
+
case 'misconfigured':
|
|
217
|
+
return 'Set PLANU_TELEMETRY_ENDPOINT or run configure_telemetry';
|
|
218
|
+
case 'degraded':
|
|
219
|
+
return 'Check network connectivity or firewall rules blocking outbound requests';
|
|
220
|
+
case 'healthy':
|
|
221
|
+
return 'Telemetry is working. If no data shows in dashboard, check the dashboard filters.';
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function buildHumanSummary(status, checks) {
|
|
225
|
+
const warnCount = checks.filter((c) => c.status === 'warn').length;
|
|
226
|
+
switch (status) {
|
|
227
|
+
case 'disabled':
|
|
228
|
+
return 'Telemetry is turned off — no usage data is being collected.';
|
|
229
|
+
case 'misconfigured':
|
|
230
|
+
return 'Telemetry cannot send data: configuration issue needs fixing.';
|
|
231
|
+
case 'degraded':
|
|
232
|
+
return `Telemetry is configured but ${warnCount} issue(s) may be preventing data from reaching the dashboard.`;
|
|
233
|
+
case 'healthy':
|
|
234
|
+
return 'Telemetry appears healthy. Data should be reaching the dashboard.';
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function computeStatus(isEnabled, checks) {
|
|
238
|
+
if (!isEnabled) {
|
|
239
|
+
return 'disabled';
|
|
240
|
+
}
|
|
241
|
+
const endpointCheck = checks.find((c) => c.name === 'endpoint-configured');
|
|
242
|
+
if (endpointCheck?.status === 'fail') {
|
|
243
|
+
return 'misconfigured';
|
|
244
|
+
}
|
|
245
|
+
const hasWarn = checks.some((c) => c.status === 'warn');
|
|
246
|
+
if (hasWarn) {
|
|
247
|
+
return 'degraded';
|
|
248
|
+
}
|
|
249
|
+
return 'healthy';
|
|
250
|
+
}
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
// Public API
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
export async function checkTelemetryHealth(projectPath, options) {
|
|
255
|
+
const { check: enabledCheck, enabled } = await checkConfigEnabled();
|
|
256
|
+
if (!enabled) {
|
|
257
|
+
const checks = [enabledCheck];
|
|
258
|
+
const status = 'disabled';
|
|
259
|
+
return {
|
|
260
|
+
status,
|
|
261
|
+
checks,
|
|
262
|
+
recommendation: buildRecommendation(status),
|
|
263
|
+
humanSummary: buildHumanSummary(status, checks),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// Default endpoint from telemetry-client
|
|
267
|
+
const defaultEndpoint = 'https://canusqigtzldstnjddio.supabase.co/rest/v1/telemetry_events';
|
|
268
|
+
const endpoint = process.env.PLANU_TELEMETRY_ENDPOINT?.trim() ?? defaultEndpoint;
|
|
269
|
+
const [networkCheck, lastEventCheck, errorLogCheck, versionCheck] = await Promise.all([
|
|
270
|
+
checkNetworkReachable(endpoint),
|
|
271
|
+
checkLastEvent(projectPath),
|
|
272
|
+
checkErrorLog(projectPath),
|
|
273
|
+
checkClientVersion(projectPath),
|
|
274
|
+
]);
|
|
275
|
+
const endpointCheck = checkEndpointConfigured(endpoint);
|
|
276
|
+
const checks = [
|
|
277
|
+
enabledCheck,
|
|
278
|
+
endpointCheck,
|
|
279
|
+
networkCheck,
|
|
280
|
+
lastEventCheck,
|
|
281
|
+
errorLogCheck,
|
|
282
|
+
versionCheck,
|
|
283
|
+
];
|
|
284
|
+
const status = computeStatus(enabled, checks);
|
|
285
|
+
if (options?.sendTestEvent === true) {
|
|
286
|
+
const config = await readTelemetryConfig();
|
|
287
|
+
const installationId = config?.installationId ?? 'anonymous';
|
|
288
|
+
sendTestDiagnosticEvent(installationId);
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
status,
|
|
292
|
+
checks,
|
|
293
|
+
recommendation: buildRecommendation(status),
|
|
294
|
+
humanSummary: buildHumanSummary(status, checks),
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=health-checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-checker.js","sourceRoot":"","sources":["../../../src/engine/telemetry/health-checker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/telemetry/index.ts"],"names":[],"mappings":"AACA,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/telemetry/index.ts"],"names":[],"mappings":"AACA,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/telemetry/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/telemetry/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -156,6 +156,10 @@ import { registerFilesystemHooksTools } from './tools/register-filesystem-hooks-
|
|
|
156
156
|
import { registerSkillsEvalTools } from './tools/register-skills-eval-tools.js';
|
|
157
157
|
import { registerTrialTools } from './tools/register-trial-tools.js';
|
|
158
158
|
import { registerDepAuditTools } from './tools/register-dep-audit-tools.js';
|
|
159
|
+
import { registerSpecPromptTools } from './tools/register-spec-prompt-tools.js';
|
|
160
|
+
import { registerTelemetryHealthTools } from './tools/register-telemetry-health-tools.js';
|
|
161
|
+
import { registerMergeRiskTools } from './tools/register-merge-risk-tools.js';
|
|
162
|
+
import { registerDomainBundleTools } from './tools/register-domain-bundle-tools.js';
|
|
159
163
|
// Server setup
|
|
160
164
|
const SERVER_INSTRUCTIONS = [
|
|
161
165
|
'CONTEXT — Why structured specs matter:',
|
|
@@ -377,11 +381,18 @@ function registerExtendedTools(s) {
|
|
|
377
381
|
registerSpec323Tools(s);
|
|
378
382
|
registerProductInsightsTools(s);
|
|
379
383
|
registerSpec331Tools(s);
|
|
384
|
+
registerLatestSpecTools(s);
|
|
385
|
+
registerPrompts(s);
|
|
386
|
+
}
|
|
387
|
+
function registerLatestSpecTools(s) {
|
|
380
388
|
registerFilesystemHooksTools(s);
|
|
381
389
|
registerSkillsEvalTools(s);
|
|
382
390
|
registerTrialTools(s);
|
|
383
391
|
registerDepAuditTools(s);
|
|
384
|
-
|
|
392
|
+
registerSpecPromptTools(s);
|
|
393
|
+
registerTelemetryHealthTools(s);
|
|
394
|
+
registerMergeRiskTools(s);
|
|
395
|
+
registerDomainBundleTools(s);
|
|
385
396
|
}
|
|
386
397
|
function createMcpServer() {
|
|
387
398
|
const s = withToolTracking(new McpServer({ name: 'planu', version: PLANU_VERSION }, { instructions: SERVER_INSTRUCTIONS }));
|