ctxinit 0.1.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/LICENSE +21 -0
- package/README.md +484 -0
- package/bin/ctx.js +3 -0
- package/dist/analysis/index.d.ts +2 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +18 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/static-analysis.d.ts +79 -0
- package/dist/analysis/static-analysis.d.ts.map +1 -0
- package/dist/analysis/static-analysis.js +279 -0
- package/dist/analysis/static-analysis.js.map +1 -0
- package/dist/bootstrap/index.d.ts +8 -0
- package/dist/bootstrap/index.d.ts.map +1 -0
- package/dist/bootstrap/index.js +13 -0
- package/dist/bootstrap/index.js.map +1 -0
- package/dist/bootstrap/orchestrator.d.ts +48 -0
- package/dist/bootstrap/orchestrator.d.ts.map +1 -0
- package/dist/bootstrap/orchestrator.js +363 -0
- package/dist/bootstrap/orchestrator.js.map +1 -0
- package/dist/bootstrap/validator.d.ts +25 -0
- package/dist/bootstrap/validator.d.ts.map +1 -0
- package/dist/bootstrap/validator.js +412 -0
- package/dist/bootstrap/validator.js.map +1 -0
- package/dist/build/atomic.d.ts +74 -0
- package/dist/build/atomic.d.ts.map +1 -0
- package/dist/build/atomic.js +235 -0
- package/dist/build/atomic.js.map +1 -0
- package/dist/build/index.d.ts +10 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +26 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/lock.d.ts +102 -0
- package/dist/build/lock.d.ts.map +1 -0
- package/dist/build/lock.js +297 -0
- package/dist/build/lock.js.map +1 -0
- package/dist/build/manifest.d.ts +138 -0
- package/dist/build/manifest.d.ts.map +1 -0
- package/dist/build/manifest.js +269 -0
- package/dist/build/manifest.js.map +1 -0
- package/dist/build/orchestrator.d.ts +103 -0
- package/dist/build/orchestrator.d.ts.map +1 -0
- package/dist/build/orchestrator.js +524 -0
- package/dist/build/orchestrator.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +77 -0
- package/dist/cli/bootstrap.d.ts.map +1 -0
- package/dist/cli/bootstrap.js +527 -0
- package/dist/cli/bootstrap.js.map +1 -0
- package/dist/cli/build.d.ts +32 -0
- package/dist/cli/build.d.ts.map +1 -0
- package/dist/cli/build.js +156 -0
- package/dist/cli/build.js.map +1 -0
- package/dist/cli/diff.d.ts +23 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +226 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/hooks.d.ts +29 -0
- package/dist/cli/hooks.d.ts.map +1 -0
- package/dist/cli/hooks.js +176 -0
- package/dist/cli/hooks.js.map +1 -0
- package/dist/cli/init.d.ts +53 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +254 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/lint.d.ts +46 -0
- package/dist/cli/lint.d.ts.map +1 -0
- package/dist/cli/lint.js +210 -0
- package/dist/cli/lint.js.map +1 -0
- package/dist/cli/migrate.d.ts +28 -0
- package/dist/cli/migrate.d.ts.map +1 -0
- package/dist/cli/migrate.js +350 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/verify.d.ts +21 -0
- package/dist/cli/verify.d.ts.map +1 -0
- package/dist/cli/verify.js +209 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +262 -0
- package/dist/cli.js.map +1 -0
- package/dist/compiler/agents-compiler.d.ts +24 -0
- package/dist/compiler/agents-compiler.d.ts.map +1 -0
- package/dist/compiler/agents-compiler.js +192 -0
- package/dist/compiler/agents-compiler.js.map +1 -0
- package/dist/compiler/base-compiler.d.ts +152 -0
- package/dist/compiler/base-compiler.d.ts.map +1 -0
- package/dist/compiler/base-compiler.js +180 -0
- package/dist/compiler/base-compiler.js.map +1 -0
- package/dist/compiler/claude-compiler.d.ts +24 -0
- package/dist/compiler/claude-compiler.d.ts.map +1 -0
- package/dist/compiler/claude-compiler.js +182 -0
- package/dist/compiler/claude-compiler.js.map +1 -0
- package/dist/compiler/cursor-compiler.d.ts +33 -0
- package/dist/compiler/cursor-compiler.d.ts.map +1 -0
- package/dist/compiler/cursor-compiler.js +136 -0
- package/dist/compiler/cursor-compiler.js.map +1 -0
- package/dist/compiler/index.d.ts +7 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +24 -0
- package/dist/compiler/index.js.map +1 -0
- package/dist/compiler/rule-selector.d.ts +115 -0
- package/dist/compiler/rule-selector.d.ts.map +1 -0
- package/dist/compiler/rule-selector.js +273 -0
- package/dist/compiler/rule-selector.js.map +1 -0
- package/dist/compiler/token-estimator.d.ts +74 -0
- package/dist/compiler/token-estimator.d.ts.map +1 -0
- package/dist/compiler/token-estimator.js +191 -0
- package/dist/compiler/token-estimator.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +18 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +48 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +175 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/git/gitignore.d.ts +59 -0
- package/dist/git/gitignore.d.ts.map +1 -0
- package/dist/git/gitignore.js +268 -0
- package/dist/git/gitignore.js.map +1 -0
- package/dist/git/hooks.d.ts +34 -0
- package/dist/git/hooks.d.ts.map +1 -0
- package/dist/git/hooks.js +129 -0
- package/dist/git/hooks.js.map +1 -0
- package/dist/git/husky.d.ts +52 -0
- package/dist/git/husky.d.ts.map +1 -0
- package/dist/git/husky.js +219 -0
- package/dist/git/husky.js.map +1 -0
- package/dist/git/index.d.ts +9 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +15 -0
- package/dist/git/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/base-provider.d.ts +43 -0
- package/dist/llm/base-provider.d.ts.map +1 -0
- package/dist/llm/base-provider.js +91 -0
- package/dist/llm/base-provider.js.map +1 -0
- package/dist/llm/index.d.ts +17 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +36 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/prompts/bootstrap-prompt.d.ts +27 -0
- package/dist/llm/prompts/bootstrap-prompt.d.ts.map +1 -0
- package/dist/llm/prompts/bootstrap-prompt.js +278 -0
- package/dist/llm/prompts/bootstrap-prompt.js.map +1 -0
- package/dist/llm/prompts/index.d.ts +5 -0
- package/dist/llm/prompts/index.d.ts.map +1 -0
- package/dist/llm/prompts/index.js +11 -0
- package/dist/llm/prompts/index.js.map +1 -0
- package/dist/llm/provider-factory.d.ts +27 -0
- package/dist/llm/provider-factory.d.ts.map +1 -0
- package/dist/llm/provider-factory.js +213 -0
- package/dist/llm/provider-factory.js.map +1 -0
- package/dist/llm/providers/claude-api.d.ts +21 -0
- package/dist/llm/providers/claude-api.d.ts.map +1 -0
- package/dist/llm/providers/claude-api.js +110 -0
- package/dist/llm/providers/claude-api.js.map +1 -0
- package/dist/llm/providers/claude-code.d.ts +21 -0
- package/dist/llm/providers/claude-code.d.ts.map +1 -0
- package/dist/llm/providers/claude-code.js +120 -0
- package/dist/llm/providers/claude-code.js.map +1 -0
- package/dist/llm/providers/codex-cli.d.ts +25 -0
- package/dist/llm/providers/codex-cli.d.ts.map +1 -0
- package/dist/llm/providers/codex-cli.js +129 -0
- package/dist/llm/providers/codex-cli.js.map +1 -0
- package/dist/llm/providers/cursor-cli.d.ts +24 -0
- package/dist/llm/providers/cursor-cli.d.ts.map +1 -0
- package/dist/llm/providers/cursor-cli.js +106 -0
- package/dist/llm/providers/cursor-cli.js.map +1 -0
- package/dist/llm/providers/gemini-api.d.ts +20 -0
- package/dist/llm/providers/gemini-api.d.ts.map +1 -0
- package/dist/llm/providers/gemini-api.js +121 -0
- package/dist/llm/providers/gemini-api.js.map +1 -0
- package/dist/llm/providers/gemini-cli.d.ts +20 -0
- package/dist/llm/providers/gemini-cli.d.ts.map +1 -0
- package/dist/llm/providers/gemini-cli.js +109 -0
- package/dist/llm/providers/gemini-cli.js.map +1 -0
- package/dist/llm/providers/interactive.d.ts +42 -0
- package/dist/llm/providers/interactive.d.ts.map +1 -0
- package/dist/llm/providers/interactive.js +200 -0
- package/dist/llm/providers/interactive.js.map +1 -0
- package/dist/llm/providers/openai-api.d.ts +21 -0
- package/dist/llm/providers/openai-api.d.ts.map +1 -0
- package/dist/llm/providers/openai-api.js +107 -0
- package/dist/llm/providers/openai-api.js.map +1 -0
- package/dist/llm/types.d.ts +128 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +8 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/parser/index.d.ts +3 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +19 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/path-security.d.ts +40 -0
- package/dist/parser/path-security.d.ts.map +1 -0
- package/dist/parser/path-security.js +183 -0
- package/dist/parser/path-security.js.map +1 -0
- package/dist/parser/rule-parser.d.ts +50 -0
- package/dist/parser/rule-parser.d.ts.map +1 -0
- package/dist/parser/rule-parser.js +203 -0
- package/dist/parser/rule-parser.js.map +1 -0
- package/dist/schemas/config.d.ts +202 -0
- package/dist/schemas/config.d.ts.map +1 -0
- package/dist/schemas/config.js +96 -0
- package/dist/schemas/config.js.map +1 -0
- package/dist/schemas/index.d.ts +3 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +19 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/rule.d.ts +67 -0
- package/dist/schemas/rule.d.ts.map +1 -0
- package/dist/schemas/rule.js +44 -0
- package/dist/schemas/rule.js.map +1 -0
- package/package.json +69 -0
- package/templates/architecture.md +35 -0
- package/templates/bootstrap-prompt.md +242 -0
- package/templates/config.yaml +25 -0
- package/templates/project.md +44 -0
- package/templates/rules/example.md +36 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.findDuplicateIds = findDuplicateIds;
|
|
40
|
+
exports.findDeadLinks = findDeadLinks;
|
|
41
|
+
exports.findGhostRules = findGhostRules;
|
|
42
|
+
exports.checkTokenLimits = checkTokenLimits;
|
|
43
|
+
exports.findCircularReferences = findCircularReferences;
|
|
44
|
+
exports.validateRule = validateRule;
|
|
45
|
+
exports.analyzeRules = analyzeRules;
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
49
|
+
/**
|
|
50
|
+
* Analyze rules for duplicate IDs
|
|
51
|
+
*
|
|
52
|
+
* @param rules - Parsed rules to analyze
|
|
53
|
+
* @returns Array of duplicate ID errors
|
|
54
|
+
*/
|
|
55
|
+
function findDuplicateIds(rules) {
|
|
56
|
+
const errors = [];
|
|
57
|
+
const idMap = new Map();
|
|
58
|
+
for (const rule of rules) {
|
|
59
|
+
const id = rule.frontmatter.id;
|
|
60
|
+
const paths = idMap.get(id) || [];
|
|
61
|
+
paths.push(rule.path);
|
|
62
|
+
idMap.set(id, paths);
|
|
63
|
+
}
|
|
64
|
+
for (const [id, paths] of idMap) {
|
|
65
|
+
if (paths.length > 1) {
|
|
66
|
+
for (const rulePath of paths) {
|
|
67
|
+
errors.push({
|
|
68
|
+
type: 'duplicate_id',
|
|
69
|
+
message: `Duplicate rule ID '${id}' found in: ${paths.filter(p => p !== rulePath).join(', ')}`,
|
|
70
|
+
path: rulePath,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return errors;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Find dead links in markdown content
|
|
79
|
+
*
|
|
80
|
+
* @param rule - Parsed rule to analyze
|
|
81
|
+
* @param projectRoot - Project root for resolving relative links
|
|
82
|
+
* @returns Array of dead link errors
|
|
83
|
+
*/
|
|
84
|
+
function findDeadLinks(rule, projectRoot) {
|
|
85
|
+
const errors = [];
|
|
86
|
+
// Match markdown links: [text](path)
|
|
87
|
+
const linkPattern = /\[([^\]]*)\]\(([^)]+)\)/g;
|
|
88
|
+
let match;
|
|
89
|
+
while ((match = linkPattern.exec(rule.content)) !== null) {
|
|
90
|
+
const linkPath = match[2];
|
|
91
|
+
// Skip external URLs and anchors
|
|
92
|
+
if (linkPath.startsWith('http://') ||
|
|
93
|
+
linkPath.startsWith('https://') ||
|
|
94
|
+
linkPath.startsWith('#') ||
|
|
95
|
+
linkPath.startsWith('mailto:')) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// Handle paths relative to the rule file
|
|
99
|
+
const ruleDir = path.dirname(rule.absolutePath);
|
|
100
|
+
const resolvedPath = linkPath.startsWith('/')
|
|
101
|
+
? path.join(projectRoot, linkPath)
|
|
102
|
+
: path.join(ruleDir, linkPath);
|
|
103
|
+
// Remove anchor from path for file existence check
|
|
104
|
+
const pathWithoutAnchor = resolvedPath.split('#')[0];
|
|
105
|
+
if (!fs.existsSync(pathWithoutAnchor)) {
|
|
106
|
+
const lineNumber = getLineNumber(rule.content, match.index);
|
|
107
|
+
errors.push({
|
|
108
|
+
type: 'dead_link',
|
|
109
|
+
message: `Dead link found: ${linkPath}`,
|
|
110
|
+
path: rule.path,
|
|
111
|
+
line: lineNumber,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return errors;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Find ghost rules (globs that match no files)
|
|
119
|
+
*
|
|
120
|
+
* @param rule - Parsed rule to analyze
|
|
121
|
+
* @param projectRoot - Project root for glob matching
|
|
122
|
+
* @returns Array of ghost rule warnings
|
|
123
|
+
*/
|
|
124
|
+
function findGhostRules(rule, projectRoot) {
|
|
125
|
+
const warnings = [];
|
|
126
|
+
// Skip rules with always_apply flag
|
|
127
|
+
if (rule.frontmatter.always_apply) {
|
|
128
|
+
return warnings;
|
|
129
|
+
}
|
|
130
|
+
for (const glob of rule.effectiveGlobs) {
|
|
131
|
+
try {
|
|
132
|
+
const matches = fast_glob_1.default.sync(glob, {
|
|
133
|
+
cwd: projectRoot,
|
|
134
|
+
onlyFiles: true,
|
|
135
|
+
ignore: ['node_modules/**', '.git/**', 'dist/**', 'coverage/**'],
|
|
136
|
+
});
|
|
137
|
+
if (matches.length === 0) {
|
|
138
|
+
warnings.push({
|
|
139
|
+
type: 'ghost_rule',
|
|
140
|
+
message: `Glob pattern '${glob}' matches no files`,
|
|
141
|
+
path: rule.path,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Invalid glob pattern - will be caught elsewhere
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return warnings;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check for potential token limit issues
|
|
153
|
+
*
|
|
154
|
+
* @param rules - Parsed rules to analyze
|
|
155
|
+
* @param config - Configuration with token limits
|
|
156
|
+
* @returns Array of token limit warnings
|
|
157
|
+
*/
|
|
158
|
+
function checkTokenLimits(rules, config) {
|
|
159
|
+
const warnings = [];
|
|
160
|
+
if (!config?.compile?.claude?.max_tokens) {
|
|
161
|
+
return warnings;
|
|
162
|
+
}
|
|
163
|
+
const maxTokens = config.compile.claude.max_tokens;
|
|
164
|
+
// Rough token estimation: ~4 chars per token for English text
|
|
165
|
+
const totalChars = rules.reduce((sum, rule) => {
|
|
166
|
+
return sum + rule.content.length + JSON.stringify(rule.frontmatter).length;
|
|
167
|
+
}, 0);
|
|
168
|
+
const estimatedTokens = Math.ceil(totalChars / 4);
|
|
169
|
+
if (estimatedTokens > maxTokens * 0.9) {
|
|
170
|
+
warnings.push({
|
|
171
|
+
type: 'token_limit',
|
|
172
|
+
message: `Estimated tokens (${estimatedTokens}) approaching limit (${maxTokens}). Consider reducing content or increasing limit.`,
|
|
173
|
+
path: 'all rules',
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return warnings;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Detect circular references in rule imports
|
|
180
|
+
*
|
|
181
|
+
* @param rules - Parsed rules to analyze
|
|
182
|
+
* @returns Array of circular reference errors
|
|
183
|
+
*/
|
|
184
|
+
function findCircularReferences(rules) {
|
|
185
|
+
const errors = [];
|
|
186
|
+
const ruleMap = new Map();
|
|
187
|
+
// Build a map of rule IDs to rules
|
|
188
|
+
for (const rule of rules) {
|
|
189
|
+
ruleMap.set(rule.frontmatter.id, rule);
|
|
190
|
+
}
|
|
191
|
+
// Find @import or @include references in content
|
|
192
|
+
const importPattern = /@(?:import|include)\s+["']([^"']+)["']/g;
|
|
193
|
+
for (const rule of rules) {
|
|
194
|
+
const visited = new Set();
|
|
195
|
+
const stack = [rule.frontmatter.id];
|
|
196
|
+
while (stack.length > 0) {
|
|
197
|
+
const currentId = stack.pop();
|
|
198
|
+
if (visited.has(currentId)) {
|
|
199
|
+
errors.push({
|
|
200
|
+
type: 'circular_reference',
|
|
201
|
+
message: `Circular reference detected: ${Array.from(visited).join(' -> ')} -> ${currentId}`,
|
|
202
|
+
path: rule.path,
|
|
203
|
+
});
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
visited.add(currentId);
|
|
207
|
+
const currentRule = ruleMap.get(currentId);
|
|
208
|
+
if (currentRule) {
|
|
209
|
+
let match;
|
|
210
|
+
while ((match = importPattern.exec(currentRule.content)) !== null) {
|
|
211
|
+
const importedId = match[1];
|
|
212
|
+
if (ruleMap.has(importedId)) {
|
|
213
|
+
stack.push(importedId);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Reset regex lastIndex for next iteration
|
|
217
|
+
importPattern.lastIndex = 0;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return errors;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Validate a single rule
|
|
225
|
+
*
|
|
226
|
+
* @param rule - Parsed rule to validate
|
|
227
|
+
* @param options - Analysis options
|
|
228
|
+
* @returns Validation result for the rule
|
|
229
|
+
*/
|
|
230
|
+
function validateRule(rule, options) {
|
|
231
|
+
const errors = [];
|
|
232
|
+
const warnings = [];
|
|
233
|
+
// Check for dead links
|
|
234
|
+
errors.push(...findDeadLinks(rule, options.projectRoot));
|
|
235
|
+
// Check for ghost rules
|
|
236
|
+
warnings.push(...findGhostRules(rule, options.projectRoot));
|
|
237
|
+
return {
|
|
238
|
+
valid: errors.length === 0,
|
|
239
|
+
errors,
|
|
240
|
+
warnings,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Run complete static analysis on all rules
|
|
245
|
+
*
|
|
246
|
+
* @param rules - Parsed rules to analyze
|
|
247
|
+
* @param options - Analysis options
|
|
248
|
+
* @returns Complete analysis result
|
|
249
|
+
*/
|
|
250
|
+
function analyzeRules(rules, options) {
|
|
251
|
+
const errors = [];
|
|
252
|
+
const warnings = [];
|
|
253
|
+
// Check for duplicate IDs
|
|
254
|
+
errors.push(...findDuplicateIds(rules));
|
|
255
|
+
// Check for circular references
|
|
256
|
+
errors.push(...findCircularReferences(rules));
|
|
257
|
+
// Validate each rule individually
|
|
258
|
+
for (const rule of rules) {
|
|
259
|
+
const result = validateRule(rule, options);
|
|
260
|
+
errors.push(...result.errors);
|
|
261
|
+
warnings.push(...result.warnings);
|
|
262
|
+
}
|
|
263
|
+
// Check token limits
|
|
264
|
+
warnings.push(...checkTokenLimits(rules, options.config));
|
|
265
|
+
return {
|
|
266
|
+
valid: errors.length === 0,
|
|
267
|
+
errors,
|
|
268
|
+
warnings,
|
|
269
|
+
rulesAnalyzed: rules.length,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Get line number from string index
|
|
274
|
+
*/
|
|
275
|
+
function getLineNumber(content, index) {
|
|
276
|
+
const lines = content.slice(0, index).split('\n');
|
|
277
|
+
return lines.length;
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=static-analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-analysis.js","sourceRoot":"","sources":["../../src/analysis/static-analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootstrap Module
|
|
3
|
+
*
|
|
4
|
+
* Enhanced bootstrap flow for generating and validating AI context files.
|
|
5
|
+
*/
|
|
6
|
+
export { runEnhancedBootstrap, BootstrapOptions, BootstrapResult, } from './orchestrator';
|
|
7
|
+
export { validateBootstrapOutput, ValidationResult, } from './validator';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bootstrap/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Bootstrap Module
|
|
4
|
+
*
|
|
5
|
+
* Enhanced bootstrap flow for generating and validating AI context files.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.validateBootstrapOutput = exports.runEnhancedBootstrap = void 0;
|
|
9
|
+
var orchestrator_1 = require("./orchestrator");
|
|
10
|
+
Object.defineProperty(exports, "runEnhancedBootstrap", { enumerable: true, get: function () { return orchestrator_1.runEnhancedBootstrap; } });
|
|
11
|
+
var validator_1 = require("./validator");
|
|
12
|
+
Object.defineProperty(exports, "validateBootstrapOutput", { enumerable: true, get: function () { return validator_1.validateBootstrapOutput; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bootstrap/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,+CAIwB;AAHtB,oHAAA,oBAAoB,OAAA;AAKtB,yCAGqB;AAFnB,oHAAA,uBAAuB,OAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootstrap Orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Coordinates the enhanced bootstrap flow:
|
|
5
|
+
* 1. Analyze codebase
|
|
6
|
+
* 2. Load existing .context files (preserve user edits)
|
|
7
|
+
* 3. Invoke LLM to generate/enhance context
|
|
8
|
+
* 4. Validate output (links, references, best practices)
|
|
9
|
+
* 5. Write files to .context/
|
|
10
|
+
* 6. Optionally run build to generate outputs
|
|
11
|
+
*/
|
|
12
|
+
import { LLMProviderType, BootstrapLLMOutput } from '../llm';
|
|
13
|
+
import { CodebaseAnalysis } from '../cli/bootstrap';
|
|
14
|
+
import { ValidationResult } from './validator';
|
|
15
|
+
/**
|
|
16
|
+
* Bootstrap options
|
|
17
|
+
*/
|
|
18
|
+
export interface BootstrapOptions {
|
|
19
|
+
/** LLM provider to use (auto-detect if not specified) */
|
|
20
|
+
provider?: LLMProviderType;
|
|
21
|
+
/** Skip LLM invocation, just analyze */
|
|
22
|
+
analyzeOnly?: boolean;
|
|
23
|
+
/** Skip validation */
|
|
24
|
+
skipValidation?: boolean;
|
|
25
|
+
/** Auto-run build after bootstrap */
|
|
26
|
+
autoBuild?: boolean;
|
|
27
|
+
/** Verbose output */
|
|
28
|
+
verbose?: boolean;
|
|
29
|
+
/** Dry run - don't write files */
|
|
30
|
+
dryRun?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Bootstrap result
|
|
34
|
+
*/
|
|
35
|
+
export interface BootstrapResult {
|
|
36
|
+
success: boolean;
|
|
37
|
+
analysis: CodebaseAnalysis;
|
|
38
|
+
llmOutput?: BootstrapLLMOutput;
|
|
39
|
+
validation?: ValidationResult;
|
|
40
|
+
filesWritten: string[];
|
|
41
|
+
errors: string[];
|
|
42
|
+
warnings: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Run the enhanced bootstrap flow
|
|
46
|
+
*/
|
|
47
|
+
export declare function runEnhancedBootstrap(projectRoot: string, options?: BootstrapOptions): Promise<BootstrapResult>;
|
|
48
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/bootstrap/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EAEL,eAAe,EACf,kBAAkB,EAInB,MAAM,QAAQ,CAAC;AAKhB,OAAO,EAEL,gBAAgB,EAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAA2B,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGxE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,wCAAwC;IACxC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sBAAsB;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kCAAkC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAWD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CA2N1B"}
|