threadlines 0.1.27 → 0.1.29
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/api/client.js +6 -4
- package/dist/commands/check.js +3 -6
- package/dist/commands/init.js +2 -1
- package/dist/git/diff.js +14 -7
- package/dist/git/file.js +5 -4
- package/dist/git/github-diff.js +2 -1
- package/dist/git/repo.js +16 -13
- package/dist/utils/git-diff-executor.js +1 -1
- package/dist/validators/experts.js +11 -7
- package/package.json +13 -3
package/dist/api/client.js
CHANGED
|
@@ -21,14 +21,16 @@ class ReviewAPIClient {
|
|
|
21
21
|
return response.data;
|
|
22
22
|
}
|
|
23
23
|
catch (error) {
|
|
24
|
-
if (error
|
|
25
|
-
|
|
24
|
+
if (error && typeof error === 'object' && 'response' in error) {
|
|
25
|
+
const axiosError = error;
|
|
26
|
+
throw new Error(`API error: ${axiosError.response.status} - ${axiosError.response.data?.message || axiosError.message || 'Unknown error'}`);
|
|
26
27
|
}
|
|
27
|
-
else if (error
|
|
28
|
+
else if (error && typeof error === 'object' && 'request' in error) {
|
|
28
29
|
throw new Error(`Network error: Could not reach Threadline server at ${this.client.defaults.baseURL}`);
|
|
29
30
|
}
|
|
30
31
|
else {
|
|
31
|
-
|
|
32
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
33
|
+
throw new Error(`Request error: ${errorMessage}`);
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
}
|
package/dist/commands/check.js
CHANGED
|
@@ -59,11 +59,8 @@ async function checkCommand(options) {
|
|
|
59
59
|
// Pre-flight check: Validate ALL required environment variables at once
|
|
60
60
|
const apiKey = (0, config_1.getThreadlineApiKey)();
|
|
61
61
|
const account = (0, config_1.getThreadlineAccount)();
|
|
62
|
-
// Debug: Show what we got (masked for security)
|
|
63
|
-
console.log(chalk_1.default.gray(` [Debug] THREADLINE_API_KEY: ${apiKey ? `"${apiKey.substring(0, 4)}..."` : 'undefined'}`));
|
|
64
|
-
console.log(chalk_1.default.gray(` [Debug] THREADLINE_ACCOUNT: ${account ? `"${account.substring(0, 4)}..."` : 'undefined'}`));
|
|
65
62
|
const missingVars = [];
|
|
66
|
-
// Check for undefined, empty string, or literal unexpanded variable
|
|
63
|
+
// Check for undefined, empty string, or literal unexpanded variable (GitLab keeps "$VAR" literal)
|
|
67
64
|
if (!apiKey || apiKey.startsWith('$'))
|
|
68
65
|
missingVars.push('THREADLINE_API_KEY');
|
|
69
66
|
if (!account || account.startsWith('$'))
|
|
@@ -187,7 +184,6 @@ async function checkCommand(options) {
|
|
|
187
184
|
if (gitDiff.changedFiles.length === 0) {
|
|
188
185
|
console.error(chalk_1.default.red('❌ Error: No changes detected.'));
|
|
189
186
|
console.error(chalk_1.default.red(' Threadline check requires code changes to analyze.'));
|
|
190
|
-
console.error(chalk_1.default.red(' This may indicate a problem with git diff detection.'));
|
|
191
187
|
process.exit(1);
|
|
192
188
|
}
|
|
193
189
|
// Check for zero diff (files changed but no actual code changes)
|
|
@@ -249,7 +245,8 @@ async function checkCommand(options) {
|
|
|
249
245
|
process.exit(hasAttention ? 1 : 0);
|
|
250
246
|
}
|
|
251
247
|
catch (error) {
|
|
252
|
-
|
|
248
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
249
|
+
console.error(chalk_1.default.red(`\n❌ Error: ${errorMessage}`));
|
|
253
250
|
process.exit(1);
|
|
254
251
|
}
|
|
255
252
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -108,7 +108,8 @@ async function initCommand() {
|
|
|
108
108
|
console.log(chalk_1.default.gray(' (Use npx --yes threadlines check in non-interactive environments)'));
|
|
109
109
|
}
|
|
110
110
|
catch (error) {
|
|
111
|
-
|
|
111
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
112
|
+
console.error(chalk_1.default.red(`\n❌ Error: ${errorMessage}`));
|
|
112
113
|
process.exit(1);
|
|
113
114
|
}
|
|
114
115
|
}
|
package/dist/git/diff.js
CHANGED
|
@@ -45,7 +45,8 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
45
45
|
}
|
|
46
46
|
catch (error) {
|
|
47
47
|
// If no previous commit, return empty (first commit)
|
|
48
|
-
|
|
48
|
+
const errorMessage = error instanceof Error ? error.message : 'HEAD~1 does not exist';
|
|
49
|
+
console.log(`[DEBUG] No previous commit found (first commit or error): ${errorMessage}`);
|
|
49
50
|
return {
|
|
50
51
|
diff: '',
|
|
51
52
|
changedFiles: []
|
|
@@ -88,7 +89,8 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
catch (error) {
|
|
91
|
-
|
|
92
|
+
const errorMessage = error instanceof Error ? error.message : 'no upstream configured';
|
|
93
|
+
console.log(`[DEBUG] Upstream tracking branch not set for '${branchName}': ${errorMessage}`);
|
|
92
94
|
}
|
|
93
95
|
// Strategy 2: Try default branch from origin/HEAD (reliable if configured)
|
|
94
96
|
try {
|
|
@@ -117,7 +119,8 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
catch (error) {
|
|
120
|
-
|
|
122
|
+
const errorMessage = error instanceof Error ? error.message : 'not found';
|
|
123
|
+
console.log(`[DEBUG] Default branch (refs/remotes/origin/HEAD) not configured: ${errorMessage}`);
|
|
121
124
|
}
|
|
122
125
|
// Strategy 3: Try common branch names by checking remote refs first, then local branches
|
|
123
126
|
// This works reliably in CI with fetch-depth: 0, and also works locally
|
|
@@ -146,7 +149,8 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
146
149
|
}
|
|
147
150
|
}
|
|
148
151
|
catch (error) {
|
|
149
|
-
|
|
152
|
+
const errorMessage = error instanceof Error ? error.message : 'does not exist';
|
|
153
|
+
console.log(`[DEBUG] Remote branch 'origin/${candidate}' not found: ${errorMessage}`);
|
|
150
154
|
// If remote doesn't exist, also try local branch (especially for CI like Vercel)
|
|
151
155
|
try {
|
|
152
156
|
await git.revparse([candidate]);
|
|
@@ -154,7 +158,8 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
154
158
|
return candidate;
|
|
155
159
|
}
|
|
156
160
|
catch (localError) {
|
|
157
|
-
|
|
161
|
+
const localErrorMessage = localError instanceof Error ? localError.message : 'does not exist';
|
|
162
|
+
console.log(`[DEBUG] Local branch '${candidate}' also not found: ${localErrorMessage}`);
|
|
158
163
|
// Continue to next candidate
|
|
159
164
|
}
|
|
160
165
|
}
|
|
@@ -187,7 +192,7 @@ async function getCommitMessage(repoRoot, sha) {
|
|
|
187
192
|
const message = await git.show([sha, '--format=%B', '--no-patch']);
|
|
188
193
|
return message.trim() || null;
|
|
189
194
|
}
|
|
190
|
-
catch
|
|
195
|
+
catch {
|
|
191
196
|
// Commit not found or invalid
|
|
192
197
|
return null;
|
|
193
198
|
}
|
|
@@ -225,7 +230,9 @@ async function getCommitDiff(repoRoot, sha) {
|
|
|
225
230
|
changedFiles = diffSummary.files.map(f => f.file);
|
|
226
231
|
}
|
|
227
232
|
catch (diffError) {
|
|
228
|
-
|
|
233
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
234
|
+
const diffErrorMessage = diffError instanceof Error ? diffError.message : 'Unknown error';
|
|
235
|
+
throw new Error(`Commit ${sha} not found or invalid: ${errorMessage || diffErrorMessage}`);
|
|
229
236
|
}
|
|
230
237
|
}
|
|
231
238
|
return {
|
package/dist/git/file.js
CHANGED
|
@@ -57,7 +57,7 @@ async function getFileContent(repoRoot, filePath) {
|
|
|
57
57
|
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
58
58
|
// Create artificial diff (all lines as additions)
|
|
59
59
|
const lines = content.split('\n');
|
|
60
|
-
const diff = lines.map((line
|
|
60
|
+
const diff = lines.map((line) => `+${line}`).join('\n');
|
|
61
61
|
// Add diff header
|
|
62
62
|
const diffHeader = `--- /dev/null\n+++ ${filePath}\n@@ -0,0 +1,${lines.length} @@\n`;
|
|
63
63
|
const fullDiff = diffHeader + diff;
|
|
@@ -108,14 +108,15 @@ async function getFolderContent(repoRoot, folderPath) {
|
|
|
108
108
|
const content = fs.readFileSync(path.resolve(repoRoot, filePath), 'utf-8');
|
|
109
109
|
const lines = content.split('\n');
|
|
110
110
|
// Create artificial diff for this file
|
|
111
|
-
const fileDiff = lines.map((line
|
|
111
|
+
const fileDiff = lines.map((line) => `+${line}`).join('\n');
|
|
112
112
|
const diffHeader = `--- /dev/null\n+++ ${filePath}\n@@ -0,0 +1,${lines.length} @@\n`;
|
|
113
113
|
diffs.push(diffHeader + fileDiff);
|
|
114
114
|
changedFiles.push(filePath);
|
|
115
115
|
}
|
|
116
116
|
catch (error) {
|
|
117
117
|
// Skip files that can't be read (permissions, etc.)
|
|
118
|
-
|
|
118
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
119
|
+
console.warn(`Warning: Could not read file '${filePath}': ${errorMessage}`);
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
return {
|
|
@@ -147,7 +148,7 @@ async function getMultipleFilesContent(repoRoot, filePaths) {
|
|
|
147
148
|
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
148
149
|
const lines = content.split('\n');
|
|
149
150
|
// Create artificial diff for this file
|
|
150
|
-
const fileDiff = lines.map((line
|
|
151
|
+
const fileDiff = lines.map((line) => `+${line}`).join('\n');
|
|
151
152
|
const diffHeader = `--- /dev/null\n+++ ${filePath}\n@@ -0,0 +1,${lines.length} @@\n`;
|
|
152
153
|
diffs.push(diffHeader + fileDiff);
|
|
153
154
|
changedFiles.push(filePath);
|
package/dist/git/github-diff.js
CHANGED
|
@@ -87,8 +87,9 @@ async function getGitHubDiff(repoRoot) {
|
|
|
87
87
|
}
|
|
88
88
|
catch (error) {
|
|
89
89
|
// If we can't get the diff (e.g., first commit on branch), throw a clear error
|
|
90
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
90
91
|
throw new Error(`Could not get diff for default branch '${defaultBranch}'. ` +
|
|
91
|
-
`This might be the first commit on the branch. Error: ${
|
|
92
|
+
`This might be the first commit on the branch. Error: ${errorMessage}`);
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
// Scenario 3: Feature Branch Push
|
package/dist/git/repo.js
CHANGED
|
@@ -54,7 +54,7 @@ const path = __importStar(require("path"));
|
|
|
54
54
|
* Uses GITHUB_REPOSITORY environment variable (format: "owner/repo").
|
|
55
55
|
* This is the ONLY method for GitHub - no fallbacks, no alternatives.
|
|
56
56
|
*/
|
|
57
|
-
async function getGitHubRepoName(
|
|
57
|
+
async function getGitHubRepoName(_repoRoot) {
|
|
58
58
|
const githubRepo = process.env.GITHUB_REPOSITORY;
|
|
59
59
|
if (!githubRepo) {
|
|
60
60
|
throw new Error('GitHub Actions: GITHUB_REPOSITORY environment variable is not set. ' +
|
|
@@ -69,7 +69,7 @@ async function getGitHubRepoName(repoRoot) {
|
|
|
69
69
|
* Uses VERCEL_GIT_REPO_OWNER and VERCEL_GIT_REPO_SLUG environment variables.
|
|
70
70
|
* This is the ONLY method for Vercel - no fallbacks, no alternatives.
|
|
71
71
|
*/
|
|
72
|
-
async function getVercelRepoName(
|
|
72
|
+
async function getVercelRepoName(_repoRoot) {
|
|
73
73
|
const owner = process.env.VERCEL_GIT_REPO_OWNER;
|
|
74
74
|
const slug = process.env.VERCEL_GIT_REPO_SLUG;
|
|
75
75
|
if (!owner || !slug) {
|
|
@@ -103,11 +103,12 @@ async function getLocalRepoName(repoRoot) {
|
|
|
103
103
|
}
|
|
104
104
|
catch (error) {
|
|
105
105
|
// If it's already our error, re-throw it
|
|
106
|
-
if (error.message.includes('Local:')) {
|
|
106
|
+
if (error instanceof Error && error.message.includes('Local:')) {
|
|
107
107
|
throw error;
|
|
108
108
|
}
|
|
109
109
|
// Otherwise, wrap it
|
|
110
|
-
|
|
110
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
111
|
+
throw new Error(`Local: Failed to get repository name from git: ${errorMessage}`);
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
114
|
/**
|
|
@@ -116,7 +117,7 @@ async function getLocalRepoName(repoRoot) {
|
|
|
116
117
|
* Uses GITHUB_REF_NAME environment variable.
|
|
117
118
|
* This is the ONLY method for GitHub - no fallbacks, no alternatives.
|
|
118
119
|
*/
|
|
119
|
-
async function getGitHubBranchName(
|
|
120
|
+
async function getGitHubBranchName(_repoRoot) {
|
|
120
121
|
const refName = process.env.GITHUB_REF_NAME;
|
|
121
122
|
if (!refName) {
|
|
122
123
|
throw new Error('GitHub Actions: GITHUB_REF_NAME environment variable is not set. ' +
|
|
@@ -130,7 +131,7 @@ async function getGitHubBranchName(repoRoot) {
|
|
|
130
131
|
* Uses VERCEL_GIT_COMMIT_REF environment variable.
|
|
131
132
|
* This is the ONLY method for Vercel - no fallbacks, no alternatives.
|
|
132
133
|
*/
|
|
133
|
-
async function getVercelBranchName(
|
|
134
|
+
async function getVercelBranchName(_repoRoot) {
|
|
134
135
|
const branchName = process.env.VERCEL_GIT_COMMIT_REF;
|
|
135
136
|
if (!branchName) {
|
|
136
137
|
throw new Error('Vercel: VERCEL_GIT_COMMIT_REF environment variable is not set. ' +
|
|
@@ -168,11 +169,12 @@ async function getLocalBranchName(repoRoot) {
|
|
|
168
169
|
}
|
|
169
170
|
catch (error) {
|
|
170
171
|
// If it's already our error, re-throw it
|
|
171
|
-
if (error.message.includes('Local:')) {
|
|
172
|
+
if (error instanceof Error && error.message.includes('Local:')) {
|
|
172
173
|
throw error;
|
|
173
174
|
}
|
|
174
175
|
// Otherwise, wrap it
|
|
175
|
-
|
|
176
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
177
|
+
throw new Error(`Local: Failed to get branch name from git: ${errorMessage}`);
|
|
176
178
|
}
|
|
177
179
|
}
|
|
178
180
|
/**
|
|
@@ -181,7 +183,7 @@ async function getLocalBranchName(repoRoot) {
|
|
|
181
183
|
* Uses CI_PROJECT_URL environment variable.
|
|
182
184
|
* This is the ONLY method for GitLab - no fallbacks, no alternatives.
|
|
183
185
|
*/
|
|
184
|
-
async function getGitLabRepoName(
|
|
186
|
+
async function getGitLabRepoName(_repoRoot) {
|
|
185
187
|
const projectUrl = process.env.CI_PROJECT_URL;
|
|
186
188
|
if (!projectUrl) {
|
|
187
189
|
throw new Error('GitLab CI: CI_PROJECT_URL environment variable is not set. ' +
|
|
@@ -197,7 +199,7 @@ async function getGitLabRepoName(repoRoot) {
|
|
|
197
199
|
* Uses CI_COMMIT_REF_NAME environment variable.
|
|
198
200
|
* This is the ONLY method for GitLab - no fallbacks, no alternatives.
|
|
199
201
|
*/
|
|
200
|
-
async function getGitLabBranchName(
|
|
202
|
+
async function getGitLabBranchName(_repoRoot) {
|
|
201
203
|
const refName = process.env.CI_COMMIT_REF_NAME;
|
|
202
204
|
if (!refName) {
|
|
203
205
|
throw new Error('GitLab CI: CI_COMMIT_REF_NAME environment variable is not set. ' +
|
|
@@ -217,7 +219,7 @@ async function getGitLabBranchName(repoRoot) {
|
|
|
217
219
|
* Returns the branch name (e.g., "main", "master") without the "origin/" prefix.
|
|
218
220
|
* Throws an error if the default branch cannot be detected.
|
|
219
221
|
*/
|
|
220
|
-
async function getDefaultBranchName(
|
|
222
|
+
async function getDefaultBranchName(_repoRoot) {
|
|
221
223
|
// GitHub Actions provides GITHUB_EVENT_PATH which contains repository.default_branch
|
|
222
224
|
const githubEventPath = process.env.GITHUB_EVENT_PATH;
|
|
223
225
|
if (!githubEventPath) {
|
|
@@ -240,11 +242,12 @@ async function getDefaultBranchName(repoRoot) {
|
|
|
240
242
|
}
|
|
241
243
|
catch (error) {
|
|
242
244
|
// If it's already our error, re-throw it
|
|
243
|
-
if (error.message.includes('GITHUB_EVENT_PATH') || error.message.includes('default_branch')) {
|
|
245
|
+
if (error instanceof Error && (error.message.includes('GITHUB_EVENT_PATH') || error.message.includes('default_branch'))) {
|
|
244
246
|
throw error;
|
|
245
247
|
}
|
|
246
248
|
// Otherwise, wrap it
|
|
247
|
-
|
|
249
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
250
|
+
throw new Error(`Failed to read or parse GITHUB_EVENT_PATH: ${errorMessage}. ` +
|
|
248
251
|
'This should be automatically provided by GitHub Actions.');
|
|
249
252
|
}
|
|
250
253
|
}
|
|
@@ -26,7 +26,7 @@ const gitlab_diff_1 = require("../git/gitlab-diff");
|
|
|
26
26
|
* No fallbacks - if the environment-specific implementation fails, we fail clearly.
|
|
27
27
|
* Each environment is completely isolated - changes to one don't affect others.
|
|
28
28
|
*/
|
|
29
|
-
async function getDiffForEnvironment(environment, repoRoot,
|
|
29
|
+
async function getDiffForEnvironment(environment, repoRoot, _context) {
|
|
30
30
|
switch (environment) {
|
|
31
31
|
case 'vercel':
|
|
32
32
|
// Vercel: Single implementation using commit SHA
|
|
@@ -85,7 +85,7 @@ async function validateThreadline(filePath, repoRoot) {
|
|
|
85
85
|
if (frontmatter.patterns && !Array.isArray(frontmatter.patterns)) {
|
|
86
86
|
errors.push('patterns must be an array');
|
|
87
87
|
}
|
|
88
|
-
if (frontmatter.patterns && frontmatter.patterns.length === 0) {
|
|
88
|
+
if (Array.isArray(frontmatter.patterns) && frontmatter.patterns.length === 0) {
|
|
89
89
|
errors.push('patterns array cannot be empty');
|
|
90
90
|
}
|
|
91
91
|
// Validate context_files if present
|
|
@@ -96,9 +96,11 @@ async function validateThreadline(filePath, repoRoot) {
|
|
|
96
96
|
else {
|
|
97
97
|
// Check if context files exist
|
|
98
98
|
for (const contextFile of frontmatter.context_files) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
if (typeof contextFile === 'string') {
|
|
100
|
+
const fullPath = path.join(repoRoot, contextFile);
|
|
101
|
+
if (!fs.existsSync(fullPath)) {
|
|
102
|
+
errors.push(`Context file not found: ${contextFile}`);
|
|
103
|
+
}
|
|
102
104
|
}
|
|
103
105
|
}
|
|
104
106
|
}
|
|
@@ -108,26 +110,28 @@ async function validateThreadline(filePath, repoRoot) {
|
|
|
108
110
|
errors.push('Threadline body cannot be empty');
|
|
109
111
|
}
|
|
110
112
|
// Validate version format (basic semver check)
|
|
111
|
-
if (frontmatter.version && !/^\d+\.\d+\.\d+/.test(frontmatter.version)) {
|
|
113
|
+
if (frontmatter.version && typeof frontmatter.version === 'string' && !/^\d+\.\d+\.\d+/.test(frontmatter.version)) {
|
|
112
114
|
errors.push('version must be in semver format (e.g., 1.0.0)');
|
|
113
115
|
}
|
|
114
116
|
if (errors.length > 0) {
|
|
115
117
|
return { valid: false, errors };
|
|
116
118
|
}
|
|
119
|
+
// Type assertions for required fields (already validated above)
|
|
117
120
|
const threadline = {
|
|
118
121
|
id: frontmatter.id,
|
|
119
122
|
version: frontmatter.version,
|
|
120
123
|
patterns: frontmatter.patterns,
|
|
121
|
-
contextFiles: frontmatter.context_files
|
|
124
|
+
contextFiles: (Array.isArray(frontmatter.context_files) ? frontmatter.context_files.filter((f) => typeof f === 'string') : []),
|
|
122
125
|
content: body,
|
|
123
126
|
filePath: path.relative(repoRoot, filePath)
|
|
124
127
|
};
|
|
125
128
|
return { valid: true, threadline };
|
|
126
129
|
}
|
|
127
130
|
catch (error) {
|
|
131
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
128
132
|
return {
|
|
129
133
|
valid: false,
|
|
130
|
-
errors: [`Failed to parse threadline file: ${
|
|
134
|
+
errors: [`Failed to parse threadline file: ${errorMessage}`]
|
|
131
135
|
};
|
|
132
136
|
}
|
|
133
137
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "threadlines",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"description": "Threadline CLI - AI-powered linter based on your natural language documentation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -27,10 +27,17 @@
|
|
|
27
27
|
"directory": "packages/cli"
|
|
28
28
|
},
|
|
29
29
|
"scripts": {
|
|
30
|
-
"build": "tsc",
|
|
30
|
+
"build": "npm run check && (npm run threadlines || exit 0) && tsc",
|
|
31
31
|
"dev": "tsc --watch",
|
|
32
32
|
"start": "node dist/index.js",
|
|
33
|
-
"prepublishOnly": "npm run build"
|
|
33
|
+
"prepublishOnly": "npm run build",
|
|
34
|
+
"lint": "eslint src/**/*.ts",
|
|
35
|
+
"lint:fix": "eslint src/**/*.ts --fix",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"check": "npm run lint && npm run typecheck",
|
|
38
|
+
"threadlines": "npx -y threadlines check",
|
|
39
|
+
"threadlines:local": "npx -y threadlines check || true",
|
|
40
|
+
"check:all": "npm run check && npm run threadlines"
|
|
34
41
|
},
|
|
35
42
|
"dependencies": {
|
|
36
43
|
"axios": "^1.7.9",
|
|
@@ -45,6 +52,9 @@
|
|
|
45
52
|
"@types/glob": "^8.1.0",
|
|
46
53
|
"@types/js-yaml": "^4.0.9",
|
|
47
54
|
"@types/node": "^22.10.2",
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "^8.51.0",
|
|
56
|
+
"@typescript-eslint/parser": "^8.51.0",
|
|
57
|
+
"eslint": "^9.39.2",
|
|
48
58
|
"typescript": "^5.7.2"
|
|
49
59
|
}
|
|
50
60
|
}
|