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.
@@ -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 repoRoot = process.cwd();
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)(repoRoot);
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
- async function findThreadlines(repoRoot) {
43
- const expertsDir = path.join(repoRoot, 'threadlines');
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), repoRoot);
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
- async function validateThreadline(filePath, repoRoot) {
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(repoRoot, contextFile);
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(repoRoot, filePath)
138
+ filePath: path.relative(gitRoot, filePath)
127
139
  };
128
140
  return { valid: true, threadline };
129
141
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "threadlines",
3
- "version": "0.1.39",
3
+ "version": "0.1.40",
4
4
  "description": "Threadline CLI - AI-powered linter based on your natural language documentation",
5
5
  "main": "dist/index.js",
6
6
  "bin": {