@smartmemory/compose 0.1.6-beta → 0.1.7-beta
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/bin/compose.js +186 -55
- package/bin/git-hooks/pre-push.template +26 -0
- package/contracts/feature-json.schema.json +115 -0
- package/contracts/roadmap-row.schema.json +23 -0
- package/contracts/vision-state.schema.json +64 -0
- package/lib/completion-writer.js +1 -2
- package/lib/feature-code.js +29 -0
- package/lib/feature-validator.js +629 -0
- package/lib/feature-writer.js +1 -1
- package/lib/journal-writer.js +1 -1
- package/package.json +1 -1
- package/server/compose-mcp-tools.js +18 -0
- package/server/compose-mcp.js +28 -0
- package/server/schema-validator.js +50 -9
package/server/compose-mcp.js
CHANGED
|
@@ -56,6 +56,8 @@ import {
|
|
|
56
56
|
toolGetJournalEntries,
|
|
57
57
|
toolRecordCompletion,
|
|
58
58
|
toolGetCompletions,
|
|
59
|
+
toolValidateFeature,
|
|
60
|
+
toolValidateProject,
|
|
59
61
|
} from './compose-mcp-tools.js';
|
|
60
62
|
|
|
61
63
|
// ---------------------------------------------------------------------------
|
|
@@ -322,6 +324,30 @@ const TOOLS = [
|
|
|
322
324
|
},
|
|
323
325
|
},
|
|
324
326
|
},
|
|
327
|
+
{
|
|
328
|
+
name: 'validate_feature',
|
|
329
|
+
description: 'Cross-check a single feature against ROADMAP, vision-state, feature.json, folder contents, linked artifacts, and cross-references. Returns structured findings with severity (error/warning/info). FEATURE_NOT_FOUND emitted as a finding (not thrown) when the code matches strict regex but exists in no source.',
|
|
330
|
+
inputSchema: {
|
|
331
|
+
type: 'object',
|
|
332
|
+
required: ['feature_code'],
|
|
333
|
+
properties: {
|
|
334
|
+
feature_code: { type: 'string', description: 'Strict feature code, e.g. "COMP-MCP-VALIDATE"' },
|
|
335
|
+
external_prefixes: { type: 'array', items: { type: 'string' }, description: 'Code prefixes (e.g. ["STRAT-"]) treated as external; downgrades ORPHAN_FOLDER to info' },
|
|
336
|
+
feature_json_mode: { type: 'boolean', description: 'Default true. Set false to skip feature.json comparisons in legacy projects.' },
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
name: 'validate_project',
|
|
342
|
+
description: 'Run validate_feature for every code in vision-state, ROADMAP, and folders, plus cross-cutting checks (orphan folders, dangling cross-refs, CHANGELOG references, journal index drift). Returns the union of all findings.',
|
|
343
|
+
inputSchema: {
|
|
344
|
+
type: 'object',
|
|
345
|
+
properties: {
|
|
346
|
+
external_prefixes: { type: 'array', items: { type: 'string' } },
|
|
347
|
+
feature_json_mode: { type: 'boolean' },
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
},
|
|
325
351
|
|
|
326
352
|
// -------------------------------------------------------------------------
|
|
327
353
|
// Linker — COMP-MCP-ARTIFACT-LINKER
|
|
@@ -554,6 +580,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
554
580
|
case 'get_journal_entries': result = await toolGetJournalEntries(args); break;
|
|
555
581
|
case 'record_completion': result = await toolRecordCompletion(args); break;
|
|
556
582
|
case 'get_completions': result = await toolGetCompletions(args); break;
|
|
583
|
+
case 'validate_feature': result = await toolValidateFeature(args); break;
|
|
584
|
+
case 'validate_project': result = await toolValidateProject(args); break;
|
|
557
585
|
// agent_run removed — STRAT-DEDUP-AGENTRUN v1. Use mcp__stratum__stratum_agent_run.
|
|
558
586
|
default:
|
|
559
587
|
return {
|
|
@@ -5,26 +5,43 @@ import Ajv from 'ajv';
|
|
|
5
5
|
import addFormats from 'ajv-formats';
|
|
6
6
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const
|
|
8
|
+
const DEFAULT_SCHEMA_PATH = resolve(__dirname, '../contracts/comp-obs-contract.schema.json');
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// Per-path cache. Each entry: { schema, ajv }.
|
|
11
|
+
const cache = new Map();
|
|
11
12
|
|
|
12
|
-
function load() {
|
|
13
|
-
if (
|
|
14
|
-
const schema = JSON.parse(readFileSync(
|
|
13
|
+
function load(schemaPath = DEFAULT_SCHEMA_PATH) {
|
|
14
|
+
if (cache.has(schemaPath)) return cache.get(schemaPath);
|
|
15
|
+
const schema = JSON.parse(readFileSync(schemaPath, 'utf8'));
|
|
15
16
|
const ajv = new Ajv({ strict: false, allErrors: true });
|
|
16
17
|
addFormats(ajv);
|
|
17
18
|
ajv.addSchema(schema);
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const entry = { schema, ajv };
|
|
20
|
+
cache.set(schemaPath, entry);
|
|
21
|
+
return entry;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Load (and cache) a schema by absolute path. Returns `{ schema, ajv }`.
|
|
26
|
+
* Used by code that wants to compile arbitrary `$ref`s against the schema
|
|
27
|
+
* without going through the SchemaValidator class.
|
|
28
|
+
*/
|
|
29
|
+
export function loadSchema(schemaPath) {
|
|
30
|
+
return load(schemaPath);
|
|
20
31
|
}
|
|
21
32
|
|
|
22
33
|
export class SchemaValidator {
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} [schemaPath] Absolute path to a JSON Schema file.
|
|
36
|
+
* Default is the comp-obs-contract schema (back-compat for existing
|
|
37
|
+
* callers that pass no args).
|
|
38
|
+
*/
|
|
39
|
+
constructor(schemaPath = DEFAULT_SCHEMA_PATH) {
|
|
40
|
+
const { schema, ajv } = load(schemaPath);
|
|
25
41
|
this.schema = schema;
|
|
26
42
|
this.ajv = ajv;
|
|
27
43
|
this._validators = new Map();
|
|
44
|
+
this._rootValidator = null;
|
|
28
45
|
}
|
|
29
46
|
|
|
30
47
|
_getValidator(defName) {
|
|
@@ -39,11 +56,35 @@ export class SchemaValidator {
|
|
|
39
56
|
return v;
|
|
40
57
|
}
|
|
41
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Validate `obj` against `schema.definitions[defName]`. Used by the
|
|
61
|
+
* comp-obs-contract code paths.
|
|
62
|
+
*/
|
|
42
63
|
validate(defName, obj) {
|
|
43
64
|
const v = this._getValidator(defName);
|
|
44
65
|
const valid = v(obj);
|
|
45
66
|
return { valid: !!valid, errors: valid ? [] : (v.errors || []) };
|
|
46
67
|
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Validate `obj` against the schema's root (no $defs/$ref indirection).
|
|
71
|
+
* Used by feature-json / vision-state / roadmap-row schemas, which are
|
|
72
|
+
* top-level shapes without nested definitions.
|
|
73
|
+
*/
|
|
74
|
+
validateRoot(obj) {
|
|
75
|
+
if (!this._rootValidator) {
|
|
76
|
+
// ajv.getSchema by $id returns the root validator if the schema was
|
|
77
|
+
// added via addSchema (which load() does).
|
|
78
|
+
let v = this.schema.$id ? this.ajv.getSchema(this.schema.$id) : null;
|
|
79
|
+
if (!v) v = this.ajv.compile(this.schema);
|
|
80
|
+
this._rootValidator = v;
|
|
81
|
+
}
|
|
82
|
+
const v = this._rootValidator;
|
|
83
|
+
const valid = v(obj);
|
|
84
|
+
return { valid: !!valid, errors: valid ? [] : (v.errors || []) };
|
|
85
|
+
}
|
|
47
86
|
}
|
|
48
87
|
|
|
88
|
+
// Back-compat export — points at the comp-obs schema version. Existing
|
|
89
|
+
// callers consuming SCHEMA_VERSION continue to work unchanged.
|
|
49
90
|
export const SCHEMA_VERSION = load().schema.version;
|