@planu/cli 1.4.0 → 1.6.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.
- package/dist/config/license-plans.json +15 -1
- package/dist/engine/audit-trail/formatter.d.ts +13 -0
- package/dist/engine/audit-trail/formatter.d.ts.map +1 -0
- package/dist/engine/audit-trail/formatter.js +43 -0
- package/dist/engine/audit-trail/formatter.js.map +1 -0
- package/dist/engine/audit-trail/hasher.d.ts +18 -0
- package/dist/engine/audit-trail/hasher.d.ts.map +1 -0
- package/dist/engine/audit-trail/hasher.js +46 -0
- package/dist/engine/audit-trail/hasher.js.map +1 -0
- package/dist/engine/audit-trail/index.d.ts +2 -0
- package/dist/engine/audit-trail/index.d.ts.map +1 -1
- package/dist/engine/audit-trail/index.js +4 -1
- package/dist/engine/audit-trail/index.js.map +1 -1
- package/dist/engine/auto-promoter.d.ts +14 -0
- package/dist/engine/auto-promoter.d.ts.map +1 -0
- package/dist/engine/auto-promoter.js +40 -0
- package/dist/engine/auto-promoter.js.map +1 -0
- package/dist/engine/compliance-test-generator/control-mapper.d.ts +4 -0
- package/dist/engine/compliance-test-generator/control-mapper.d.ts.map +1 -0
- package/dist/engine/compliance-test-generator/control-mapper.js +41 -0
- package/dist/engine/compliance-test-generator/control-mapper.js.map +1 -0
- package/dist/engine/compliance-test-generator/frameworks/iso42001.d.ts +3 -0
- package/dist/engine/compliance-test-generator/frameworks/iso42001.d.ts.map +1 -0
- package/dist/engine/compliance-test-generator/frameworks/iso42001.js +55 -0
- package/dist/engine/compliance-test-generator/frameworks/iso42001.js.map +1 -0
- package/dist/engine/compliance-test-generator/frameworks/pci-dss.d.ts +3 -0
- package/dist/engine/compliance-test-generator/frameworks/pci-dss.d.ts.map +1 -0
- package/dist/engine/compliance-test-generator/frameworks/pci-dss.js +55 -0
- package/dist/engine/compliance-test-generator/frameworks/pci-dss.js.map +1 -0
- package/dist/engine/compliance-test-generator/frameworks/soc2.d.ts +3 -0
- package/dist/engine/compliance-test-generator/frameworks/soc2.d.ts.map +1 -0
- package/dist/engine/compliance-test-generator/frameworks/soc2.js +47 -0
- package/dist/engine/compliance-test-generator/frameworks/soc2.js.map +1 -0
- package/dist/engine/compliance-test-generator/index.d.ts +3 -0
- package/dist/engine/compliance-test-generator/index.d.ts.map +1 -0
- package/dist/engine/compliance-test-generator/index.js +64 -0
- package/dist/engine/compliance-test-generator/index.js.map +1 -0
- package/dist/engine/compliance-test-generator/test-formatter.d.ts +6 -0
- package/dist/engine/compliance-test-generator/test-formatter.d.ts.map +1 -0
- package/dist/engine/compliance-test-generator/test-formatter.js +33 -0
- package/dist/engine/compliance-test-generator/test-formatter.js.map +1 -0
- package/dist/engine/cost-guardrails.d.ts +11 -0
- package/dist/engine/cost-guardrails.d.ts.map +1 -0
- package/dist/engine/cost-guardrails.js +39 -0
- package/dist/engine/cost-guardrails.js.map +1 -0
- package/dist/engine/dogfood-analyzer.d.ts +6 -0
- package/dist/engine/dogfood-analyzer.d.ts.map +1 -0
- package/dist/engine/dogfood-analyzer.js +59 -0
- package/dist/engine/dogfood-analyzer.js.map +1 -0
- package/dist/engine/drift-watcher/criteria-checker.d.ts +16 -0
- package/dist/engine/drift-watcher/criteria-checker.d.ts.map +1 -0
- package/dist/engine/drift-watcher/criteria-checker.js +81 -0
- package/dist/engine/drift-watcher/criteria-checker.js.map +1 -0
- package/dist/engine/drift-watcher/file-watcher.d.ts +8 -0
- package/dist/engine/drift-watcher/file-watcher.d.ts.map +1 -0
- package/dist/engine/drift-watcher/file-watcher.js +24 -0
- package/dist/engine/drift-watcher/file-watcher.js.map +1 -0
- package/dist/engine/drift-watcher/index.d.ts +19 -0
- package/dist/engine/drift-watcher/index.d.ts.map +1 -0
- package/dist/engine/drift-watcher/index.js +70 -0
- package/dist/engine/drift-watcher/index.js.map +1 -0
- package/dist/engine/hooks-reconciler.d.ts +7 -1
- package/dist/engine/hooks-reconciler.d.ts.map +1 -1
- package/dist/engine/hooks-reconciler.js +127 -2
- package/dist/engine/hooks-reconciler.js.map +1 -1
- package/dist/engine/mcp-gateway/gateway-registry.d.ts +19 -0
- package/dist/engine/mcp-gateway/gateway-registry.d.ts.map +1 -0
- package/dist/engine/mcp-gateway/gateway-registry.js +33 -0
- package/dist/engine/mcp-gateway/gateway-registry.js.map +1 -0
- package/dist/engine/mcp-gateway/gateway-scanner.d.ts +17 -0
- package/dist/engine/mcp-gateway/gateway-scanner.d.ts.map +1 -0
- package/dist/engine/mcp-gateway/gateway-scanner.js +62 -0
- package/dist/engine/mcp-gateway/gateway-scanner.js.map +1 -0
- package/dist/engine/mcp-gateway/index.d.ts +3 -0
- package/dist/engine/mcp-gateway/index.d.ts.map +1 -0
- package/dist/engine/mcp-gateway/index.js +4 -0
- package/dist/engine/mcp-gateway/index.js.map +1 -0
- package/dist/engine/multi-repo/companion-spec-builder.d.ts +9 -0
- package/dist/engine/multi-repo/companion-spec-builder.d.ts.map +1 -0
- package/dist/engine/multi-repo/companion-spec-builder.js +22 -0
- package/dist/engine/multi-repo/companion-spec-builder.js.map +1 -0
- package/dist/engine/multi-repo/consumer-scanner.d.ts +12 -0
- package/dist/engine/multi-repo/consumer-scanner.d.ts.map +1 -0
- package/dist/engine/multi-repo/consumer-scanner.js +48 -0
- package/dist/engine/multi-repo/consumer-scanner.js.map +1 -0
- package/dist/engine/multi-repo/index.d.ts +4 -0
- package/dist/engine/multi-repo/index.d.ts.map +1 -0
- package/dist/engine/multi-repo/index.js +5 -0
- package/dist/engine/multi-repo/index.js.map +1 -0
- package/dist/engine/multi-repo/refactor-tracker.d.ts +7 -0
- package/dist/engine/multi-repo/refactor-tracker.d.ts.map +1 -0
- package/dist/engine/multi-repo/refactor-tracker.js +22 -0
- package/dist/engine/multi-repo/refactor-tracker.js.map +1 -0
- package/dist/engine/skills-reconciler.d.ts +10 -1
- package/dist/engine/skills-reconciler.d.ts.map +1 -1
- package/dist/engine/skills-reconciler.js +128 -2
- package/dist/engine/skills-reconciler.js.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/audit-trail-store.d.ts +20 -0
- package/dist/storage/audit-trail-store.d.ts.map +1 -0
- package/dist/storage/audit-trail-store.js +98 -0
- package/dist/storage/audit-trail-store.js.map +1 -0
- package/dist/storage/auto-promoter-config-store.d.ts +11 -0
- package/dist/storage/auto-promoter-config-store.d.ts.map +1 -0
- package/dist/storage/auto-promoter-config-store.js +23 -0
- package/dist/storage/auto-promoter-config-store.js.map +1 -0
- package/dist/storage/budget-store.d.ts +19 -0
- package/dist/storage/budget-store.d.ts.map +1 -0
- package/dist/storage/budget-store.js +64 -0
- package/dist/storage/budget-store.js.map +1 -0
- package/dist/storage/gateway-store.d.ts +23 -0
- package/dist/storage/gateway-store.d.ts.map +1 -0
- package/dist/storage/gateway-store.js +52 -0
- package/dist/storage/gateway-store.js.map +1 -0
- package/dist/storage/refactor-registry-store.d.ts +21 -0
- package/dist/storage/refactor-registry-store.d.ts.map +1 -0
- package/dist/storage/refactor-registry-store.js +77 -0
- package/dist/storage/refactor-registry-store.js.map +1 -0
- package/dist/tools/auto-promoter-handler.d.ts +13 -0
- package/dist/tools/auto-promoter-handler.d.ts.map +1 -0
- package/dist/tools/auto-promoter-handler.js +50 -0
- package/dist/tools/auto-promoter-handler.js.map +1 -0
- package/dist/tools/compliance-test-handler.d.ts +5 -0
- package/dist/tools/compliance-test-handler.d.ts.map +1 -0
- package/dist/tools/compliance-test-handler.js +66 -0
- package/dist/tools/compliance-test-handler.js.map +1 -0
- package/dist/tools/cost-guardrails-handler.d.ts +15 -0
- package/dist/tools/cost-guardrails-handler.d.ts.map +1 -0
- package/dist/tools/cost-guardrails-handler.js +72 -0
- package/dist/tools/cost-guardrails-handler.js.map +1 -0
- package/dist/tools/dogfood-status-handler.d.ts +3 -0
- package/dist/tools/dogfood-status-handler.d.ts.map +1 -0
- package/dist/tools/dogfood-status-handler.js +28 -0
- package/dist/tools/dogfood-status-handler.js.map +1 -0
- package/dist/tools/drift-watcher-handler.d.ts +7 -0
- package/dist/tools/drift-watcher-handler.d.ts.map +1 -0
- package/dist/tools/drift-watcher-handler.js +65 -0
- package/dist/tools/drift-watcher-handler.js.map +1 -0
- package/dist/tools/export-audit-trail-handler.d.ts +9 -0
- package/dist/tools/export-audit-trail-handler.d.ts.map +1 -0
- package/dist/tools/export-audit-trail-handler.js +103 -0
- package/dist/tools/export-audit-trail-handler.js.map +1 -0
- package/dist/tools/mcp-gateway-handler.d.ts +13 -0
- package/dist/tools/mcp-gateway-handler.d.ts.map +1 -0
- package/dist/tools/mcp-gateway-handler.js +60 -0
- package/dist/tools/mcp-gateway-handler.js.map +1 -0
- package/dist/tools/multi-repo-handler.d.ts +15 -0
- package/dist/tools/multi-repo-handler.d.ts.map +1 -0
- package/dist/tools/multi-repo-handler.js +86 -0
- package/dist/tools/multi-repo-handler.js.map +1 -0
- package/dist/tools/reconcile-hooks.d.ts +5 -0
- package/dist/tools/reconcile-hooks.d.ts.map +1 -1
- package/dist/tools/reconcile-hooks.js +61 -4
- package/dist/tools/reconcile-hooks.js.map +1 -1
- package/dist/tools/reconcile-skills.d.ts +1 -0
- package/dist/tools/reconcile-skills.d.ts.map +1 -1
- package/dist/tools/reconcile-skills.js +57 -9
- package/dist/tools/reconcile-skills.js.map +1 -1
- package/dist/tools/register-audit-trail-tools.d.ts.map +1 -1
- package/dist/tools/register-audit-trail-tools.js +38 -0
- package/dist/tools/register-audit-trail-tools.js.map +1 -1
- package/dist/tools/register-auto-promoter-tools.d.ts +3 -0
- package/dist/tools/register-auto-promoter-tools.d.ts.map +1 -0
- package/dist/tools/register-auto-promoter-tools.js +43 -0
- package/dist/tools/register-auto-promoter-tools.js.map +1 -0
- package/dist/tools/register-compliance-test-tools.d.ts +3 -0
- package/dist/tools/register-compliance-test-tools.d.ts.map +1 -0
- package/dist/tools/register-compliance-test-tools.js +55 -0
- package/dist/tools/register-compliance-test-tools.js.map +1 -0
- package/dist/tools/register-cost-guardrails-tools.d.ts +3 -0
- package/dist/tools/register-cost-guardrails-tools.d.ts.map +1 -0
- package/dist/tools/register-cost-guardrails-tools.js +61 -0
- package/dist/tools/register-cost-guardrails-tools.js.map +1 -0
- package/dist/tools/register-dogfood-tools.d.ts +3 -0
- package/dist/tools/register-dogfood-tools.d.ts.map +1 -0
- package/dist/tools/register-dogfood-tools.js +21 -0
- package/dist/tools/register-dogfood-tools.js.map +1 -0
- package/dist/tools/register-drift-watcher-tools.d.ts +3 -0
- package/dist/tools/register-drift-watcher-tools.d.ts.map +1 -0
- package/dist/tools/register-drift-watcher-tools.js +28 -0
- package/dist/tools/register-drift-watcher-tools.js.map +1 -0
- package/dist/tools/register-mcp-gateway-tools.d.ts +3 -0
- package/dist/tools/register-mcp-gateway-tools.d.ts.map +1 -0
- package/dist/tools/register-mcp-gateway-tools.js +35 -0
- package/dist/tools/register-mcp-gateway-tools.js.map +1 -0
- package/dist/tools/register-multi-repo-tools.d.ts +8 -0
- package/dist/tools/register-multi-repo-tools.d.ts.map +1 -0
- package/dist/tools/register-multi-repo-tools.js +52 -0
- package/dist/tools/register-multi-repo-tools.js.map +1 -0
- package/dist/tools/safe-handler.d.ts.map +1 -1
- package/dist/tools/safe-handler.js +50 -1
- package/dist/tools/safe-handler.js.map +1 -1
- package/dist/tools/schemas/reconcile-skills-schemas.d.ts +1 -0
- package/dist/tools/schemas/reconcile-skills-schemas.d.ts.map +1 -1
- package/dist/tools/schemas/reconcile-skills-schemas.js +5 -0
- package/dist/tools/schemas/reconcile-skills-schemas.js.map +1 -1
- package/dist/types/audit.d.ts +64 -0
- package/dist/types/audit.d.ts.map +1 -0
- package/dist/types/audit.js +3 -0
- package/dist/types/audit.js.map +1 -0
- package/dist/types/auto-promoter.d.ts +26 -0
- package/dist/types/auto-promoter.d.ts.map +1 -0
- package/dist/types/auto-promoter.js +3 -0
- package/dist/types/auto-promoter.js.map +1 -0
- package/dist/types/compliance-tests.d.ts +41 -0
- package/dist/types/compliance-tests.d.ts.map +1 -0
- package/dist/types/compliance-tests.js +3 -0
- package/dist/types/compliance-tests.js.map +1 -0
- package/dist/types/conventions.d.ts +29 -0
- package/dist/types/conventions.d.ts.map +1 -1
- package/dist/types/cost-guardrails.d.ts +41 -0
- package/dist/types/cost-guardrails.d.ts.map +1 -0
- package/dist/types/cost-guardrails.js +3 -0
- package/dist/types/cost-guardrails.js.map +1 -0
- package/dist/types/dogfood.d.ts +22 -0
- package/dist/types/dogfood.d.ts.map +1 -0
- package/dist/types/dogfood.js +3 -0
- package/dist/types/dogfood.js.map +1 -0
- package/dist/types/drift-watcher.d.ts +35 -0
- package/dist/types/drift-watcher.d.ts.map +1 -0
- package/dist/types/drift-watcher.js +3 -0
- package/dist/types/drift-watcher.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/mcp-gateway.d.ts +34 -0
- package/dist/types/mcp-gateway.d.ts.map +1 -0
- package/dist/types/mcp-gateway.js +3 -0
- package/dist/types/mcp-gateway.js.map +1 -0
- package/dist/types/multi-repo.d.ts +39 -0
- package/dist/types/multi-repo.d.ts.map +1 -0
- package/dist/types/multi-repo.js +5 -0
- package/dist/types/multi-repo.js.map +1 -0
- package/package.json +1 -1
- package/src/config/license-plans.json +15 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// tools/compliance-test-handler.ts — SPEC-390: Compliance Test Suite Generator handlers
|
|
2
|
+
import { generateComplianceTests } from '../engine/compliance-test-generator/index.js';
|
|
3
|
+
import { getControlsForFrameworks } from '../engine/compliance-test-generator/control-mapper.js';
|
|
4
|
+
import { specStore } from '../storage/index.js';
|
|
5
|
+
import { hashProjectPath } from '../storage/base-store.js';
|
|
6
|
+
export async function handleGenerateComplianceTests(input) {
|
|
7
|
+
const projectId = hashProjectPath(input.projectPath);
|
|
8
|
+
const spec = await specStore.getSpec(projectId, input.specId);
|
|
9
|
+
if (!spec) {
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: 'text',
|
|
14
|
+
text: `Spec "${input.specId}" not found in project at "${input.projectPath}". ` +
|
|
15
|
+
`Run list_specs to see available specs.`,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const outputFormat = input.outputFormat ?? 'jest';
|
|
21
|
+
const result = await generateComplianceTests(spec.specPath, input.specId, input.frameworks, outputFormat);
|
|
22
|
+
const fileLines = result.generatedFiles.map((f) => ` ${f.path} (${f.content.split('\n').length} lines)`);
|
|
23
|
+
const coveredCount = result.coverageReport.filter((r) => r.covered).length;
|
|
24
|
+
const totalCount = result.coverageReport.length;
|
|
25
|
+
const lines = [
|
|
26
|
+
result.message,
|
|
27
|
+
``,
|
|
28
|
+
`Mapped tests: ${result.mappedTests.length}`,
|
|
29
|
+
`Control coverage: ${coveredCount}/${totalCount}`,
|
|
30
|
+
``,
|
|
31
|
+
`Generated files:`,
|
|
32
|
+
...fileLines,
|
|
33
|
+
];
|
|
34
|
+
if (result.mappedTests.length > 0) {
|
|
35
|
+
lines.push(``, `Preview (first test):`, ``, result.mappedTests[0]?.testCode ?? '');
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function handleComplianceCoverageReport(input) {
|
|
42
|
+
const controls = getControlsForFrameworks(input.frameworks);
|
|
43
|
+
if (controls.length === 0) {
|
|
44
|
+
return {
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: 'text',
|
|
48
|
+
text: `No built-in controls found for frameworks: ${input.frameworks.join(', ')}. ` +
|
|
49
|
+
`Supported: soc2, pci-dss, iso-42001.`,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const controlLines = controls.map((c) => `• [${c.id}] ${c.title}\n ${c.description}\n Keywords: ${c.keywords.join(', ')}`);
|
|
55
|
+
const lines = [
|
|
56
|
+
`Compliance controls for ${input.frameworks.join(', ')} (${controls.length} total):`,
|
|
57
|
+
``,
|
|
58
|
+
...controlLines,
|
|
59
|
+
``,
|
|
60
|
+
`Run generate_compliance_tests with a specId to map spec criteria to these controls.`,
|
|
61
|
+
];
|
|
62
|
+
return {
|
|
63
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=compliance-test-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compliance-test-handler.js","sourceRoot":"","sources":["../../src/tools/compliance-test-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ToolResult } from '../types/common/primitives.js';
|
|
2
|
+
import type { SetSpecBudgetInput, BudgetStatusInput, RecordSpendInput } from '../types/cost-guardrails.js';
|
|
3
|
+
/**
|
|
4
|
+
* Set or update the budget for a spec.
|
|
5
|
+
*/
|
|
6
|
+
export declare function handleSetSpecBudget(input: SetSpecBudgetInput): Promise<ToolResult>;
|
|
7
|
+
/**
|
|
8
|
+
* Return the budget status for one spec or all specs in a project.
|
|
9
|
+
*/
|
|
10
|
+
export declare function handleBudgetStatus(input: BudgetStatusInput): Promise<ToolResult>;
|
|
11
|
+
/**
|
|
12
|
+
* Record spend for a spec and return updated status with warnings if triggered.
|
|
13
|
+
*/
|
|
14
|
+
export declare function handleRecordSpend(input: RecordSpendInput): Promise<ToolResult>;
|
|
15
|
+
//# sourceMappingURL=cost-guardrails-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-guardrails-handler.d.ts","sourceRoot":"","sources":["../../src/tools/cost-guardrails-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAEjB,MAAM,6BAA6B,CAAC;AAMrC;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,CAoBxF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAmBtF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CA6BpF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// tools/cost-guardrails-handler.ts — Cost Guardrails tool handlers (SPEC-393)
|
|
2
|
+
import { computeBudgetStatus, formatBudgetMessage } from '../engine/cost-guardrails.js';
|
|
3
|
+
import { getBudget, saveBudget, listBudgets, recordSpend } from '../storage/budget-store.js';
|
|
4
|
+
const DEFAULT_WARNING_THRESHOLD = 80;
|
|
5
|
+
/**
|
|
6
|
+
* Set or update the budget for a spec.
|
|
7
|
+
*/
|
|
8
|
+
export async function handleSetSpecBudget(input) {
|
|
9
|
+
const { projectPath, specId, maxUsdCents, warningThreshold = DEFAULT_WARNING_THRESHOLD } = input;
|
|
10
|
+
const existing = await getBudget(projectPath, specId);
|
|
11
|
+
const budget = {
|
|
12
|
+
specId,
|
|
13
|
+
projectPath,
|
|
14
|
+
maxUsdCents,
|
|
15
|
+
usedUsdCents: existing?.usedUsdCents ?? 0,
|
|
16
|
+
warningThreshold,
|
|
17
|
+
lastUpdated: new Date().toISOString(),
|
|
18
|
+
};
|
|
19
|
+
await saveBudget(projectPath, budget);
|
|
20
|
+
const dollars = (maxUsdCents / 100).toFixed(2);
|
|
21
|
+
const text = `Budget set for ${specId}: $${dollars} (warning at ${warningThreshold}%).`;
|
|
22
|
+
return { content: [{ type: 'text', text }] };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Return the budget status for one spec or all specs in a project.
|
|
26
|
+
*/
|
|
27
|
+
export async function handleBudgetStatus(input) {
|
|
28
|
+
const { projectPath, specId } = input;
|
|
29
|
+
if (specId !== undefined) {
|
|
30
|
+
const budget = await getBudget(projectPath, specId);
|
|
31
|
+
if (budget === null) {
|
|
32
|
+
return { content: [{ type: 'text', text: `No budget found for ${specId}.` }] };
|
|
33
|
+
}
|
|
34
|
+
const status = computeBudgetStatus(budget);
|
|
35
|
+
return { content: [{ type: 'text', text: formatBudgetMessage(status) }] };
|
|
36
|
+
}
|
|
37
|
+
const budgets = await listBudgets(projectPath);
|
|
38
|
+
if (budgets.length === 0) {
|
|
39
|
+
return { content: [{ type: 'text', text: 'No budgets configured for this project.' }] };
|
|
40
|
+
}
|
|
41
|
+
const lines = budgets.map((b) => formatBudgetMessage(computeBudgetStatus(b)));
|
|
42
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Record spend for a spec and return updated status with warnings if triggered.
|
|
46
|
+
*/
|
|
47
|
+
export async function handleRecordSpend(input) {
|
|
48
|
+
const { projectPath, specId, usdCents, modelUsed, toolName } = input;
|
|
49
|
+
await recordSpend(projectPath, specId, usdCents);
|
|
50
|
+
const budget = await getBudget(projectPath, specId);
|
|
51
|
+
if (budget === null) {
|
|
52
|
+
const dollars = (usdCents / 100).toFixed(4);
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: `Recorded $${dollars} via ${toolName} (${modelUsed}). No budget configured for ${specId}.`,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const status = computeBudgetStatus(budget);
|
|
63
|
+
const statusMsg = formatBudgetMessage(status);
|
|
64
|
+
const dollars = (usdCents / 100).toFixed(4);
|
|
65
|
+
const lines = [
|
|
66
|
+
`Recorded $${dollars} via ${toolName} (${modelUsed}).`,
|
|
67
|
+
statusMsg,
|
|
68
|
+
`Recommended model: ${status.recommendedModel}`,
|
|
69
|
+
];
|
|
70
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=cost-guardrails-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-guardrails-handler.js","sourceRoot":"","sources":["../../src/tools/cost-guardrails-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dogfood-status-handler.d.ts","sourceRoot":"","sources":["../../src/tools/dogfood-status-handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAOxE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,UAAU,CA2BzE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getRecentCommitMessages, detectToolUsageFromMessages, buildDogfoodReport, } from '../engine/dogfood-analyzer.js';
|
|
2
|
+
export function handleDogfoodStatus(input) {
|
|
3
|
+
const sinceDays = input.since
|
|
4
|
+
? Math.ceil((Date.now() - new Date(input.since).getTime()) / 86400000)
|
|
5
|
+
: 30;
|
|
6
|
+
const period = `Last ${String(sinceDays)} days`;
|
|
7
|
+
const messages = getRecentCommitMessages(input.projectPath, sinceDays);
|
|
8
|
+
const usedTools = detectToolUsageFromMessages(messages);
|
|
9
|
+
const report = buildDogfoodReport(usedTools, period, messages);
|
|
10
|
+
const lines = [
|
|
11
|
+
`## Planu Dogfood Status — ${report.period}`,
|
|
12
|
+
`**Score**: ${String(report.dogfoodScore)}/100`,
|
|
13
|
+
`**Tools used**: ${report.usedTools.join(', ') || 'none'}`,
|
|
14
|
+
`**Missing**: ${report.missingTools.join(', ') || 'none'}`,
|
|
15
|
+
'',
|
|
16
|
+
`### Metrics`,
|
|
17
|
+
`- Specs created: ${String(report.metrics.specCreated)}`,
|
|
18
|
+
`- Specs validated: ${String(report.metrics.specValidated)}`,
|
|
19
|
+
`- Specs challenged: ${String(report.metrics.specChallenged)}`,
|
|
20
|
+
`- Readiness checked: ${String(report.metrics.readinessChecked)}`,
|
|
21
|
+
`- Status updates: ${String(report.metrics.statusUpdated)}`,
|
|
22
|
+
'',
|
|
23
|
+
`### Recommendation`,
|
|
24
|
+
report.recommendation,
|
|
25
|
+
];
|
|
26
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=dogfood-status-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dogfood-status-handler.js","sourceRoot":"","sources":["../../src/tools/dogfood-status-handler.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,UAAU,mBAAmB,CAAC,KAAyB;IAC3D,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK;QAC3B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,CAAC;QACtE,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,MAAM,GAAG,QAAQ,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC;IAChD,MAAM,QAAQ,GAAG,uBAAuB,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAE/D,MAAM,KAAK,GAAG;QACZ,6BAA6B,MAAM,CAAC,MAAM,EAAE;QAC5C,cAAc,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM;QAC/C,mBAAmB,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE;QAC1D,gBAAgB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE;QAC1D,EAAE;QACF,aAAa;QACb,oBAAoB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;QACxD,sBAAsB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;QAC5D,uBAAuB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE;QAC9D,wBAAwB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;QACjE,qBAAqB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;QAC3D,EAAE;QACF,oBAAoB;QACpB,MAAM,CAAC,cAAc;KACtB,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ToolResult, WatchSpecDriftInput } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Handle the watch_spec_drift tool invocation.
|
|
4
|
+
* Routes to start/stop/status based on the action field.
|
|
5
|
+
*/
|
|
6
|
+
export declare function handleWatchSpecDrift(input: WatchSpecDriftInput): Promise<ToolResult>;
|
|
7
|
+
//# sourceMappingURL=drift-watcher-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drift-watcher-handler.d.ts","sourceRoot":"","sources":["../../src/tools/drift-watcher-handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAKzE;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CA+D1F"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { hashProjectPath } from '../storage/base-store.js';
|
|
2
|
+
import { listSpecs } from '../storage/spec-store.js';
|
|
3
|
+
import { startWatcher, stopWatcher, getWatcherState } from '../engine/drift-watcher/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Handle the watch_spec_drift tool invocation.
|
|
6
|
+
* Routes to start/stop/status based on the action field.
|
|
7
|
+
*/
|
|
8
|
+
export async function handleWatchSpecDrift(input) {
|
|
9
|
+
const { projectPath, specId, action } = input;
|
|
10
|
+
if (action === 'status') {
|
|
11
|
+
const state = getWatcherState(specId);
|
|
12
|
+
if (!state) {
|
|
13
|
+
return {
|
|
14
|
+
content: [{ type: 'text', text: `No active watcher for spec ${specId}.` }],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
type: 'text',
|
|
21
|
+
text: JSON.stringify(state, null, 2),
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (action === 'stop') {
|
|
27
|
+
const stopped = stopWatcher(specId);
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{
|
|
31
|
+
type: 'text',
|
|
32
|
+
text: stopped
|
|
33
|
+
? `Watcher stopped for spec ${specId}.`
|
|
34
|
+
: `No active watcher found for spec ${specId}.`,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// action === 'start'
|
|
40
|
+
const projectId = hashProjectPath(projectPath);
|
|
41
|
+
const specs = await listSpecs(projectId);
|
|
42
|
+
const spec = specs.find((s) => s.id === specId);
|
|
43
|
+
if (!spec) {
|
|
44
|
+
return {
|
|
45
|
+
content: [{ type: 'text', text: `Spec ${specId} not found in project ${projectPath}.` }],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const specPath = spec.specPath;
|
|
49
|
+
const watchedPaths = [projectPath];
|
|
50
|
+
const state = startWatcher({
|
|
51
|
+
specId,
|
|
52
|
+
projectPath,
|
|
53
|
+
specPath,
|
|
54
|
+
watchedPaths,
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
content: [
|
|
58
|
+
{
|
|
59
|
+
type: 'text',
|
|
60
|
+
text: JSON.stringify(state, null, 2),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=drift-watcher-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drift-watcher-handler.js","sourceRoot":"","sources":["../../src/tools/drift-watcher-handler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAE9F;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAA0B;IACnE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAE9C,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,8BAA8B,MAAM,GAAG,EAAE,CAAC;aAC3E,CAAC;QACJ,CAAC;QACD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;iBACrC;aACF;SACF,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,OAAO;wBACX,CAAC,CAAC,4BAA4B,MAAM,GAAG;wBACvC,CAAC,CAAC,oCAAoC,MAAM,GAAG;iBAClD;aACF;SACF,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,MAAM,SAAS,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IAEhD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,MAAM,yBAAyB,WAAW,GAAG,EAAE,CAAC;SACzF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,MAAM,YAAY,GAAG,CAAC,WAAW,CAAC,CAAC;IAEnC,MAAM,KAAK,GAAG,YAAY,CAAC;QACzB,MAAM;QACN,WAAW;QACX,QAAQ;QACR,YAAY;KACb,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;aACrC;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolResult } from '../types/index.js';
|
|
2
|
+
import type { AuditTrailExportInput } from '../types/audit.js';
|
|
3
|
+
/**
|
|
4
|
+
* Handle export_audit_trail tool invocation.
|
|
5
|
+
* Reads the global audit trail, applies filters, verifies chain integrity,
|
|
6
|
+
* and returns formatted output in the requested format.
|
|
7
|
+
*/
|
|
8
|
+
export declare function handleExportAuditTrail(input: AuditTrailExportInput): ToolResult;
|
|
9
|
+
//# sourceMappingURL=export-audit-trail-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-audit-trail-handler.d.ts","sourceRoot":"","sources":["../../src/tools/export-audit-trail-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAEV,qBAAqB,EAEtB,MAAM,mBAAmB,CAAC;AA4E3B;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,UAAU,CAuC/E"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// tools/export-audit-trail-handler.ts — Handler for export_audit_trail tool (SPEC-387)
|
|
2
|
+
import { readEntries } from '../storage/audit-trail-store.js';
|
|
3
|
+
import { verifyChain } from '../engine/audit-trail/hasher.js';
|
|
4
|
+
import { formatSuccess, toolResult } from './response-helpers.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Formatters
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
function formatJson(entries) {
|
|
9
|
+
return JSON.stringify(entries, null, 2);
|
|
10
|
+
}
|
|
11
|
+
function formatJsonLd(entries) {
|
|
12
|
+
const graph = entries.map((e) => ({
|
|
13
|
+
'@type': 'prov:Activity',
|
|
14
|
+
'@id': `urn:planu:audit:${e.id}`,
|
|
15
|
+
'prov:startedAtTime': e.timestamp,
|
|
16
|
+
'prov:endedAtTime': e.timestamp,
|
|
17
|
+
'planu:toolName': e.toolName,
|
|
18
|
+
'planu:inputSummary': e.inputSummary,
|
|
19
|
+
'planu:outputType': e.outputType,
|
|
20
|
+
'planu:durationMs': e.durationMs,
|
|
21
|
+
'planu:hash': e.hash,
|
|
22
|
+
'planu:prevHash': e.prevHash,
|
|
23
|
+
...(e.specId !== undefined ? { 'planu:specId': e.specId } : {}),
|
|
24
|
+
...(e.projectPath !== undefined ? { 'planu:projectPath': e.projectPath } : {}),
|
|
25
|
+
}));
|
|
26
|
+
const doc = {
|
|
27
|
+
'@context': {
|
|
28
|
+
prov: 'http://www.w3.org/ns/prov#',
|
|
29
|
+
planu: 'https://planu.dev/vocab#',
|
|
30
|
+
},
|
|
31
|
+
'@graph': graph,
|
|
32
|
+
};
|
|
33
|
+
return JSON.stringify(doc, null, 2);
|
|
34
|
+
}
|
|
35
|
+
function formatCsv(entries) {
|
|
36
|
+
const header = 'id,timestamp,toolName,outputType,durationMs,specId,projectPath,hash,prevHash,inputSummary';
|
|
37
|
+
const rows = entries.map((e) => {
|
|
38
|
+
const cols = [
|
|
39
|
+
e.id,
|
|
40
|
+
e.timestamp,
|
|
41
|
+
e.toolName,
|
|
42
|
+
e.outputType,
|
|
43
|
+
String(e.durationMs),
|
|
44
|
+
e.specId ?? '',
|
|
45
|
+
e.projectPath ?? '',
|
|
46
|
+
e.hash,
|
|
47
|
+
e.prevHash,
|
|
48
|
+
`"${e.inputSummary.replace(/"/g, '""')}"`,
|
|
49
|
+
];
|
|
50
|
+
return cols.join(',');
|
|
51
|
+
});
|
|
52
|
+
return [header, ...rows].join('\n');
|
|
53
|
+
}
|
|
54
|
+
function renderFormat(format, entries) {
|
|
55
|
+
switch (format) {
|
|
56
|
+
case 'json':
|
|
57
|
+
return formatJson(entries);
|
|
58
|
+
case 'json-ld':
|
|
59
|
+
return formatJsonLd(entries);
|
|
60
|
+
case 'csv':
|
|
61
|
+
return formatCsv(entries);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Handler
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* Handle export_audit_trail tool invocation.
|
|
69
|
+
* Reads the global audit trail, applies filters, verifies chain integrity,
|
|
70
|
+
* and returns formatted output in the requested format.
|
|
71
|
+
*/
|
|
72
|
+
export function handleExportAuditTrail(input) {
|
|
73
|
+
const format = input.format ?? 'json';
|
|
74
|
+
const allEntries = readEntries({
|
|
75
|
+
fromDate: input.fromDate,
|
|
76
|
+
toDate: input.toDate,
|
|
77
|
+
specId: input.specId,
|
|
78
|
+
projectPath: input.projectPath,
|
|
79
|
+
limit: input.limit,
|
|
80
|
+
});
|
|
81
|
+
// Verify chain on the full unfiltered set for accurate integrity reporting
|
|
82
|
+
const fullEntries = readEntries();
|
|
83
|
+
const integrityValid = verifyChain(fullEntries);
|
|
84
|
+
const formatted = renderFormat(format, allEntries);
|
|
85
|
+
const exportedAt = new Date().toISOString();
|
|
86
|
+
const result = {
|
|
87
|
+
entries: allEntries,
|
|
88
|
+
totalCount: allEntries.length,
|
|
89
|
+
format,
|
|
90
|
+
exportedAt,
|
|
91
|
+
integrityValid,
|
|
92
|
+
};
|
|
93
|
+
const summary = [
|
|
94
|
+
`Audit Trail Export — SPEC-387 (EU AI Act Article 12)`,
|
|
95
|
+
`Entries: ${String(allEntries.length)} | Format: ${format}`,
|
|
96
|
+
`Chain integrity: ${integrityValid ? 'VALID' : 'BROKEN'}`,
|
|
97
|
+
`Exported at: ${exportedAt}`,
|
|
98
|
+
'',
|
|
99
|
+
formatted,
|
|
100
|
+
].join('\n');
|
|
101
|
+
return toolResult(formatSuccess('Audit Trail Export', summary), result);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=export-audit-trail-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-audit-trail-handler.js","sourceRoot":"","sources":["../../src/tools/export-audit-trail-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ToolResult } from '../types/index.js';
|
|
2
|
+
import type { DiscoverMcpGatewaysInput, FederationDiscoveryStatusInput } from '../types/mcp-gateway.js';
|
|
3
|
+
/**
|
|
4
|
+
* Handle discover_mcp_gateways tool call.
|
|
5
|
+
* Runs a discovery pass and returns a summary of found gateways.
|
|
6
|
+
*/
|
|
7
|
+
export declare function handleDiscoverMcpGateways(input: DiscoverMcpGatewaysInput): Promise<ToolResult>;
|
|
8
|
+
/**
|
|
9
|
+
* Handle federation_discovery_status tool call.
|
|
10
|
+
* Returns all known gateways from the registry with their current status.
|
|
11
|
+
*/
|
|
12
|
+
export declare function handleFederationDiscoveryStatus(input: FederationDiscoveryStatusInput): Promise<ToolResult>;
|
|
13
|
+
//# sourceMappingURL=mcp-gateway-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-gateway-handler.d.ts","sourceRoot":"","sources":["../../src/tools/mcp-gateway-handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EACV,wBAAwB,EACxB,8BAA8B,EAC/B,MAAM,yBAAyB,CAAC;AAGjC;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,UAAU,CAAC,CA0BrB;AAED;;;GAGG;AACH,wBAAsB,+BAA+B,CACnD,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,UAAU,CAAC,CAiCrB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { discoverGateways, getGatewayStatus } from '../engine/mcp-gateway/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Handle discover_mcp_gateways tool call.
|
|
4
|
+
* Runs a discovery pass and returns a summary of found gateways.
|
|
5
|
+
*/
|
|
6
|
+
export async function handleDiscoverMcpGateways(input) {
|
|
7
|
+
const { urls = [], includeLocalhost = true } = input;
|
|
8
|
+
const found = await discoverGateways(urls, includeLocalhost);
|
|
9
|
+
if (found.length === 0) {
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: 'text',
|
|
14
|
+
text: 'No MCP gateways discovered. Make sure target servers expose /.well-known/mcp.',
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const lines = [`Discovered ${found.length} MCP gateway(s):`, ''];
|
|
20
|
+
for (const gw of found) {
|
|
21
|
+
const compat = gw.planuCompatible ? ' [Planu-compatible]' : '';
|
|
22
|
+
lines.push(` ${gw.name} (${gw.url})${compat}`);
|
|
23
|
+
if (gw.tools.length > 0) {
|
|
24
|
+
lines.push(` Tools: ${gw.tools.join(', ')}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Handle federation_discovery_status tool call.
|
|
31
|
+
* Returns all known gateways from the registry with their current status.
|
|
32
|
+
*/
|
|
33
|
+
export async function handleFederationDiscoveryStatus(input) {
|
|
34
|
+
// projectPath is required by the tool schema but the registry is global
|
|
35
|
+
void input.projectPath;
|
|
36
|
+
const { registry, active } = await getGatewayStatus();
|
|
37
|
+
const all = registry.gateways;
|
|
38
|
+
if (all.length === 0) {
|
|
39
|
+
return {
|
|
40
|
+
content: [
|
|
41
|
+
{
|
|
42
|
+
type: 'text',
|
|
43
|
+
text: 'No gateways in registry. Run discover_mcp_gateways to start discovery.',
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const lines = [`Gateway registry: ${all.length} known, ${active.length} active`];
|
|
49
|
+
if (registry.lastDiscoveryAt) {
|
|
50
|
+
lines.push(`Last discovery: ${registry.lastDiscoveryAt}`);
|
|
51
|
+
}
|
|
52
|
+
lines.push('');
|
|
53
|
+
for (const gw of all) {
|
|
54
|
+
const compat = gw.planuCompatible ? ' [Planu]' : '';
|
|
55
|
+
lines.push(` [${gw.status}] ${gw.name} (${gw.url})${compat}`);
|
|
56
|
+
lines.push(` Last seen: ${gw.lastSeenAt}`);
|
|
57
|
+
}
|
|
58
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=mcp-gateway-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-gateway-handler.js","sourceRoot":"","sources":["../../src/tools/mcp-gateway-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ToolResult } from '../types/index.js';
|
|
2
|
+
import type { CoordinateRefactorInput, SyncRefactorStatusInput } from '../types/multi-repo.js';
|
|
3
|
+
/**
|
|
4
|
+
* Initiate a multi-repo refactor session.
|
|
5
|
+
* 1. Loads the source spec to verify it exists.
|
|
6
|
+
* 2. Discovers all registered projects (excluding source).
|
|
7
|
+
* 3. Scans each project for symbol usage.
|
|
8
|
+
* 4. Persists a RefactorSession and returns summary.
|
|
9
|
+
*/
|
|
10
|
+
export declare function handleCoordinateRefactor(input: CoordinateRefactorInput): Promise<ToolResult>;
|
|
11
|
+
/**
|
|
12
|
+
* Returns the current progress report for a refactor session.
|
|
13
|
+
*/
|
|
14
|
+
export declare function handleSyncRefactorStatus(input: SyncRefactorStatusInput): Promise<ToolResult>;
|
|
15
|
+
//# sourceMappingURL=multi-repo-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-repo-handler.d.ts","sourceRoot":"","sources":["../../src/tools/multi-repo-handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EAGxB,MAAM,wBAAwB,CAAC;AAehC;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAoDrB;AAMD;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAqBrB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// tools/multi-repo-handler.ts — SPEC-389: Handlers for multi-repo refactoring coordination
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { hashProjectPath } from '../storage/base-store.js';
|
|
4
|
+
import { getSpec } from '../storage/spec-store.js';
|
|
5
|
+
import { createSession, getSession } from '../storage/refactor-registry-store.js';
|
|
6
|
+
import { scanProjectForSymbols, getRegisteredProjectPaths, buildStatusReport, } from '../engine/multi-repo/index.js';
|
|
7
|
+
import { textResult, errText } from './response-helpers.js';
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// coordinate_refactor
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/**
|
|
12
|
+
* Initiate a multi-repo refactor session.
|
|
13
|
+
* 1. Loads the source spec to verify it exists.
|
|
14
|
+
* 2. Discovers all registered projects (excluding source).
|
|
15
|
+
* 3. Scans each project for symbol usage.
|
|
16
|
+
* 4. Persists a RefactorSession and returns summary.
|
|
17
|
+
*/
|
|
18
|
+
export async function handleCoordinateRefactor(input) {
|
|
19
|
+
const { projectPath, specId, affectedSymbols } = input;
|
|
20
|
+
if (affectedSymbols.length === 0) {
|
|
21
|
+
return errText('affectedSymbols must contain at least one symbol name.');
|
|
22
|
+
}
|
|
23
|
+
const projectId = hashProjectPath(projectPath);
|
|
24
|
+
const spec = await getSpec(projectId, specId);
|
|
25
|
+
if (!spec) {
|
|
26
|
+
return errText(`Spec "${specId}" not found in project "${projectPath}".`);
|
|
27
|
+
}
|
|
28
|
+
const consumerPaths = await getRegisteredProjectPaths(projectPath);
|
|
29
|
+
const consumerProjects = [];
|
|
30
|
+
for (const consumerPath of consumerPaths) {
|
|
31
|
+
const usageLocations = await scanProjectForSymbols(consumerPath, affectedSymbols);
|
|
32
|
+
if (usageLocations.length > 0) {
|
|
33
|
+
consumerProjects.push({
|
|
34
|
+
projectPath: consumerPath,
|
|
35
|
+
projectId: hashProjectPath(consumerPath),
|
|
36
|
+
usageLocations,
|
|
37
|
+
status: 'pending',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const session = {
|
|
42
|
+
id: randomUUID(),
|
|
43
|
+
sourceSpecId: specId,
|
|
44
|
+
sourceProjectPath: projectPath,
|
|
45
|
+
affectedSymbols,
|
|
46
|
+
consumerProjects,
|
|
47
|
+
startedAt: new Date().toISOString(),
|
|
48
|
+
status: 'scanning',
|
|
49
|
+
};
|
|
50
|
+
await createSession(session);
|
|
51
|
+
const lines = [
|
|
52
|
+
`Refactor session created: ${session.id}`,
|
|
53
|
+
`Source spec: ${specId}`,
|
|
54
|
+
`Affected symbols: ${affectedSymbols.join(', ')}`,
|
|
55
|
+
`Consumer projects with usages: ${consumerProjects.length}`,
|
|
56
|
+
];
|
|
57
|
+
for (const cp of consumerProjects) {
|
|
58
|
+
lines.push(` - ${cp.projectPath}: ${cp.usageLocations.length} file(s)`);
|
|
59
|
+
}
|
|
60
|
+
return textResult(lines.join('\n'));
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// sync_refactor_status
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
/**
|
|
66
|
+
* Returns the current progress report for a refactor session.
|
|
67
|
+
*/
|
|
68
|
+
export async function handleSyncRefactorStatus(input) {
|
|
69
|
+
const { refactorId } = input;
|
|
70
|
+
const session = await getSession(refactorId);
|
|
71
|
+
if (!session) {
|
|
72
|
+
return errText(`Refactor session "${refactorId}" not found.`);
|
|
73
|
+
}
|
|
74
|
+
const report = buildStatusReport(session);
|
|
75
|
+
const lines = [
|
|
76
|
+
`Refactor: ${report.refactorId}`,
|
|
77
|
+
`Source spec: ${report.sourceSpec}`,
|
|
78
|
+
`Total consumers: ${report.totalConsumers}`,
|
|
79
|
+
`Completed: ${report.completed}`,
|
|
80
|
+
`In progress: ${report.inProgress}`,
|
|
81
|
+
`Pending: ${report.pending}`,
|
|
82
|
+
`Overall progress: ${report.overallProgress}%`,
|
|
83
|
+
];
|
|
84
|
+
return textResult(lines.join('\n'));
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=multi-repo-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-repo-handler.js","sourceRoot":"","sources":["../../src/tools/multi-repo-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,11 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
2
2
|
import type { ToolResult } from '../types/index.js';
|
|
3
3
|
export declare function handleReconcileHooks(args: {
|
|
4
4
|
projectPath: string;
|
|
5
|
+
autoFix?: boolean;
|
|
6
|
+
}): ToolResult;
|
|
7
|
+
export declare function handleReconcileHooksAsync(args: {
|
|
8
|
+
projectPath: string;
|
|
9
|
+
autoFix?: boolean;
|
|
5
10
|
}): ToolResult;
|
|
6
11
|
export declare function registerReconcileHooksTool(server: McpServer): void;
|
|
7
12
|
//# sourceMappingURL=reconcile-hooks.d.ts.map
|