threadlines 0.1.39 → 0.1.40
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/commands/check.js +19 -2
- package/dist/validators/experts.js +19 -7
- package/package.json +1 -1
package/dist/commands/check.js
CHANGED
|
@@ -50,13 +50,30 @@ const git_diff_executor_1 = require("../utils/git-diff-executor");
|
|
|
50
50
|
const fs = __importStar(require("fs"));
|
|
51
51
|
const path = __importStar(require("path"));
|
|
52
52
|
const chalk_1 = __importDefault(require("chalk"));
|
|
53
|
+
const simple_git_1 = __importDefault(require("simple-git"));
|
|
53
54
|
// Get CLI version from package.json
|
|
54
55
|
const packageJsonPath = path.join(__dirname, '../../package.json');
|
|
55
56
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
56
57
|
const CLI_VERSION = packageJson.version;
|
|
57
58
|
async function checkCommand(options) {
|
|
58
|
-
const
|
|
59
|
+
const cwd = process.cwd();
|
|
60
|
+
const repoRoot = cwd; // Keep for backward compatibility with rest of function
|
|
59
61
|
console.log(chalk_1.default.blue(`🔍 Threadline CLI v${CLI_VERSION}: Checking code against your threadlines...\n`));
|
|
62
|
+
// Get git root for consistent file paths across monorepo
|
|
63
|
+
const git = (0, simple_git_1.default)(cwd);
|
|
64
|
+
let gitRoot;
|
|
65
|
+
try {
|
|
66
|
+
const isRepo = await git.checkIsRepo();
|
|
67
|
+
if (!isRepo) {
|
|
68
|
+
console.error(chalk_1.default.red('❌ Error: Not a git repository. Threadline requires a git repository.'));
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
gitRoot = (await git.revparse(['--show-toplevel'])).trim();
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
console.error(chalk_1.default.red('❌ Error: Failed to get git root. Make sure you are in a git repository.'));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
60
77
|
// Pre-flight check: Validate ALL required environment variables at once
|
|
61
78
|
const apiKey = (0, config_1.getThreadlineApiKey)();
|
|
62
79
|
const account = (0, config_1.getThreadlineAccount)();
|
|
@@ -96,7 +113,7 @@ async function checkCommand(options) {
|
|
|
96
113
|
try {
|
|
97
114
|
// 1. Find and validate threadlines
|
|
98
115
|
console.log(chalk_1.default.gray('📋 Finding threadlines...'));
|
|
99
|
-
const threadlines = await (0, experts_1.findThreadlines)(
|
|
116
|
+
const threadlines = await (0, experts_1.findThreadlines)(cwd, gitRoot);
|
|
100
117
|
console.log(chalk_1.default.green(`✓ Found ${threadlines.length} threadline(s)\n`));
|
|
101
118
|
if (threadlines.length === 0) {
|
|
102
119
|
console.log(chalk_1.default.yellow('⚠️ No valid threadlines found.'));
|
|
@@ -39,8 +39,13 @@ const fs = __importStar(require("fs"));
|
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
40
|
const yaml = __importStar(require("js-yaml"));
|
|
41
41
|
const REQUIRED_FIELDS = ['id', 'version', 'patterns'];
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Find and validate all threadlines in the threadlines folder.
|
|
44
|
+
* @param searchRoot - Where to look for threadlines (usually cwd)
|
|
45
|
+
* @param gitRoot - Git repository root (for consistent filePath across monorepo)
|
|
46
|
+
*/
|
|
47
|
+
async function findThreadlines(searchRoot, gitRoot) {
|
|
48
|
+
const expertsDir = path.join(searchRoot, 'threadlines');
|
|
44
49
|
if (!fs.existsSync(expertsDir)) {
|
|
45
50
|
throw new Error('No /threadlines folder found. Run `npx threadlines init` to create your first threadline.');
|
|
46
51
|
}
|
|
@@ -51,7 +56,7 @@ async function findThreadlines(repoRoot) {
|
|
|
51
56
|
}
|
|
52
57
|
const threadlines = [];
|
|
53
58
|
for (const file of expertFiles) {
|
|
54
|
-
const result = await validateThreadline(path.join(expertsDir, file),
|
|
59
|
+
const result = await validateThreadline(path.join(expertsDir, file), searchRoot, gitRoot);
|
|
55
60
|
if (result.valid && result.threadline) {
|
|
56
61
|
threadlines.push(result.threadline);
|
|
57
62
|
}
|
|
@@ -61,7 +66,13 @@ async function findThreadlines(repoRoot) {
|
|
|
61
66
|
}
|
|
62
67
|
return threadlines;
|
|
63
68
|
}
|
|
64
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Validate a threadline file and extract its configuration.
|
|
71
|
+
* @param filePath - Absolute path to the threadline file
|
|
72
|
+
* @param searchRoot - Where threadlines were searched from (for context file resolution)
|
|
73
|
+
* @param gitRoot - Git repository root (for consistent filePath in database)
|
|
74
|
+
*/
|
|
75
|
+
async function validateThreadline(filePath, searchRoot, gitRoot) {
|
|
65
76
|
try {
|
|
66
77
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
67
78
|
// Parse YAML frontmatter
|
|
@@ -94,10 +105,10 @@ async function validateThreadline(filePath, repoRoot) {
|
|
|
94
105
|
errors.push('context_files must be an array');
|
|
95
106
|
}
|
|
96
107
|
else {
|
|
97
|
-
// Check if context files exist
|
|
108
|
+
// Check if context files exist (relative to searchRoot)
|
|
98
109
|
for (const contextFile of frontmatter.context_files) {
|
|
99
110
|
if (typeof contextFile === 'string') {
|
|
100
|
-
const fullPath = path.join(
|
|
111
|
+
const fullPath = path.join(searchRoot, contextFile);
|
|
101
112
|
if (!fs.existsSync(fullPath)) {
|
|
102
113
|
errors.push(`Context file not found: ${contextFile}`);
|
|
103
114
|
}
|
|
@@ -117,13 +128,14 @@ async function validateThreadline(filePath, repoRoot) {
|
|
|
117
128
|
return { valid: false, errors };
|
|
118
129
|
}
|
|
119
130
|
// Type assertions for required fields (already validated above)
|
|
131
|
+
// filePath is relative to gitRoot for consistent identification across monorepo
|
|
120
132
|
const threadline = {
|
|
121
133
|
id: frontmatter.id,
|
|
122
134
|
version: frontmatter.version,
|
|
123
135
|
patterns: frontmatter.patterns,
|
|
124
136
|
contextFiles: (Array.isArray(frontmatter.context_files) ? frontmatter.context_files.filter((f) => typeof f === 'string') : []),
|
|
125
137
|
content: body,
|
|
126
|
-
filePath: path.relative(
|
|
138
|
+
filePath: path.relative(gitRoot, filePath)
|
|
127
139
|
};
|
|
128
140
|
return { valid: true, threadline };
|
|
129
141
|
}
|