@ai-dossier/mcp-server 1.0.1 → 1.0.3
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/LICENSE +661 -0
- package/README.md +110 -297
- package/dist/index.js +272 -38
- package/dist/index.js.map +1 -1
- package/dist/orchestration/graph.d.ts +33 -0
- package/dist/orchestration/graph.d.ts.map +1 -0
- package/dist/orchestration/graph.js +240 -0
- package/dist/orchestration/graph.js.map +1 -0
- package/dist/orchestration/outputMapper.d.ts +94 -0
- package/dist/orchestration/outputMapper.d.ts.map +1 -0
- package/dist/orchestration/outputMapper.js +129 -0
- package/dist/orchestration/outputMapper.js.map +1 -0
- package/dist/orchestration/resolver.d.ts +40 -0
- package/dist/orchestration/resolver.d.ts.map +1 -0
- package/dist/orchestration/resolver.js +208 -0
- package/dist/orchestration/resolver.js.map +1 -0
- package/dist/orchestration/session.d.ts +43 -0
- package/dist/orchestration/session.d.ts.map +1 -0
- package/dist/orchestration/session.js +67 -0
- package/dist/orchestration/session.js.map +1 -0
- package/dist/orchestration/types.d.ts +76 -0
- package/dist/orchestration/types.d.ts.map +1 -0
- package/dist/orchestration/types.js +6 -0
- package/dist/orchestration/types.js.map +1 -0
- package/dist/resources/orchestration.d.ts +7 -0
- package/dist/resources/orchestration.d.ts.map +1 -0
- package/dist/resources/orchestration.js +11 -0
- package/dist/resources/orchestration.js.map +1 -0
- package/dist/tools/cancelJourney.d.ts +20 -0
- package/dist/tools/cancelJourney.d.ts.map +1 -0
- package/dist/tools/cancelJourney.js +50 -0
- package/dist/tools/cancelJourney.js.map +1 -0
- package/dist/tools/getJourneyStatus.d.ts +29 -0
- package/dist/tools/getJourneyStatus.d.ts.map +1 -0
- package/dist/tools/getJourneyStatus.js +39 -0
- package/dist/tools/getJourneyStatus.js.map +1 -0
- package/dist/tools/listDossiers.d.ts +13 -4
- package/dist/tools/listDossiers.d.ts.map +1 -1
- package/dist/tools/listDossiers.js +28 -89
- package/dist/tools/listDossiers.js.map +1 -1
- package/dist/tools/readDossier.d.ts +5 -15
- package/dist/tools/readDossier.d.ts.map +1 -1
- package/dist/tools/readDossier.js +53 -33
- package/dist/tools/readDossier.js.map +1 -1
- package/dist/tools/resolveGraph.d.ts +25 -0
- package/dist/tools/resolveGraph.d.ts.map +1 -0
- package/dist/tools/resolveGraph.js +67 -0
- package/dist/tools/resolveGraph.js.map +1 -0
- package/dist/tools/searchDossiers.d.ts +28 -0
- package/dist/tools/searchDossiers.d.ts.map +1 -0
- package/dist/tools/searchDossiers.js +38 -0
- package/dist/tools/searchDossiers.js.map +1 -0
- package/dist/tools/startJourney.d.ts +26 -0
- package/dist/tools/startJourney.d.ts.map +1 -0
- package/dist/tools/startJourney.js +90 -0
- package/dist/tools/startJourney.js.map +1 -0
- package/dist/tools/stepComplete.d.ts +28 -0
- package/dist/tools/stepComplete.d.ts.map +1 -0
- package/dist/tools/stepComplete.js +101 -0
- package/dist/tools/stepComplete.js.map +1 -0
- package/dist/tools/verifyDossier.d.ts +14 -6
- package/dist/tools/verifyDossier.d.ts.map +1 -1
- package/dist/tools/verifyDossier.js +16 -89
- package/dist/tools/verifyDossier.js.map +1 -1
- package/dist/tools/verifyGraph.d.ts +33 -0
- package/dist/tools/verifyGraph.d.ts.map +1 -0
- package/dist/tools/verifyGraph.js +175 -0
- package/dist/tools/verifyGraph.js.map +1 -0
- package/dist/utils/cli-wrapper.d.ts +25 -0
- package/dist/utils/cli-wrapper.d.ts.map +1 -0
- package/dist/utils/cli-wrapper.js +83 -0
- package/dist/utils/cli-wrapper.js.map +1 -0
- package/dist/utils/graphStore.d.ts +9 -0
- package/dist/utils/graphStore.d.ts.map +1 -0
- package/dist/utils/graphStore.js +21 -0
- package/dist/utils/graphStore.js.map +1 -0
- package/dist/utils/paths.d.ts +8 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +19 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/resourceLoader.d.ts.map +1 -1
- package/dist/utils/resourceLoader.js +2 -3
- package/dist/utils/resourceLoader.js.map +1 -1
- package/package.json +23 -9
- package/dist/parsers/signatureVerifier.d.ts +0 -10
- package/dist/parsers/signatureVerifier.d.ts.map +0 -1
- package/dist/parsers/signatureVerifier.js +0 -85
- package/dist/parsers/signatureVerifier.js.map +0 -1
- package/dist/utils/errors.d.ts +0 -35
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -68
- package/dist/utils/errors.js.map +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* step_complete tool - Advance a journey session to the next step.
|
|
3
|
+
* Maps outputs to next step's inputs and returns the next step's dossier content.
|
|
4
|
+
*/
|
|
5
|
+
import type { JourneySummary } from '../orchestration/session';
|
|
6
|
+
import type { StepPayload } from './startJourney';
|
|
7
|
+
export interface StepCompleteInput {
|
|
8
|
+
journey_id: string;
|
|
9
|
+
outputs?: Record<string, unknown>;
|
|
10
|
+
status: 'completed' | 'failed';
|
|
11
|
+
}
|
|
12
|
+
export interface StepCompleteRunning {
|
|
13
|
+
status: 'running';
|
|
14
|
+
step: StepPayload;
|
|
15
|
+
}
|
|
16
|
+
export interface StepCompleteDone {
|
|
17
|
+
status: 'completed' | 'failed';
|
|
18
|
+
summary: JourneySummary;
|
|
19
|
+
}
|
|
20
|
+
export interface StepCompleteError {
|
|
21
|
+
error: {
|
|
22
|
+
type: 'not_found' | 'invalid_state' | 'unknown';
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export type StepCompleteOutput = StepCompleteRunning | StepCompleteDone;
|
|
27
|
+
export declare function stepComplete(input: StepCompleteInput): Promise<StepCompleteOutput | StepCompleteError>;
|
|
28
|
+
//# sourceMappingURL=stepComplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepComplete.d.ts","sourceRoot":"","sources":["../../src/tools/stepComplete.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQ5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE;QACL,IAAI,EAAE,WAAW,GAAG,eAAe,GAAG,SAAS,CAAC;QAChD,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG,gBAAgB,CAAC;AAkBxE,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,kBAAkB,GAAG,iBAAiB,CAAC,CA2FjD"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* step_complete tool - Advance a journey session to the next step.
|
|
4
|
+
* Maps outputs to next step's inputs and returns the next step's dossier content.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.stepComplete = stepComplete;
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const core_1 = require("@ai-dossier/core");
|
|
10
|
+
const session_1 = require("../orchestration/session");
|
|
11
|
+
const logger_1 = require("../utils/logger");
|
|
12
|
+
function fetchDossierBody(step) {
|
|
13
|
+
if (step.source === 'local' && step.path) {
|
|
14
|
+
try {
|
|
15
|
+
const raw = (0, node_fs_1.readFileSync)(step.path, 'utf8');
|
|
16
|
+
try {
|
|
17
|
+
return (0, core_1.parseDossierContent)(raw).body;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return raw;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return '';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return '';
|
|
28
|
+
}
|
|
29
|
+
async function stepComplete(input) {
|
|
30
|
+
const { journey_id, outputs, status } = input;
|
|
31
|
+
if (!journey_id) {
|
|
32
|
+
return { error: { type: 'unknown', message: 'journey_id is required' } };
|
|
33
|
+
}
|
|
34
|
+
const session = (0, session_1.getSession)(journey_id);
|
|
35
|
+
if (!session) {
|
|
36
|
+
return { error: { type: 'not_found', message: `No journey found with id: ${journey_id}` } };
|
|
37
|
+
}
|
|
38
|
+
if (session.status === 'completed' ||
|
|
39
|
+
session.status === 'cancelled' ||
|
|
40
|
+
session.status === 'failed') {
|
|
41
|
+
return {
|
|
42
|
+
error: {
|
|
43
|
+
type: 'invalid_state',
|
|
44
|
+
message: `Journey is already ${session.status}`,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const currentStep = session.steps[session.currentStepIndex];
|
|
49
|
+
// Record outputs and mark current step
|
|
50
|
+
if (outputs) {
|
|
51
|
+
currentStep.collectedOutputs = outputs;
|
|
52
|
+
session.outputs[currentStep.dossier] = outputs;
|
|
53
|
+
}
|
|
54
|
+
currentStep.status = status;
|
|
55
|
+
if (status === 'failed') {
|
|
56
|
+
session.status = 'failed';
|
|
57
|
+
session.completedAt = new Date();
|
|
58
|
+
(0, session_1.updateSession)(session);
|
|
59
|
+
logger_1.logger.info('Journey failed at step', {
|
|
60
|
+
journeyId: journey_id,
|
|
61
|
+
stepIndex: session.currentStepIndex,
|
|
62
|
+
dossier: currentStep.dossier,
|
|
63
|
+
});
|
|
64
|
+
return { status: 'failed', summary: (0, session_1.buildSummary)(session) };
|
|
65
|
+
}
|
|
66
|
+
// Find next step (skip optional steps that are already marked skipped)
|
|
67
|
+
const nextIndex = session.currentStepIndex + 1;
|
|
68
|
+
if (nextIndex >= session.steps.length) {
|
|
69
|
+
session.status = 'completed';
|
|
70
|
+
session.completedAt = new Date();
|
|
71
|
+
(0, session_1.updateSession)(session);
|
|
72
|
+
logger_1.logger.info('Journey completed', {
|
|
73
|
+
journeyId: journey_id,
|
|
74
|
+
totalSteps: session.steps.length,
|
|
75
|
+
});
|
|
76
|
+
return { status: 'completed', summary: (0, session_1.buildSummary)(session) };
|
|
77
|
+
}
|
|
78
|
+
// Advance to next step
|
|
79
|
+
session.currentStepIndex = nextIndex;
|
|
80
|
+
const nextStep = session.steps[nextIndex];
|
|
81
|
+
nextStep.status = 'running';
|
|
82
|
+
const context = (0, session_1.buildOutputContext)(session.outputs);
|
|
83
|
+
nextStep.injectedContext = context;
|
|
84
|
+
(0, session_1.updateSession)(session);
|
|
85
|
+
const body = fetchDossierBody(nextStep);
|
|
86
|
+
logger_1.logger.info('Journey advanced to next step', {
|
|
87
|
+
journeyId: journey_id,
|
|
88
|
+
stepIndex: nextIndex,
|
|
89
|
+
dossier: nextStep.dossier,
|
|
90
|
+
});
|
|
91
|
+
return {
|
|
92
|
+
status: 'running',
|
|
93
|
+
step: {
|
|
94
|
+
index: nextIndex,
|
|
95
|
+
dossier: nextStep.dossier,
|
|
96
|
+
body,
|
|
97
|
+
context,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=stepComplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepComplete.js","sourceRoot":"","sources":["../../src/tools/stepComplete.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* verify_dossier tool - Security verification for dossiers
|
|
3
|
-
*
|
|
4
|
-
* Returns recommendation: ALLOW, WARN, or BLOCK
|
|
3
|
+
* Thin wrapper around `ai-dossier verify --json <path>`
|
|
5
4
|
*/
|
|
6
|
-
import { type VerificationResult } from '@ai-dossier/core';
|
|
7
5
|
export interface VerifyDossierInput {
|
|
8
6
|
path: string;
|
|
9
|
-
|
|
7
|
+
}
|
|
8
|
+
export interface VerificationStage {
|
|
9
|
+
stage: number;
|
|
10
|
+
name: string;
|
|
11
|
+
passed?: boolean;
|
|
12
|
+
skipped?: boolean;
|
|
13
|
+
demo?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface VerifyDossierOutput {
|
|
16
|
+
passed: boolean;
|
|
17
|
+
stages: VerificationStage[];
|
|
10
18
|
}
|
|
11
19
|
/**
|
|
12
|
-
* Verify dossier security
|
|
20
|
+
* Verify dossier security via CLI
|
|
13
21
|
*/
|
|
14
|
-
export declare function verifyDossier(input: VerifyDossierInput): Promise<
|
|
22
|
+
export declare function verifyDossier(input: VerifyDossierInput): Promise<VerifyDossierOutput>;
|
|
15
23
|
//# sourceMappingURL=verifyDossier.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyDossier.d.ts","sourceRoot":"","sources":["../../src/tools/verifyDossier.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"verifyDossier.d.ts","sourceRoot":"","sources":["../../src/tools/verifyDossier.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuB3F"}
|
|
@@ -1,107 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* verify_dossier tool - Security verification for dossiers
|
|
4
|
-
*
|
|
5
|
-
* Returns recommendation: ALLOW, WARN, or BLOCK
|
|
4
|
+
* Thin wrapper around `ai-dossier verify --json <path>`
|
|
6
5
|
*/
|
|
7
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
7
|
exports.verifyDossier = verifyDossier;
|
|
9
|
-
const
|
|
10
|
-
const signatureVerifier_1 = require("../parsers/signatureVerifier");
|
|
8
|
+
const cli_wrapper_1 = require("../utils/cli-wrapper");
|
|
11
9
|
const logger_1 = require("../utils/logger");
|
|
12
10
|
/**
|
|
13
|
-
* Verify dossier security
|
|
11
|
+
* Verify dossier security via CLI
|
|
14
12
|
*/
|
|
15
13
|
async function verifyDossier(input) {
|
|
16
|
-
const { path
|
|
17
|
-
logger_1.logger.info('Starting dossier verification', { dossierFile: path });
|
|
18
|
-
const result = (0, core_1.createDefaultVerificationResult)(path);
|
|
14
|
+
const { path } = input;
|
|
15
|
+
logger_1.logger.info('Starting dossier verification via CLI', { dossierFile: path });
|
|
19
16
|
try {
|
|
20
|
-
|
|
21
|
-
const parsed = (0, core_1.parseDossierFile)(path);
|
|
22
|
-
const { frontmatter, body } = parsed;
|
|
23
|
-
// 2. INTEGRITY CHECK (checksum)
|
|
24
|
-
const checksumHash = frontmatter.checksum?.hash;
|
|
25
|
-
result.integrity = (0, core_1.verifyIntegrity)(body, checksumHash);
|
|
26
|
-
if (result.integrity.status === 'missing') {
|
|
27
|
-
result.errors.push('Missing checksum - cannot verify integrity');
|
|
28
|
-
result.recommendation = 'BLOCK';
|
|
29
|
-
result.message = 'DO NOT EXECUTE - No checksum found';
|
|
30
|
-
logger_1.logger.error('Verification FAILED - missing checksum', { dossierFile: path });
|
|
31
|
-
return result;
|
|
32
|
-
}
|
|
33
|
-
if (result.integrity.status === 'invalid') {
|
|
34
|
-
result.errors.push('Checksum verification FAILED - do not execute!');
|
|
35
|
-
result.recommendation = 'BLOCK';
|
|
36
|
-
result.message = 'DO NOT EXECUTE - Dossier has been tampered with!';
|
|
37
|
-
result.authenticity.status = 'error';
|
|
38
|
-
result.authenticity.message = 'Cannot verify signature - integrity check failed';
|
|
39
|
-
logger_1.logger.error('Verification FAILED - checksum mismatch', { dossierFile: path });
|
|
40
|
-
return result;
|
|
41
|
-
}
|
|
42
|
-
// 3. AUTHENTICITY CHECK (signature)
|
|
43
|
-
result.authenticity = await (0, signatureVerifier_1.verifyAuthenticity)(body, frontmatter, trusted_keys_path);
|
|
44
|
-
if (result.authenticity.status === 'invalid') {
|
|
45
|
-
result.errors.push('Signature verification FAILED - do not execute!');
|
|
46
|
-
result.recommendation = 'BLOCK';
|
|
47
|
-
result.message = 'DO NOT EXECUTE - Invalid signature!';
|
|
48
|
-
logger_1.logger.error('Verification FAILED - invalid signature', { dossierFile: path });
|
|
49
|
-
return result;
|
|
50
|
-
}
|
|
51
|
-
// 4. RISK ASSESSMENT
|
|
52
|
-
result.riskAssessment = {
|
|
53
|
-
riskLevel: frontmatter.risk_level || 'unknown',
|
|
54
|
-
riskFactors: frontmatter.risk_factors || [],
|
|
55
|
-
destructiveOperations: frontmatter.destructive_operations || [],
|
|
56
|
-
requiresApproval: frontmatter.requires_approval !== false, // default true
|
|
57
|
-
};
|
|
58
|
-
// 5. RECOMMENDATION LOGIC
|
|
59
|
-
// Note: integrity 'invalid' and authenticity 'invalid' already handled above with early return
|
|
60
|
-
if (result.authenticity.status === 'verified' && result.riskAssessment.riskLevel === 'low') {
|
|
61
|
-
result.recommendation = 'ALLOW';
|
|
62
|
-
result.message = 'Verified dossier from trusted source with low risk. Safe to execute.';
|
|
63
|
-
}
|
|
64
|
-
else if (result.authenticity.status === 'unsigned' ||
|
|
65
|
-
result.authenticity.status === 'signed_unknown' ||
|
|
66
|
-
result.riskAssessment.riskLevel === 'high' ||
|
|
67
|
-
result.riskAssessment.riskLevel === 'critical') {
|
|
68
|
-
result.recommendation = 'WARN';
|
|
69
|
-
// Build warning message
|
|
70
|
-
const warnings = [];
|
|
71
|
-
if (result.authenticity.status === 'unsigned') {
|
|
72
|
-
warnings.push('Dossier is not signed (cannot verify author)');
|
|
73
|
-
}
|
|
74
|
-
if (result.authenticity.status === 'signed_unknown') {
|
|
75
|
-
warnings.push('Signature is valid but signer is not in your trusted keys list');
|
|
76
|
-
}
|
|
77
|
-
if (result.riskAssessment.riskLevel === 'high' ||
|
|
78
|
-
result.riskAssessment.riskLevel === 'critical') {
|
|
79
|
-
warnings.push(`High risk level: ${result.riskAssessment.riskLevel}`);
|
|
80
|
-
}
|
|
81
|
-
result.message = `WARNING: ${warnings.join('. ')}. Review before execution.`;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
result.recommendation = 'WARN';
|
|
85
|
-
result.message = 'Unsigned dossier with medium risk. Verify source before execution.';
|
|
86
|
-
}
|
|
17
|
+
const result = await (0, cli_wrapper_1.execCli)('verify', [path, '--json']);
|
|
87
18
|
logger_1.logger.info('Verification completed', {
|
|
88
19
|
dossierFile: path,
|
|
89
|
-
|
|
90
|
-
integrity: result.integrity.status,
|
|
91
|
-
authenticity: result.authenticity.status,
|
|
92
|
-
riskLevel: result.riskAssessment.riskLevel,
|
|
20
|
+
passed: result.passed,
|
|
93
21
|
});
|
|
22
|
+
return result;
|
|
94
23
|
}
|
|
95
|
-
catch (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
});
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (error instanceof cli_wrapper_1.CliNotFoundError) {
|
|
26
|
+
return {
|
|
27
|
+
passed: false,
|
|
28
|
+
stages: [{ stage: 0, name: 'CLI Check', passed: false }],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
104
32
|
}
|
|
105
|
-
return result;
|
|
106
33
|
}
|
|
107
34
|
//# sourceMappingURL=verifyDossier.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifyDossier.js","sourceRoot":"","sources":["../../src/tools/verifyDossier.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"verifyDossier.js","sourceRoot":"","sources":["../../src/tools/verifyDossier.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAyBH,sCAuBC;AA9CD,sDAAiE;AACjE,4CAAyC;AAmBzC;;GAEG;AACI,KAAK,UAAU,aAAa,CAAC,KAAyB;IAC3D,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAEvB,eAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAO,EAAsB,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAE9E,eAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE;YACpC,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,8BAAgB,EAAE,CAAC;YACtC,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;aACzD,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* verify_graph tool - Batch verification for dossier dependency graphs.
|
|
3
|
+
* Verifies all dossiers in a resolved graph and returns an aggregate security report.
|
|
4
|
+
*/
|
|
5
|
+
export interface VerifyGraphInput {
|
|
6
|
+
graph_id?: string;
|
|
7
|
+
dossier?: string;
|
|
8
|
+
}
|
|
9
|
+
export type Recommendation = 'ALLOW' | 'WARN' | 'BLOCK';
|
|
10
|
+
export interface DossierVerificationResult {
|
|
11
|
+
name: string;
|
|
12
|
+
recommendation: Recommendation;
|
|
13
|
+
risk: string;
|
|
14
|
+
passed: boolean;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface VerifyGraphOutput {
|
|
18
|
+
overall_recommendation: Recommendation;
|
|
19
|
+
summary: string;
|
|
20
|
+
blockers: string[];
|
|
21
|
+
dossiers: DossierVerificationResult[];
|
|
22
|
+
}
|
|
23
|
+
export interface VerifyGraphError {
|
|
24
|
+
error: {
|
|
25
|
+
type: 'validation' | 'resolve' | 'not_found';
|
|
26
|
+
message: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Verify all dossiers in a dependency graph and return an aggregate security report.
|
|
31
|
+
*/
|
|
32
|
+
export declare function verifyGraph(input: VerifyGraphInput): Promise<VerifyGraphOutput | VerifyGraphError>;
|
|
33
|
+
//# sourceMappingURL=verifyGraph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyGraph.d.ts","sourceRoot":"","sources":["../../src/tools/verifyGraph.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAExD,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,cAAc,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,sBAAsB,EAAE,cAAc,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,yBAAyB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE;QACL,IAAI,EAAE,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;QAC7C,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAiGD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,CAuE/C"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* verify_graph tool - Batch verification for dossier dependency graphs.
|
|
4
|
+
* Verifies all dossiers in a resolved graph and returns an aggregate security report.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.verifyGraph = verifyGraph;
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const graph_1 = require("../orchestration/graph");
|
|
10
|
+
const resolver_1 = require("../orchestration/resolver");
|
|
11
|
+
const cli_wrapper_1 = require("../utils/cli-wrapper");
|
|
12
|
+
const graphStore_1 = require("../utils/graphStore");
|
|
13
|
+
const logger_1 = require("../utils/logger");
|
|
14
|
+
/**
|
|
15
|
+
* Extract all unique dossiers from an execution plan.
|
|
16
|
+
*/
|
|
17
|
+
function extractDossiers(plan) {
|
|
18
|
+
const seen = new Set();
|
|
19
|
+
const dossiers = [];
|
|
20
|
+
for (const phase of plan.phases) {
|
|
21
|
+
for (const entry of phase.dossiers) {
|
|
22
|
+
if (!seen.has(entry.name)) {
|
|
23
|
+
seen.add(entry.name);
|
|
24
|
+
dossiers.push(entry);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return dossiers;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Determine recommendation based on verification result and risk level.
|
|
32
|
+
*/
|
|
33
|
+
function getRecommendation(result, riskLevel) {
|
|
34
|
+
if (!result.passed) {
|
|
35
|
+
// Check if integrity stage specifically failed (stage 1 is typically integrity/checksum)
|
|
36
|
+
const integrityFailed = result.stages.some((s) => s.passed === false &&
|
|
37
|
+
(s.name.toLowerCase().includes('integrity') || s.name.toLowerCase().includes('checksum')));
|
|
38
|
+
if (integrityFailed)
|
|
39
|
+
return 'BLOCK';
|
|
40
|
+
return 'WARN';
|
|
41
|
+
}
|
|
42
|
+
// Even if verification passed, high risk dossiers get a WARN
|
|
43
|
+
if (riskLevel === 'critical' || riskLevel === 'high')
|
|
44
|
+
return 'WARN';
|
|
45
|
+
return 'ALLOW';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Compute the worst-case recommendation across all results.
|
|
49
|
+
*/
|
|
50
|
+
function worstCase(recommendations) {
|
|
51
|
+
if (recommendations.includes('BLOCK'))
|
|
52
|
+
return 'BLOCK';
|
|
53
|
+
if (recommendations.includes('WARN'))
|
|
54
|
+
return 'WARN';
|
|
55
|
+
return 'ALLOW';
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Verify a single dossier entry, returning its verification result.
|
|
59
|
+
*/
|
|
60
|
+
async function verifySingleDossier(entry) {
|
|
61
|
+
const identifier = entry.path ?? entry.name;
|
|
62
|
+
try {
|
|
63
|
+
const result = await (0, cli_wrapper_1.execCli)('verify', [identifier, '--json']);
|
|
64
|
+
const risk = entry.riskLevel ?? 'unknown';
|
|
65
|
+
const recommendation = getRecommendation(result, risk);
|
|
66
|
+
return {
|
|
67
|
+
name: entry.name,
|
|
68
|
+
recommendation,
|
|
69
|
+
risk,
|
|
70
|
+
passed: result.passed,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (error instanceof cli_wrapper_1.CliNotFoundError) {
|
|
75
|
+
return {
|
|
76
|
+
name: entry.name,
|
|
77
|
+
recommendation: 'BLOCK',
|
|
78
|
+
risk: entry.riskLevel ?? 'unknown',
|
|
79
|
+
passed: false,
|
|
80
|
+
error: error.message,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
84
|
+
return {
|
|
85
|
+
name: entry.name,
|
|
86
|
+
recommendation: 'BLOCK',
|
|
87
|
+
risk: entry.riskLevel ?? 'unknown',
|
|
88
|
+
passed: false,
|
|
89
|
+
error: message,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Resolve a dossier reference into an execution plan (same logic as resolveGraph tool).
|
|
95
|
+
*/
|
|
96
|
+
async function resolvePlan(dossierRef) {
|
|
97
|
+
const resolver = new resolver_1.DossierResolver();
|
|
98
|
+
const isPath = dossierRef.includes('/') || dossierRef.endsWith('.ds.md');
|
|
99
|
+
const entryDossier = isPath
|
|
100
|
+
? await resolver.resolveFromPath((0, node_path_1.resolve)(dossierRef))
|
|
101
|
+
: await resolver.resolve(dossierRef);
|
|
102
|
+
const nodes = await resolver.resolveGraph(entryDossier);
|
|
103
|
+
const graph = (0, graph_1.buildGraph)(nodes);
|
|
104
|
+
return (0, graph_1.buildExecutionPlan)(graph, entryDossier.name);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Verify all dossiers in a dependency graph and return an aggregate security report.
|
|
108
|
+
*/
|
|
109
|
+
async function verifyGraph(input) {
|
|
110
|
+
const { graph_id, dossier } = input;
|
|
111
|
+
if (!graph_id && !dossier) {
|
|
112
|
+
return {
|
|
113
|
+
error: {
|
|
114
|
+
type: 'validation',
|
|
115
|
+
message: 'Either graph_id or dossier parameter is required',
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
let plan;
|
|
120
|
+
if (graph_id) {
|
|
121
|
+
const stored = (0, graphStore_1.getGraph)(graph_id);
|
|
122
|
+
if (!stored) {
|
|
123
|
+
return {
|
|
124
|
+
error: {
|
|
125
|
+
type: 'not_found',
|
|
126
|
+
message: `No graph found with id: ${graph_id}`,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
plan = stored;
|
|
131
|
+
logger_1.logger.info('Verifying graph from store', { graphId: graph_id });
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
logger_1.logger.info('Resolving and verifying graph', { dossier });
|
|
135
|
+
try {
|
|
136
|
+
plan = await resolvePlan(dossier);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
140
|
+
logger_1.logger.error('Graph resolution failed during verify', { dossier, error: message });
|
|
141
|
+
return {
|
|
142
|
+
error: { type: 'resolve', message },
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const entries = extractDossiers(plan);
|
|
147
|
+
logger_1.logger.info('Starting batch verification', { totalDossiers: entries.length });
|
|
148
|
+
// Verify all dossiers in parallel
|
|
149
|
+
const results = await Promise.all(entries.map(verifySingleDossier));
|
|
150
|
+
const blockers = results.filter((r) => r.recommendation === 'BLOCK').map((r) => r.name);
|
|
151
|
+
const overall = worstCase(results.map((r) => r.recommendation));
|
|
152
|
+
const counts = { ALLOW: 0, WARN: 0, BLOCK: 0 };
|
|
153
|
+
for (const r of results)
|
|
154
|
+
counts[r.recommendation]++;
|
|
155
|
+
const parts = [`${results.length} dossiers verified`];
|
|
156
|
+
if (counts.ALLOW > 0)
|
|
157
|
+
parts.push(`${counts.ALLOW} passed`);
|
|
158
|
+
if (counts.WARN > 0)
|
|
159
|
+
parts.push(`${counts.WARN} warnings`);
|
|
160
|
+
if (counts.BLOCK > 0)
|
|
161
|
+
parts.push(`${counts.BLOCK} blocked`);
|
|
162
|
+
const output = {
|
|
163
|
+
overall_recommendation: overall,
|
|
164
|
+
summary: parts.join(', '),
|
|
165
|
+
blockers,
|
|
166
|
+
dossiers: results,
|
|
167
|
+
};
|
|
168
|
+
logger_1.logger.info('Batch verification complete', {
|
|
169
|
+
overall,
|
|
170
|
+
total: results.length,
|
|
171
|
+
blockers: blockers.length,
|
|
172
|
+
});
|
|
173
|
+
return output;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=verifyGraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyGraph.js","sourceRoot":"","sources":["../../src/tools/verifyGraph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI wrapper utility - executes `ai-dossier` CLI commands and parses JSON output.
|
|
3
|
+
* This is the single integration point between the MCP server and CLI.
|
|
4
|
+
*/
|
|
5
|
+
export interface CliResult<T = unknown> {
|
|
6
|
+
data: T;
|
|
7
|
+
}
|
|
8
|
+
export declare class CliNotFoundError extends Error {
|
|
9
|
+
constructor();
|
|
10
|
+
}
|
|
11
|
+
export declare class CliExecutionError extends Error {
|
|
12
|
+
readonly command: string;
|
|
13
|
+
readonly exitCode: number | null;
|
|
14
|
+
readonly stderr: string;
|
|
15
|
+
constructor(command: string, exitCode: number | null, stderr: string);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Execute a CLI command and return parsed JSON output.
|
|
19
|
+
*
|
|
20
|
+
* @param command - The CLI subcommand (e.g. "verify", "info", "list", "search")
|
|
21
|
+
* @param args - Arguments to pass to the command
|
|
22
|
+
* @returns Parsed JSON output from the CLI
|
|
23
|
+
*/
|
|
24
|
+
export declare function execCli<T = unknown>(command: string, args: string[]): Promise<T>;
|
|
25
|
+
//# sourceMappingURL=cli-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-wrapper.d.ts","sourceRoot":"","sources":["../../src/utils/cli-wrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,OAAO;IACpC,IAAI,EAAE,CAAC,CAAC;CACT;AAED,qBAAa,gBAAiB,SAAQ,KAAK;;CAK1C;AAED,qBAAa,iBAAkB,SAAQ,KAAK;aAExB,OAAO,EAAE,MAAM;aACf,QAAQ,EAAE,MAAM,GAAG,IAAI;aACvB,MAAM,EAAE,MAAM;gBAFd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,MAAM,EAAE,MAAM;CAKjC;AAUD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAsDhF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CLI wrapper utility - executes `ai-dossier` CLI commands and parses JSON output.
|
|
4
|
+
* This is the single integration point between the MCP server and CLI.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.CliExecutionError = exports.CliNotFoundError = void 0;
|
|
8
|
+
exports.execCli = execCli;
|
|
9
|
+
const node_child_process_1 = require("node:child_process");
|
|
10
|
+
const logger_1 = require("./logger");
|
|
11
|
+
const CLI_TIMEOUT_MS = 30_000;
|
|
12
|
+
class CliNotFoundError extends Error {
|
|
13
|
+
constructor() {
|
|
14
|
+
super('ai-dossier CLI not found. Install it with: npm install -g @ai-dossier/cli');
|
|
15
|
+
this.name = 'CliNotFoundError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.CliNotFoundError = CliNotFoundError;
|
|
19
|
+
class CliExecutionError extends Error {
|
|
20
|
+
command;
|
|
21
|
+
exitCode;
|
|
22
|
+
stderr;
|
|
23
|
+
constructor(command, exitCode, stderr) {
|
|
24
|
+
super(`CLI command failed: ai-dossier ${command} (exit code ${exitCode})`);
|
|
25
|
+
this.command = command;
|
|
26
|
+
this.exitCode = exitCode;
|
|
27
|
+
this.stderr = stderr;
|
|
28
|
+
this.name = 'CliExecutionError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.CliExecutionError = CliExecutionError;
|
|
32
|
+
/**
|
|
33
|
+
* Find the ai-dossier binary path.
|
|
34
|
+
* Tries the global binary first, then falls back to npx.
|
|
35
|
+
*/
|
|
36
|
+
function findCliBinary() {
|
|
37
|
+
return { cmd: 'ai-dossier', prefixArgs: [] };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Execute a CLI command and return parsed JSON output.
|
|
41
|
+
*
|
|
42
|
+
* @param command - The CLI subcommand (e.g. "verify", "info", "list", "search")
|
|
43
|
+
* @param args - Arguments to pass to the command
|
|
44
|
+
* @returns Parsed JSON output from the CLI
|
|
45
|
+
*/
|
|
46
|
+
function execCli(command, args) {
|
|
47
|
+
const { cmd, prefixArgs } = findCliBinary();
|
|
48
|
+
const fullArgs = [...prefixArgs, command, ...args];
|
|
49
|
+
logger_1.logger.debug('Executing CLI command', { cmd, args: fullArgs });
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
(0, node_child_process_1.execFile)(cmd, fullArgs, { timeout: CLI_TIMEOUT_MS, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {
|
|
52
|
+
if (error) {
|
|
53
|
+
// Check if the binary was not found
|
|
54
|
+
if ('code' in error && error.code === 'ENOENT') {
|
|
55
|
+
reject(new CliNotFoundError());
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// For verify, a non-zero exit code with JSON on stdout is still valid
|
|
59
|
+
// (verification failed but output is structured)
|
|
60
|
+
if (stdout.trim()) {
|
|
61
|
+
try {
|
|
62
|
+
const parsed = JSON.parse(stdout);
|
|
63
|
+
resolve(parsed);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Not valid JSON, fall through to error
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
reject(new CliExecutionError(command, error.code !== undefined ? Number(error.code) : null, stderr));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const parsed = JSON.parse(stdout);
|
|
75
|
+
resolve(parsed);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
reject(new Error(`Failed to parse CLI JSON output for "ai-dossier ${command}": ${stdout.slice(0, 200)}`));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=cli-wrapper.js.map
|