@epiccontext/mcp 0.1.61 → 0.1.63
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/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +118 -64
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/push.d.ts.map +1 -1
- package/dist/cli/commands/push.js +24 -0
- package/dist/cli/commands/push.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +16 -0
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +105 -0
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/files.d.ts +7 -1
- package/dist/cli/files.d.ts.map +1 -1
- package/dist/cli/files.js +1160 -9
- package/dist/cli/files.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +6 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/create-block.d.ts.map +1 -1
- package/dist/mcp/tools/create-block.js +3 -3
- package/dist/mcp/tools/create-block.js.map +1 -1
- package/dist/mcp/tools/update-block.d.ts.map +1 -1
- package/dist/mcp/tools/update-block.js +2 -2
- package/dist/mcp/tools/update-block.js.map +1 -1
- package/dist/mcp/tools/validate.d.ts +10 -0
- package/dist/mcp/tools/validate.d.ts.map +1 -0
- package/dist/mcp/tools/validate.js +105 -0
- package/dist/mcp/tools/validate.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqKrE"}
|
|
@@ -3,101 +3,155 @@ import * as path from "path";
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import ora from "ora";
|
|
5
5
|
import { ensureContextFolder, ensureDocumentsFolder, ensureAppsFolder, generateAgentConfigFiles, copyStorybookTemplate } from "../files.js";
|
|
6
|
-
import { saveConfig, isInsideProject } from "../config.js";
|
|
6
|
+
import { saveConfig, isInsideProject, loadConfig } from "../config.js";
|
|
7
7
|
export async function initCommand(options) {
|
|
8
|
+
const isUpgrade = isInsideProject();
|
|
8
9
|
const contextPath = options.path || "./CONTEXT";
|
|
9
10
|
const documentsPath = "./DOCUMENTS";
|
|
10
11
|
const appsPath = "./apps";
|
|
11
12
|
const absoluteContextPath = path.resolve(process.cwd(), contextPath);
|
|
12
13
|
const absoluteDocumentsPath = path.resolve(process.cwd(), documentsPath);
|
|
13
14
|
const absoluteAppsPath = path.resolve(process.cwd(), appsPath);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
console.log("
|
|
19
|
-
return;
|
|
15
|
+
if (isUpgrade) {
|
|
16
|
+
console.log(chalk.blue("Existing EpicContext project detected — upgrading..."));
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.log(chalk.blue("Initializing EpicContext project..."));
|
|
20
20
|
}
|
|
21
21
|
// Warn if inside a git repo (project root should not be a git repo)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
if (!isUpgrade) {
|
|
23
|
+
const gitDir = path.join(process.cwd(), ".git");
|
|
24
|
+
if (fs.existsSync(gitDir)) {
|
|
25
|
+
console.log(chalk.yellow("\n Note: This directory is a git repository."));
|
|
26
|
+
console.log(chalk.yellow(" EpicContext project roots are typically NOT git repos."));
|
|
27
|
+
console.log(chalk.yellow(" Code repos should live inside the apps/ folder.\n"));
|
|
28
|
+
}
|
|
27
29
|
}
|
|
28
|
-
const
|
|
30
|
+
const spinnerText = isUpgrade ? "Upgrading project structure..." : "Creating project structure...";
|
|
31
|
+
const spinner = ora(spinnerText).start();
|
|
29
32
|
try {
|
|
30
|
-
//
|
|
31
|
-
|
|
33
|
+
// Track what was added during upgrade
|
|
34
|
+
const added = [];
|
|
35
|
+
// Create/update folder structure (functions are idempotent — skip existing files)
|
|
36
|
+
// For upgrades: force-regenerate AI guides since they're auto-generated
|
|
37
|
+
ensureContextFolder(absoluteContextPath, { forceRegenerateGuides: isUpgrade, skipExamplesIfHasBlocks: isUpgrade });
|
|
38
|
+
// DOCUMENTS folder — may not exist in older projects
|
|
39
|
+
const hadDocuments = fs.existsSync(absoluteDocumentsPath);
|
|
32
40
|
ensureDocumentsFolder(absoluteDocumentsPath);
|
|
41
|
+
if (isUpgrade && !hadDocuments)
|
|
42
|
+
added.push("DOCUMENTS/");
|
|
43
|
+
// apps folder
|
|
44
|
+
const hadApps = fs.existsSync(absoluteAppsPath);
|
|
33
45
|
ensureAppsFolder(absoluteAppsPath);
|
|
34
|
-
|
|
46
|
+
if (isUpgrade && !hadApps)
|
|
47
|
+
added.push("apps/");
|
|
48
|
+
// Storybook template
|
|
35
49
|
const storybookResult = copyStorybookTemplate(absoluteAppsPath);
|
|
36
|
-
//
|
|
50
|
+
// AI agent config files — may not exist in older projects
|
|
37
51
|
const projectRoot = process.cwd();
|
|
52
|
+
const hadClaudeMd = fs.existsSync(path.join(projectRoot, "CLAUDE.md"));
|
|
38
53
|
generateAgentConfigFiles(projectRoot, contextPath);
|
|
39
|
-
|
|
54
|
+
if (isUpgrade && !hadClaudeMd)
|
|
55
|
+
added.push("AI agent config files (CLAUDE.md, .cursorrules, etc.)");
|
|
56
|
+
// Save/update config (saveConfig does deep merge with existing)
|
|
57
|
+
const existingConfig = loadConfig();
|
|
40
58
|
saveConfig({
|
|
41
59
|
version: 1,
|
|
42
60
|
sync: {
|
|
43
61
|
path: contextPath,
|
|
44
62
|
documentsPath,
|
|
45
|
-
conflictResolution: "timestamp",
|
|
46
|
-
autoSync: false,
|
|
47
|
-
ignoredPatterns: ["*.tmp", ".DS_Store", "node_modules"],
|
|
63
|
+
conflictResolution: existingConfig?.sync?.conflictResolution || "timestamp",
|
|
64
|
+
autoSync: existingConfig?.sync?.autoSync ?? false,
|
|
65
|
+
ignoredPatterns: existingConfig?.sync?.ignoredPatterns || ["*.tmp", ".DS_Store", "node_modules"],
|
|
48
66
|
},
|
|
49
67
|
documents: {
|
|
50
|
-
enabled: true,
|
|
51
|
-
syncOnPull: false,
|
|
52
|
-
maxFileSize: 25 * 1024 * 1024,
|
|
68
|
+
enabled: existingConfig?.documents?.enabled ?? true,
|
|
69
|
+
syncOnPull: existingConfig?.documents?.syncOnPull ?? false,
|
|
70
|
+
maxFileSize: existingConfig?.documents?.maxFileSize ?? 25 * 1024 * 1024,
|
|
53
71
|
},
|
|
54
|
-
apps: storybookResult.created > 0
|
|
72
|
+
apps: existingConfig?.apps || (storybookResult.created > 0
|
|
55
73
|
? [{ name: "storybook", path: "./apps/storybook", type: "other" }]
|
|
56
|
-
: [],
|
|
74
|
+
: []),
|
|
57
75
|
watch: {
|
|
58
|
-
debounce: 2000,
|
|
59
|
-
pushOnly: false,
|
|
76
|
+
debounce: existingConfig?.watch?.debounce ?? 2000,
|
|
77
|
+
pushOnly: existingConfig?.watch?.pushOnly ?? false,
|
|
60
78
|
},
|
|
61
79
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
if (isUpgrade) {
|
|
81
|
+
spinner.succeed("Project upgraded successfully!");
|
|
82
|
+
console.log("");
|
|
83
|
+
if (added.length > 0) {
|
|
84
|
+
console.log(chalk.green("Added missing:"));
|
|
85
|
+
for (const item of added) {
|
|
86
|
+
console.log(` + ${item}`);
|
|
87
|
+
}
|
|
88
|
+
console.log("");
|
|
89
|
+
}
|
|
90
|
+
console.log(chalk.green("Regenerated:"));
|
|
91
|
+
console.log(` ~ CONTEXT/AI-GUIDE.md ${chalk.dim("(core AI guide)")}`);
|
|
92
|
+
console.log(` ~ CONTEXT/.ai-guides/*.md ${chalk.dim("(section guides)")}`);
|
|
93
|
+
console.log(` ~ CONTEXT/*/README.md ${chalk.dim("(section READMEs)")}`);
|
|
94
|
+
console.log("");
|
|
95
|
+
console.log(chalk.green("Skipped:"));
|
|
96
|
+
console.log(` - Example files in sections that already have blocks`);
|
|
97
|
+
console.log(` - Existing agent config files (CLAUDE.md, .cursorrules, etc.)`);
|
|
98
|
+
console.log(` - Existing .epicontext config values (preserved)`);
|
|
99
|
+
console.log("");
|
|
100
|
+
console.log(chalk.blue("What's new:"));
|
|
101
|
+
if (!hadDocuments) {
|
|
102
|
+
console.log(` - ${chalk.bold("DOCUMENTS/")} folder for syncing PDFs, images, research files`);
|
|
103
|
+
console.log(` Pull documents: ${chalk.cyan("npx @epiccontext/mcp pull --with-documents")}`);
|
|
104
|
+
}
|
|
105
|
+
console.log(` - Updated AI guides with latest block type schemas`);
|
|
106
|
+
console.log(` - Example files with link/traceability examples`);
|
|
107
|
+
console.log(` - Validate command: ${chalk.cyan("npx @epiccontext/mcp validate")}`);
|
|
108
|
+
console.log("");
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
spinner.succeed("EpicContext project initialized!");
|
|
112
|
+
console.log("");
|
|
113
|
+
console.log(chalk.green("Project structure:"));
|
|
114
|
+
console.log(` ${chalk.bold("CONTEXT/")} ${chalk.dim("Documentation blocks (syncs with cloud)")}`);
|
|
115
|
+
console.log(` ├── constitution/`);
|
|
116
|
+
console.log(` ├── brand/`);
|
|
117
|
+
console.log(` ├── product/`);
|
|
118
|
+
console.log(` ├── business-strategy/`);
|
|
119
|
+
console.log(` ├── users/`);
|
|
120
|
+
console.log(` ├── research/`);
|
|
121
|
+
console.log(` ├── technical/`);
|
|
122
|
+
console.log(` ├── design-system/`);
|
|
123
|
+
console.log(` ├── information-architecture/`);
|
|
124
|
+
console.log(` ├── metrics/`);
|
|
125
|
+
console.log(` ├── decisions/`);
|
|
126
|
+
console.log(` ├── development/`);
|
|
127
|
+
console.log(` ├── marketing/`);
|
|
128
|
+
console.log(` ├── README.md`);
|
|
129
|
+
console.log(` └── AI-GUIDE.md`);
|
|
130
|
+
console.log(` ${chalk.bold("DOCUMENTS/")} ${chalk.dim("Project files (syncs with cloud)")}`);
|
|
131
|
+
console.log(` ${chalk.bold("apps/")} ${chalk.dim("Code repositories (git repos)")}`);
|
|
132
|
+
if (storybookResult.created > 0) {
|
|
133
|
+
console.log(` └── storybook/ ${chalk.dim("(pre-configured with JWT auth)")}`);
|
|
134
|
+
}
|
|
135
|
+
console.log("");
|
|
136
|
+
console.log(chalk.green("Example files:"));
|
|
137
|
+
console.log(` Each section contains ${chalk.dim("_example-*.md")} files showing the correct format.`);
|
|
138
|
+
console.log(` These are ${chalk.bold("not pushed")} to the cloud — delete them after creating your own blocks.`);
|
|
139
|
+
console.log("");
|
|
140
|
+
console.log(chalk.green("Created AI agent config files:"));
|
|
141
|
+
console.log(` CLAUDE.md ${chalk.dim("(Claude Code)")}`);
|
|
142
|
+
console.log(` .cursorrules ${chalk.dim("(Cursor)")}`);
|
|
143
|
+
console.log(` .github/copilot-instructions.md ${chalk.dim("(GitHub Copilot)")}`);
|
|
144
|
+
console.log(` .windsurfrules ${chalk.dim("(Windsurf)")}`);
|
|
145
|
+
console.log("");
|
|
146
|
+
console.log(chalk.blue("Next steps:"));
|
|
147
|
+
console.log(` 1. Run ${chalk.cyan("npx @epiccontext/mcp link")} to connect to your EpicContext project`);
|
|
148
|
+
console.log(` 2. Run ${chalk.cyan("npx @epiccontext/mcp pull --with-documents")} to download your content`);
|
|
149
|
+
console.log(` 3. Clone your code repos into ${chalk.cyan("apps/")} and register with ${chalk.cyan("npx @epiccontext/mcp add-app")}`);
|
|
150
|
+
console.log("");
|
|
85
151
|
}
|
|
86
|
-
console.log("");
|
|
87
|
-
console.log(chalk.green("Created AI agent config files:"));
|
|
88
|
-
console.log(` CLAUDE.md ${chalk.dim("(Claude Code)")}`);
|
|
89
|
-
console.log(` .cursorrules ${chalk.dim("(Cursor)")}`);
|
|
90
|
-
console.log(` .github/copilot-instructions.md ${chalk.dim("(GitHub Copilot)")}`);
|
|
91
|
-
console.log(` .windsurfrules ${chalk.dim("(Windsurf)")}`);
|
|
92
|
-
console.log("");
|
|
93
|
-
console.log(chalk.blue("Next steps:"));
|
|
94
|
-
console.log(` 1. Run ${chalk.cyan("npx @epiccontext/mcp link")} to connect to your EpicContext project`);
|
|
95
|
-
console.log(` 2. Run ${chalk.cyan("npx @epiccontext/mcp pull --with-documents")} to download your content`);
|
|
96
|
-
console.log(` 3. Clone your code repos into ${chalk.cyan("apps/")} and register with ${chalk.cyan("npx @epiccontext/mcp add-app")}`);
|
|
97
|
-
console.log("");
|
|
98
152
|
}
|
|
99
153
|
catch (error) {
|
|
100
|
-
spinner.fail("Failed to initialize");
|
|
154
|
+
spinner.fail(isUpgrade ? "Failed to upgrade" : "Failed to initialize");
|
|
101
155
|
console.error(chalk.red("Error:"), error.message);
|
|
102
156
|
process.exit(1);
|
|
103
157
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC5I,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/push.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/push.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmOrE"}
|
|
@@ -5,6 +5,7 @@ import { createClient } from "../../api/client.js";
|
|
|
5
5
|
import { pushToCloud } from "../../sync/push.js";
|
|
6
6
|
import { pushDocuments } from "../../sync/document-push.js";
|
|
7
7
|
import { runQuickValidation } from "./validate.js";
|
|
8
|
+
import { readContextFolder } from "../files.js";
|
|
8
9
|
export async function pushCommand(options) {
|
|
9
10
|
const config = loadConfig();
|
|
10
11
|
// Check if linked to a project
|
|
@@ -84,6 +85,13 @@ export async function pushCommand(options) {
|
|
|
84
85
|
spinner.succeed("Push complete!");
|
|
85
86
|
console.log("");
|
|
86
87
|
}
|
|
88
|
+
// Build section breakdown from local files
|
|
89
|
+
const localFiles = readContextFolder(contextPath);
|
|
90
|
+
const sectionCounts = {};
|
|
91
|
+
for (const file of localFiles) {
|
|
92
|
+
const section = file.path.split("/")[0] || "root";
|
|
93
|
+
sectionCounts[section] = (sectionCounts[section] || 0) + 1;
|
|
94
|
+
}
|
|
87
95
|
console.log(chalk.gray(` Files processed: ${result.filesProcessed}`));
|
|
88
96
|
if (result.result.created > 0) {
|
|
89
97
|
const verb = isDryRun ? "Would create" : "Created";
|
|
@@ -116,6 +124,17 @@ export async function pushCommand(options) {
|
|
|
116
124
|
console.log(chalk.red(` - ${error.path}: ${error.error}`));
|
|
117
125
|
}
|
|
118
126
|
}
|
|
127
|
+
// Section breakdown
|
|
128
|
+
const sectionEntries = Object.entries(sectionCounts).sort((a, b) => b[1] - a[1]);
|
|
129
|
+
if (sectionEntries.length > 0) {
|
|
130
|
+
console.log("");
|
|
131
|
+
console.log(chalk.gray(" Section breakdown:"));
|
|
132
|
+
for (const [section, count] of sectionEntries) {
|
|
133
|
+
const errorsInSection = result.result.errors.filter(e => e.path.startsWith(`${section}/`)).length;
|
|
134
|
+
const errorSuffix = errorsInSection > 0 ? chalk.red(` (${errorsInSection} error${errorsInSection > 1 ? "s" : ""})`) : "";
|
|
135
|
+
console.log(chalk.gray(` ${section}: ${count} file(s)${errorSuffix}`));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
119
138
|
// IMPORTANT: Show warning about potential orphans (blocks in cloud not in local folder)
|
|
120
139
|
const potentialOrphans = result.result.potentialOrphans;
|
|
121
140
|
if (potentialOrphans && potentialOrphans.length > 0) {
|
|
@@ -133,6 +152,11 @@ export async function pushCommand(options) {
|
|
|
133
152
|
console.log(chalk.gray(" These blocks were NOT deleted. They may have been created by team members."));
|
|
134
153
|
console.log(chalk.gray(` Run ${chalk.cyan("npx @epiccontext/mcp pull")} first to get the latest blocks.`));
|
|
135
154
|
}
|
|
155
|
+
// Link to web UI
|
|
156
|
+
if (config.project?.url && !isDryRun) {
|
|
157
|
+
console.log("");
|
|
158
|
+
console.log(chalk.gray(` View in EpicContext: ${chalk.cyan(config.project.url)}`));
|
|
159
|
+
}
|
|
136
160
|
console.log("");
|
|
137
161
|
if (isDryRun && (result.result.created > 0 || result.result.updated > 0 || (result.result.deleted && result.result.deleted > 0))) {
|
|
138
162
|
console.log(chalk.gray(`Run ${chalk.cyan("npx @epiccontext/mcp push")} (without --dry-run) to apply these changes.`));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../../src/cli/commands/push.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../../src/cli/commands/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
export interface ValidateOptions {
|
|
2
2
|
fix?: boolean;
|
|
3
3
|
}
|
|
4
|
+
interface ValidationIssue {
|
|
5
|
+
path: string;
|
|
6
|
+
severity: "error" | "warning";
|
|
7
|
+
message: string;
|
|
8
|
+
suggestion?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Run full validation and return all issues (used by MCP tool and CLI command)
|
|
12
|
+
*/
|
|
13
|
+
export declare function runFullValidation(contextPath: string): {
|
|
14
|
+
fileCount: number;
|
|
15
|
+
issues: ValidationIssue[];
|
|
16
|
+
errors: number;
|
|
17
|
+
warnings: number;
|
|
18
|
+
};
|
|
4
19
|
/**
|
|
5
20
|
* Run a quick validation and return counts (used by push command for pre-push warning)
|
|
6
21
|
* Runs the same checks as the full validate command including cross-file link validation
|
|
@@ -10,4 +25,5 @@ export declare function runQuickValidation(contextPath: string): {
|
|
|
10
25
|
warnings: number;
|
|
11
26
|
};
|
|
12
27
|
export declare function validateCommand(options: ValidateOptions): Promise<void>;
|
|
28
|
+
export {};
|
|
13
29
|
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA8oBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CA+BA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CA6B5F;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAqG7E"}
|
|
@@ -508,6 +508,105 @@ function validateUniqueKeys(files) {
|
|
|
508
508
|
}
|
|
509
509
|
return issues;
|
|
510
510
|
}
|
|
511
|
+
// Block types that are inherently standalone and don't need links
|
|
512
|
+
const STANDALONE_BLOCK_TYPES = new Set([
|
|
513
|
+
"section_guide",
|
|
514
|
+
"glossary",
|
|
515
|
+
"dev_setup",
|
|
516
|
+
"tech_stack",
|
|
517
|
+
"testing_strategy",
|
|
518
|
+
"api_spec",
|
|
519
|
+
"cost_calculator",
|
|
520
|
+
"storybook_link",
|
|
521
|
+
"figma_embed",
|
|
522
|
+
"environment_link",
|
|
523
|
+
]);
|
|
524
|
+
/**
|
|
525
|
+
* Validate that blocks have at least one connection (ref field or universal link).
|
|
526
|
+
* Blocks without any connections are flagged as warnings.
|
|
527
|
+
*/
|
|
528
|
+
function validateLinkCoverage(files) {
|
|
529
|
+
const issues = [];
|
|
530
|
+
for (const file of files) {
|
|
531
|
+
const frontmatter = extractFrontmatter(file.content);
|
|
532
|
+
if (!frontmatter || !frontmatter.type || !frontmatter.key)
|
|
533
|
+
continue;
|
|
534
|
+
const blockType = frontmatter.type;
|
|
535
|
+
// Skip standalone block types that don't need links
|
|
536
|
+
if (STANDALONE_BLOCK_TYPES.has(blockType))
|
|
537
|
+
continue;
|
|
538
|
+
// Count schema ref links
|
|
539
|
+
let hasSchemaRef = false;
|
|
540
|
+
const linkRefs = LINK_REFERENCE[blockType];
|
|
541
|
+
if (linkRefs) {
|
|
542
|
+
for (const link of linkRefs) {
|
|
543
|
+
if (frontmatter[link.fieldKey]) {
|
|
544
|
+
hasSchemaRef = true;
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
// Also check for any _ref or _refs fields not in LINK_REFERENCE
|
|
550
|
+
if (!hasSchemaRef) {
|
|
551
|
+
for (const key of Object.keys(frontmatter)) {
|
|
552
|
+
if ((key.endsWith("_ref") || key.endsWith("_refs")) && frontmatter[key]) {
|
|
553
|
+
hasSchemaRef = true;
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
// Check for universal links
|
|
559
|
+
// The simple YAML parser doesn't handle nested arrays, so check the raw frontmatter text
|
|
560
|
+
let hasUniversalLinks = false;
|
|
561
|
+
const fmMatch = file.content.match(/^---\n([\s\S]*?)\n---/);
|
|
562
|
+
if (fmMatch) {
|
|
563
|
+
const fmText = fmMatch[1];
|
|
564
|
+
// Look for "links:" followed by "- target:" lines (YAML array pattern)
|
|
565
|
+
hasUniversalLinks = /^links:\s*$/m.test(fmText) && /^\s+-\s+target:/m.test(fmText);
|
|
566
|
+
}
|
|
567
|
+
if (!hasSchemaRef && !hasUniversalLinks) {
|
|
568
|
+
issues.push({
|
|
569
|
+
path: file.path,
|
|
570
|
+
severity: "warning",
|
|
571
|
+
message: `Block "${frontmatter.key}" has no links — it falls out of the knowledge graph and won't be found by AI agents`,
|
|
572
|
+
suggestion: `Ask: where did this come from? What does it inform? Add _ref fields and/or links: array in frontmatter`,
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return issues;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Run full validation and return all issues (used by MCP tool and CLI command)
|
|
580
|
+
*/
|
|
581
|
+
export function runFullValidation(contextPath) {
|
|
582
|
+
try {
|
|
583
|
+
const files = readContextFolder(contextPath);
|
|
584
|
+
if (files.length === 0)
|
|
585
|
+
return { fileCount: 0, issues: [], errors: 0, warnings: 0 };
|
|
586
|
+
const allIssues = [];
|
|
587
|
+
for (const file of files) {
|
|
588
|
+
allIssues.push(...validateFile(file.path, file.content));
|
|
589
|
+
}
|
|
590
|
+
// Cross-file link validation
|
|
591
|
+
const linkIssues = validateLinksAcrossFiles(files);
|
|
592
|
+
allIssues.push(...linkIssues);
|
|
593
|
+
// Duplicate key check
|
|
594
|
+
const dupeIssues = validateUniqueKeys(files);
|
|
595
|
+
allIssues.push(...dupeIssues);
|
|
596
|
+
// Link coverage check (warn about unlinked blocks)
|
|
597
|
+
const coverageIssues = validateLinkCoverage(files);
|
|
598
|
+
allIssues.push(...coverageIssues);
|
|
599
|
+
return {
|
|
600
|
+
fileCount: files.length,
|
|
601
|
+
issues: allIssues,
|
|
602
|
+
errors: allIssues.filter((i) => i.severity === "error").length,
|
|
603
|
+
warnings: allIssues.filter((i) => i.severity === "warning").length,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
catch {
|
|
607
|
+
return { fileCount: 0, issues: [], errors: 0, warnings: 0 };
|
|
608
|
+
}
|
|
609
|
+
}
|
|
511
610
|
/**
|
|
512
611
|
* Run a quick validation and return counts (used by push command for pre-push warning)
|
|
513
612
|
* Runs the same checks as the full validate command including cross-file link validation
|
|
@@ -527,6 +626,9 @@ export function runQuickValidation(contextPath) {
|
|
|
527
626
|
// Check for duplicate keys
|
|
528
627
|
const dupeIssues = validateUniqueKeys(files);
|
|
529
628
|
allIssues.push(...dupeIssues);
|
|
629
|
+
// Link coverage check (warn about unlinked blocks)
|
|
630
|
+
const coverageIssues = validateLinkCoverage(files);
|
|
631
|
+
allIssues.push(...coverageIssues);
|
|
530
632
|
return {
|
|
531
633
|
errors: allIssues.filter((i) => i.severity === "error").length,
|
|
532
634
|
warnings: allIssues.filter((i) => i.severity === "warning").length,
|
|
@@ -566,6 +668,9 @@ export async function validateCommand(options) {
|
|
|
566
668
|
// Check for duplicate keys
|
|
567
669
|
const dupeIssues = validateUniqueKeys(files);
|
|
568
670
|
allIssues.push(...dupeIssues);
|
|
671
|
+
// Link coverage check (warn about unlinked blocks)
|
|
672
|
+
const coverageIssues = validateLinkCoverage(files);
|
|
673
|
+
allIssues.push(...coverageIssues);
|
|
569
674
|
spinner.stop();
|
|
570
675
|
// Group issues by severity
|
|
571
676
|
const errors = allIssues.filter((i) => i.severity === "error");
|