@staff0rd/assist 0.42.1 → 0.42.2
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/claude/settings.json +1 -1
- package/dist/index.js +366 -355
- package/package.json +2 -2
package/claude/settings.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Command } from "commander";
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "@staff0rd/assist",
|
|
10
|
-
version: "0.42.
|
|
10
|
+
version: "0.42.2",
|
|
11
11
|
type: "module",
|
|
12
12
|
main: "dist/index.js",
|
|
13
13
|
bin: {
|
|
@@ -28,7 +28,7 @@ var package_default = {
|
|
|
28
28
|
"verify:types": "tsc --noEmit",
|
|
29
29
|
"verify:knip": "knip --no-progress --treat-config-hints-as-errors",
|
|
30
30
|
"verify:duplicate-code": "jscpd --format 'typescript,tsx' --exitCode 1 --ignore '**/*.test.*' -r consoleFull src",
|
|
31
|
-
"verify:maintainability": "assist complexity maintainability ./src --threshold
|
|
31
|
+
"verify:maintainability": "assist complexity maintainability ./src --threshold 55",
|
|
32
32
|
"verify:custom-lint": "assist lint"
|
|
33
33
|
},
|
|
34
34
|
keywords: [],
|
|
@@ -212,72 +212,159 @@ function commit(message) {
|
|
|
212
212
|
import chalk3 from "chalk";
|
|
213
213
|
|
|
214
214
|
// src/commands/complexity/shared.ts
|
|
215
|
+
import fs2 from "fs";
|
|
216
|
+
import path2 from "path";
|
|
217
|
+
import chalk2 from "chalk";
|
|
218
|
+
import ts4 from "typescript";
|
|
219
|
+
|
|
220
|
+
// src/commands/complexity/findSourceFiles.ts
|
|
215
221
|
import fs from "fs";
|
|
216
222
|
import path from "path";
|
|
217
|
-
import chalk2 from "chalk";
|
|
218
223
|
import { minimatch } from "minimatch";
|
|
219
|
-
|
|
224
|
+
function applyIgnoreGlobs(files) {
|
|
225
|
+
const { complexity } = loadConfig();
|
|
226
|
+
return files.filter(
|
|
227
|
+
(f) => !complexity.ignore.some((glob) => minimatch(f, glob))
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
function walk(dir, results) {
|
|
231
|
+
if (!fs.existsSync(dir)) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const extensions = [".ts", ".tsx"];
|
|
235
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
236
|
+
for (const entry of entries) {
|
|
237
|
+
const fullPath = path.join(dir, entry.name);
|
|
238
|
+
if (entry.isDirectory()) {
|
|
239
|
+
if (entry.name !== "node_modules" && entry.name !== ".git") {
|
|
240
|
+
walk(fullPath, results);
|
|
241
|
+
}
|
|
242
|
+
} else if (entry.isFile() && extensions.some((ext) => entry.name.endsWith(ext))) {
|
|
243
|
+
results.push(fullPath);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function findSourceFiles(pattern2, baseDir = ".") {
|
|
248
|
+
const results = [];
|
|
249
|
+
if (pattern2.includes("*")) {
|
|
250
|
+
walk(baseDir, results);
|
|
251
|
+
return applyIgnoreGlobs(results.filter((f) => minimatch(f, pattern2)));
|
|
252
|
+
}
|
|
253
|
+
if (fs.existsSync(pattern2) && fs.statSync(pattern2).isFile()) {
|
|
254
|
+
return [pattern2];
|
|
255
|
+
}
|
|
256
|
+
if (fs.existsSync(pattern2) && fs.statSync(pattern2).isDirectory()) {
|
|
257
|
+
walk(pattern2, results);
|
|
258
|
+
return applyIgnoreGlobs(results);
|
|
259
|
+
}
|
|
260
|
+
walk(baseDir, results);
|
|
261
|
+
return applyIgnoreGlobs(results.filter((f) => minimatch(f, pattern2)));
|
|
262
|
+
}
|
|
220
263
|
|
|
221
|
-
// src/commands/complexity/
|
|
264
|
+
// src/commands/complexity/getNodeName.ts
|
|
222
265
|
import ts from "typescript";
|
|
266
|
+
function getNodeName(node) {
|
|
267
|
+
if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) {
|
|
268
|
+
return node.name?.text ?? "<anonymous>";
|
|
269
|
+
}
|
|
270
|
+
if (ts.isMethodDeclaration(node) || ts.isMethodSignature(node)) {
|
|
271
|
+
if (ts.isIdentifier(node.name)) {
|
|
272
|
+
return node.name.text;
|
|
273
|
+
}
|
|
274
|
+
if (ts.isStringLiteral(node.name)) {
|
|
275
|
+
return node.name.text;
|
|
276
|
+
}
|
|
277
|
+
return "<computed>";
|
|
278
|
+
}
|
|
279
|
+
if (ts.isArrowFunction(node)) {
|
|
280
|
+
const parent = node.parent;
|
|
281
|
+
if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
|
|
282
|
+
return parent.name.text;
|
|
283
|
+
}
|
|
284
|
+
if (ts.isPropertyAssignment(parent) && ts.isIdentifier(parent.name)) {
|
|
285
|
+
return parent.name.text;
|
|
286
|
+
}
|
|
287
|
+
return "<arrow>";
|
|
288
|
+
}
|
|
289
|
+
if (ts.isGetAccessor(node) || ts.isSetAccessor(node)) {
|
|
290
|
+
const prefix = ts.isGetAccessor(node) ? "get " : "set ";
|
|
291
|
+
if (ts.isIdentifier(node.name)) {
|
|
292
|
+
return `${prefix}${node.name.text}`;
|
|
293
|
+
}
|
|
294
|
+
return `${prefix}<computed>`;
|
|
295
|
+
}
|
|
296
|
+
if (ts.isConstructorDeclaration(node)) {
|
|
297
|
+
return "constructor";
|
|
298
|
+
}
|
|
299
|
+
return "<unknown>";
|
|
300
|
+
}
|
|
301
|
+
function hasFunctionBody(node) {
|
|
302
|
+
if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node) || ts.isConstructorDeclaration(node)) {
|
|
303
|
+
return node.body !== void 0;
|
|
304
|
+
}
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// src/commands/complexity/calculateCyclomaticComplexity.ts
|
|
309
|
+
import ts2 from "typescript";
|
|
223
310
|
var complexityKinds = /* @__PURE__ */ new Set([
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
311
|
+
ts2.SyntaxKind.IfStatement,
|
|
312
|
+
ts2.SyntaxKind.ForStatement,
|
|
313
|
+
ts2.SyntaxKind.ForInStatement,
|
|
314
|
+
ts2.SyntaxKind.ForOfStatement,
|
|
315
|
+
ts2.SyntaxKind.WhileStatement,
|
|
316
|
+
ts2.SyntaxKind.DoStatement,
|
|
317
|
+
ts2.SyntaxKind.CaseClause,
|
|
318
|
+
ts2.SyntaxKind.CatchClause,
|
|
319
|
+
ts2.SyntaxKind.ConditionalExpression
|
|
233
320
|
]);
|
|
234
321
|
var logicalOperators = /* @__PURE__ */ new Set([
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
322
|
+
ts2.SyntaxKind.AmpersandAmpersandToken,
|
|
323
|
+
ts2.SyntaxKind.BarBarToken,
|
|
324
|
+
ts2.SyntaxKind.QuestionQuestionToken
|
|
238
325
|
]);
|
|
239
326
|
function calculateCyclomaticComplexity(node) {
|
|
240
327
|
let complexity = 1;
|
|
241
328
|
function visit(n) {
|
|
242
329
|
if (complexityKinds.has(n.kind)) {
|
|
243
330
|
complexity++;
|
|
244
|
-
} else if (
|
|
331
|
+
} else if (ts2.isBinaryExpression(n) && logicalOperators.has(n.operatorToken.kind)) {
|
|
245
332
|
complexity++;
|
|
246
333
|
}
|
|
247
|
-
|
|
334
|
+
ts2.forEachChild(n, visit);
|
|
248
335
|
}
|
|
249
|
-
|
|
336
|
+
ts2.forEachChild(node, visit);
|
|
250
337
|
return complexity;
|
|
251
338
|
}
|
|
252
339
|
|
|
253
340
|
// src/commands/complexity/calculateHalstead.ts
|
|
254
|
-
import
|
|
341
|
+
import ts3 from "typescript";
|
|
255
342
|
var operatorChecks = [
|
|
256
|
-
(n) =>
|
|
257
|
-
(n) =>
|
|
258
|
-
(n) =>
|
|
259
|
-
(n) =>
|
|
260
|
-
(n) =>
|
|
261
|
-
(n) =>
|
|
262
|
-
(n) =>
|
|
263
|
-
(n) =>
|
|
264
|
-
(n) =>
|
|
265
|
-
(n) =>
|
|
266
|
-
(n) =>
|
|
267
|
-
(n) =>
|
|
268
|
-
(n) =>
|
|
269
|
-
(n) =>
|
|
270
|
-
(n) =>
|
|
271
|
-
(n) =>
|
|
272
|
-
(n) =>
|
|
273
|
-
(n) =>
|
|
274
|
-
(n) =>
|
|
275
|
-
(n) =>
|
|
276
|
-
(n) =>
|
|
277
|
-
(n) =>
|
|
343
|
+
(n) => ts3.isBinaryExpression(n) ? n.operatorToken.getText() : void 0,
|
|
344
|
+
(n) => ts3.isPrefixUnaryExpression(n) || ts3.isPostfixUnaryExpression(n) ? ts3.tokenToString(n.operator) ?? "" : void 0,
|
|
345
|
+
(n) => ts3.isCallExpression(n) ? "()" : void 0,
|
|
346
|
+
(n) => ts3.isPropertyAccessExpression(n) ? "." : void 0,
|
|
347
|
+
(n) => ts3.isElementAccessExpression(n) ? "[]" : void 0,
|
|
348
|
+
(n) => ts3.isConditionalExpression(n) ? "?:" : void 0,
|
|
349
|
+
(n) => ts3.isReturnStatement(n) ? "return" : void 0,
|
|
350
|
+
(n) => ts3.isIfStatement(n) ? "if" : void 0,
|
|
351
|
+
(n) => ts3.isForStatement(n) || ts3.isForInStatement(n) || ts3.isForOfStatement(n) ? "for" : void 0,
|
|
352
|
+
(n) => ts3.isWhileStatement(n) ? "while" : void 0,
|
|
353
|
+
(n) => ts3.isDoStatement(n) ? "do" : void 0,
|
|
354
|
+
(n) => ts3.isSwitchStatement(n) ? "switch" : void 0,
|
|
355
|
+
(n) => ts3.isCaseClause(n) ? "case" : void 0,
|
|
356
|
+
(n) => ts3.isDefaultClause(n) ? "default" : void 0,
|
|
357
|
+
(n) => ts3.isBreakStatement(n) ? "break" : void 0,
|
|
358
|
+
(n) => ts3.isContinueStatement(n) ? "continue" : void 0,
|
|
359
|
+
(n) => ts3.isThrowStatement(n) ? "throw" : void 0,
|
|
360
|
+
(n) => ts3.isTryStatement(n) ? "try" : void 0,
|
|
361
|
+
(n) => ts3.isCatchClause(n) ? "catch" : void 0,
|
|
362
|
+
(n) => ts3.isNewExpression(n) ? "new" : void 0,
|
|
363
|
+
(n) => ts3.isTypeOfExpression(n) ? "typeof" : void 0,
|
|
364
|
+
(n) => ts3.isAwaitExpression(n) ? "await" : void 0
|
|
278
365
|
];
|
|
279
366
|
function classifyNode(n, operators, operands) {
|
|
280
|
-
if (
|
|
367
|
+
if (ts3.isIdentifier(n) || ts3.isNumericLiteral(n) || ts3.isStringLiteral(n)) {
|
|
281
368
|
operands.set(n.text, (operands.get(n.text) ?? 0) + 1);
|
|
282
369
|
return;
|
|
283
370
|
}
|
|
@@ -314,9 +401,9 @@ function calculateHalstead(node) {
|
|
|
314
401
|
const operands = /* @__PURE__ */ new Map();
|
|
315
402
|
function visit(n) {
|
|
316
403
|
classifyNode(n, operators, operands);
|
|
317
|
-
|
|
404
|
+
ts3.forEachChild(n, visit);
|
|
318
405
|
}
|
|
319
|
-
|
|
406
|
+
ts3.forEachChild(node, visit);
|
|
320
407
|
return computeHalsteadMetrics(operators, operands);
|
|
321
408
|
}
|
|
322
409
|
|
|
@@ -358,53 +445,18 @@ function countSloc(content) {
|
|
|
358
445
|
}
|
|
359
446
|
|
|
360
447
|
// src/commands/complexity/shared.ts
|
|
361
|
-
function getNodeName(node) {
|
|
362
|
-
if (ts3.isFunctionDeclaration(node) || ts3.isFunctionExpression(node)) {
|
|
363
|
-
return node.name?.text ?? "<anonymous>";
|
|
364
|
-
}
|
|
365
|
-
if (ts3.isMethodDeclaration(node) || ts3.isMethodSignature(node)) {
|
|
366
|
-
if (ts3.isIdentifier(node.name)) {
|
|
367
|
-
return node.name.text;
|
|
368
|
-
}
|
|
369
|
-
if (ts3.isStringLiteral(node.name)) {
|
|
370
|
-
return node.name.text;
|
|
371
|
-
}
|
|
372
|
-
return "<computed>";
|
|
373
|
-
}
|
|
374
|
-
if (ts3.isArrowFunction(node)) {
|
|
375
|
-
const parent = node.parent;
|
|
376
|
-
if (ts3.isVariableDeclaration(parent) && ts3.isIdentifier(parent.name)) {
|
|
377
|
-
return parent.name.text;
|
|
378
|
-
}
|
|
379
|
-
if (ts3.isPropertyAssignment(parent) && ts3.isIdentifier(parent.name)) {
|
|
380
|
-
return parent.name.text;
|
|
381
|
-
}
|
|
382
|
-
return "<arrow>";
|
|
383
|
-
}
|
|
384
|
-
if (ts3.isGetAccessor(node) || ts3.isSetAccessor(node)) {
|
|
385
|
-
const prefix = ts3.isGetAccessor(node) ? "get " : "set ";
|
|
386
|
-
if (ts3.isIdentifier(node.name)) {
|
|
387
|
-
return `${prefix}${node.name.text}`;
|
|
388
|
-
}
|
|
389
|
-
return `${prefix}<computed>`;
|
|
390
|
-
}
|
|
391
|
-
if (ts3.isConstructorDeclaration(node)) {
|
|
392
|
-
return "constructor";
|
|
393
|
-
}
|
|
394
|
-
return "<unknown>";
|
|
395
|
-
}
|
|
396
448
|
function createSourceFromFile(filePath) {
|
|
397
|
-
const content =
|
|
398
|
-
return
|
|
399
|
-
|
|
449
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
450
|
+
return ts4.createSourceFile(
|
|
451
|
+
path2.basename(filePath),
|
|
400
452
|
content,
|
|
401
|
-
|
|
453
|
+
ts4.ScriptTarget.Latest,
|
|
402
454
|
true,
|
|
403
|
-
filePath.endsWith(".tsx") ?
|
|
455
|
+
filePath.endsWith(".tsx") ? ts4.ScriptKind.TSX : ts4.ScriptKind.TS
|
|
404
456
|
);
|
|
405
457
|
}
|
|
406
458
|
function withSourceFiles(pattern2, callback) {
|
|
407
|
-
const files =
|
|
459
|
+
const files = findSourceFiles(pattern2);
|
|
408
460
|
if (files.length === 0) {
|
|
409
461
|
console.log(chalk2.yellow("No files found matching pattern"));
|
|
410
462
|
return void 0;
|
|
@@ -418,56 +470,11 @@ function forEachFunction(files, callback) {
|
|
|
418
470
|
if (hasFunctionBody(node)) {
|
|
419
471
|
callback(file, getNodeName(node), node);
|
|
420
472
|
}
|
|
421
|
-
|
|
473
|
+
ts4.forEachChild(node, visit);
|
|
422
474
|
};
|
|
423
475
|
visit(sourceFile);
|
|
424
476
|
}
|
|
425
477
|
}
|
|
426
|
-
function applyIgnoreGlobs(files) {
|
|
427
|
-
const { complexity } = loadConfig();
|
|
428
|
-
return files.filter(
|
|
429
|
-
(f) => !complexity.ignore.some((glob) => minimatch(f, glob))
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
function findSourceFilesWithPattern(pattern2, baseDir = ".") {
|
|
433
|
-
const results = [];
|
|
434
|
-
const extensions = [".ts", ".tsx"];
|
|
435
|
-
function walk(dir) {
|
|
436
|
-
if (!fs.existsSync(dir)) {
|
|
437
|
-
return;
|
|
438
|
-
}
|
|
439
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
440
|
-
for (const entry of entries) {
|
|
441
|
-
const fullPath = path.join(dir, entry.name);
|
|
442
|
-
if (entry.isDirectory()) {
|
|
443
|
-
if (entry.name !== "node_modules" && entry.name !== ".git") {
|
|
444
|
-
walk(fullPath);
|
|
445
|
-
}
|
|
446
|
-
} else if (entry.isFile() && extensions.some((ext) => entry.name.endsWith(ext))) {
|
|
447
|
-
results.push(fullPath);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
if (pattern2.includes("*")) {
|
|
452
|
-
walk(baseDir);
|
|
453
|
-
return applyIgnoreGlobs(results.filter((f) => minimatch(f, pattern2)));
|
|
454
|
-
}
|
|
455
|
-
if (fs.existsSync(pattern2) && fs.statSync(pattern2).isFile()) {
|
|
456
|
-
return [pattern2];
|
|
457
|
-
}
|
|
458
|
-
if (fs.existsSync(pattern2) && fs.statSync(pattern2).isDirectory()) {
|
|
459
|
-
walk(pattern2);
|
|
460
|
-
return applyIgnoreGlobs(results);
|
|
461
|
-
}
|
|
462
|
-
walk(baseDir);
|
|
463
|
-
return applyIgnoreGlobs(results.filter((f) => minimatch(f, pattern2)));
|
|
464
|
-
}
|
|
465
|
-
function hasFunctionBody(node) {
|
|
466
|
-
if (ts3.isFunctionDeclaration(node) || ts3.isFunctionExpression(node) || ts3.isArrowFunction(node) || ts3.isMethodDeclaration(node) || ts3.isGetAccessor(node) || ts3.isSetAccessor(node) || ts3.isConstructorDeclaration(node)) {
|
|
467
|
-
return node.body !== void 0;
|
|
468
|
-
}
|
|
469
|
-
return false;
|
|
470
|
-
}
|
|
471
478
|
|
|
472
479
|
// src/commands/complexity/cyclomatic.ts
|
|
473
480
|
async function cyclomatic(pattern2 = "**/*.ts", options = {}) {
|
|
@@ -533,7 +540,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
533
540
|
}
|
|
534
541
|
|
|
535
542
|
// src/commands/complexity/maintainability.ts
|
|
536
|
-
import
|
|
543
|
+
import fs3 from "fs";
|
|
537
544
|
import chalk5 from "chalk";
|
|
538
545
|
function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
|
|
539
546
|
if (halsteadVolume === 0 || sloc2 === 0) {
|
|
@@ -546,7 +553,7 @@ async function maintainability(pattern2 = "**/*.ts", options = {}) {
|
|
|
546
553
|
withSourceFiles(pattern2, (files) => {
|
|
547
554
|
const fileMetrics = /* @__PURE__ */ new Map();
|
|
548
555
|
for (const file of files) {
|
|
549
|
-
const content =
|
|
556
|
+
const content = fs3.readFileSync(file, "utf-8");
|
|
550
557
|
fileMetrics.set(file, { sloc: countSloc(content), functions: [] });
|
|
551
558
|
}
|
|
552
559
|
forEachFunction(files, (file, _name, node) => {
|
|
@@ -585,10 +592,10 @@ async function maintainability(pattern2 = "**/*.ts", options = {}) {
|
|
|
585
592
|
console.log(chalk5.dim(`
|
|
586
593
|
Analyzed ${results.length} files`));
|
|
587
594
|
if (filtered.length > 0 && threshold !== void 0) {
|
|
588
|
-
console.
|
|
595
|
+
console.error(
|
|
589
596
|
chalk5.red(
|
|
590
597
|
`
|
|
591
|
-
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.`
|
|
598
|
+
Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code. Try 'complexity cyclomatic', 'complexity halstead', or 'complexity sloc' to help identify which metric is contributing most. For larger files, start by extracting responsibilities into smaller files.`
|
|
592
599
|
)
|
|
593
600
|
);
|
|
594
601
|
process.exit(1);
|
|
@@ -597,14 +604,14 @@ Fail: ${filtered.length} file(s) below threshold ${threshold}. Maintainability i
|
|
|
597
604
|
}
|
|
598
605
|
|
|
599
606
|
// src/commands/complexity/sloc.ts
|
|
600
|
-
import
|
|
607
|
+
import fs4 from "fs";
|
|
601
608
|
import chalk6 from "chalk";
|
|
602
609
|
async function sloc(pattern2 = "**/*.ts", options = {}) {
|
|
603
610
|
withSourceFiles(pattern2, (files) => {
|
|
604
611
|
const results = [];
|
|
605
612
|
let hasViolation = false;
|
|
606
613
|
for (const file of files) {
|
|
607
|
-
const content =
|
|
614
|
+
const content = fs4.readFileSync(file, "utf-8");
|
|
608
615
|
const lines = countSloc(content);
|
|
609
616
|
results.push({ file, lines });
|
|
610
617
|
if (options.threshold !== void 0 && lines > options.threshold) {
|
|
@@ -631,8 +638,8 @@ Total: ${total} lines across ${files.length} files`)
|
|
|
631
638
|
// src/commands/config/index.ts
|
|
632
639
|
import chalk7 from "chalk";
|
|
633
640
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
634
|
-
function getNestedValue(obj,
|
|
635
|
-
const keys =
|
|
641
|
+
function getNestedValue(obj, path20) {
|
|
642
|
+
const keys = path20.split(".");
|
|
636
643
|
let current = obj;
|
|
637
644
|
for (const key of keys) {
|
|
638
645
|
if (current === null || current === void 0 || typeof current !== "object") {
|
|
@@ -642,8 +649,8 @@ function getNestedValue(obj, path19) {
|
|
|
642
649
|
}
|
|
643
650
|
return current;
|
|
644
651
|
}
|
|
645
|
-
function setNestedValue(obj,
|
|
646
|
-
const keys =
|
|
652
|
+
function setNestedValue(obj, path20, value) {
|
|
653
|
+
const keys = path20.split(".");
|
|
647
654
|
const result = { ...obj };
|
|
648
655
|
let current = result;
|
|
649
656
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -670,8 +677,8 @@ function configSet(key, value) {
|
|
|
670
677
|
const result = assistConfigSchema.safeParse(updated);
|
|
671
678
|
if (!result.success) {
|
|
672
679
|
for (const issue of result.error.issues) {
|
|
673
|
-
const
|
|
674
|
-
console.error(chalk7.red(`${
|
|
680
|
+
const path20 = issue.path.length > 0 ? issue.path.join(".") : key;
|
|
681
|
+
console.error(chalk7.red(`${path20}: ${issue.message}`));
|
|
675
682
|
}
|
|
676
683
|
process.exit(1);
|
|
677
684
|
}
|
|
@@ -1221,18 +1228,18 @@ async function promptMultiselect(message, options) {
|
|
|
1221
1228
|
}
|
|
1222
1229
|
|
|
1223
1230
|
// src/shared/readPackageJson.ts
|
|
1224
|
-
import * as
|
|
1225
|
-
import * as
|
|
1231
|
+
import * as fs5 from "fs";
|
|
1232
|
+
import * as path3 from "path";
|
|
1226
1233
|
import chalk17 from "chalk";
|
|
1227
1234
|
function findPackageJson() {
|
|
1228
|
-
const packageJsonPath =
|
|
1229
|
-
if (
|
|
1235
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
1236
|
+
if (fs5.existsSync(packageJsonPath)) {
|
|
1230
1237
|
return packageJsonPath;
|
|
1231
1238
|
}
|
|
1232
1239
|
return null;
|
|
1233
1240
|
}
|
|
1234
1241
|
function readPackageJson(filePath) {
|
|
1235
|
-
return JSON.parse(
|
|
1242
|
+
return JSON.parse(fs5.readFileSync(filePath, "utf-8"));
|
|
1236
1243
|
}
|
|
1237
1244
|
function requirePackageJson() {
|
|
1238
1245
|
const packageJsonPath = findPackageJson();
|
|
@@ -1246,9 +1253,9 @@ function requirePackageJson() {
|
|
|
1246
1253
|
function findPackageJsonWithVerifyScripts(startDir) {
|
|
1247
1254
|
let currentDir = startDir;
|
|
1248
1255
|
while (true) {
|
|
1249
|
-
const packageJsonPath =
|
|
1250
|
-
if (
|
|
1251
|
-
const packageJson = JSON.parse(
|
|
1256
|
+
const packageJsonPath = path3.join(currentDir, "package.json");
|
|
1257
|
+
if (fs5.existsSync(packageJsonPath)) {
|
|
1258
|
+
const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath, "utf-8"));
|
|
1252
1259
|
const scripts = packageJson.scripts || {};
|
|
1253
1260
|
const verifyScripts = Object.keys(scripts).filter(
|
|
1254
1261
|
(name) => name.startsWith("verify:")
|
|
@@ -1257,7 +1264,7 @@ function findPackageJsonWithVerifyScripts(startDir) {
|
|
|
1257
1264
|
return { packageJsonPath, verifyScripts };
|
|
1258
1265
|
}
|
|
1259
1266
|
}
|
|
1260
|
-
const parentDir =
|
|
1267
|
+
const parentDir = path3.dirname(currentDir);
|
|
1261
1268
|
if (parentDir === currentDir) {
|
|
1262
1269
|
return null;
|
|
1263
1270
|
}
|
|
@@ -1279,11 +1286,11 @@ import chalk19 from "chalk";
|
|
|
1279
1286
|
|
|
1280
1287
|
// src/commands/verify/installPackage.ts
|
|
1281
1288
|
import { execSync as execSync7 } from "child_process";
|
|
1282
|
-
import * as
|
|
1283
|
-
import * as
|
|
1289
|
+
import * as fs6 from "fs";
|
|
1290
|
+
import * as path4 from "path";
|
|
1284
1291
|
import chalk18 from "chalk";
|
|
1285
1292
|
function writePackageJson(filePath, pkg) {
|
|
1286
|
-
|
|
1293
|
+
fs6.writeFileSync(filePath, `${JSON.stringify(pkg, null, 2)}
|
|
1287
1294
|
`);
|
|
1288
1295
|
}
|
|
1289
1296
|
function addScript(pkg, name, command) {
|
|
@@ -1306,18 +1313,18 @@ function installPackage(name, cwd) {
|
|
|
1306
1313
|
}
|
|
1307
1314
|
}
|
|
1308
1315
|
function addToKnipIgnoreBinaries(cwd, binary) {
|
|
1309
|
-
const knipJsonPath =
|
|
1316
|
+
const knipJsonPath = path4.join(cwd, "knip.json");
|
|
1310
1317
|
try {
|
|
1311
1318
|
let knipConfig;
|
|
1312
|
-
if (
|
|
1313
|
-
knipConfig = JSON.parse(
|
|
1319
|
+
if (fs6.existsSync(knipJsonPath)) {
|
|
1320
|
+
knipConfig = JSON.parse(fs6.readFileSync(knipJsonPath, "utf-8"));
|
|
1314
1321
|
} else {
|
|
1315
1322
|
knipConfig = { $schema: "https://unpkg.com/knip@5/schema.json" };
|
|
1316
1323
|
}
|
|
1317
1324
|
const ignoreBinaries = knipConfig.ignoreBinaries ?? [];
|
|
1318
1325
|
if (!ignoreBinaries.includes(binary)) {
|
|
1319
1326
|
knipConfig.ignoreBinaries = [...ignoreBinaries, binary];
|
|
1320
|
-
|
|
1327
|
+
fs6.writeFileSync(
|
|
1321
1328
|
knipJsonPath,
|
|
1322
1329
|
`${JSON.stringify(knipConfig, null, " ")}
|
|
1323
1330
|
`
|
|
@@ -1352,11 +1359,11 @@ async function setupBuild(packageJsonPath, hasVite, hasTypescript) {
|
|
|
1352
1359
|
}
|
|
1353
1360
|
|
|
1354
1361
|
// src/commands/verify/setup/setupDuplicateCode.ts
|
|
1355
|
-
import * as
|
|
1362
|
+
import * as path5 from "path";
|
|
1356
1363
|
import chalk20 from "chalk";
|
|
1357
1364
|
async function setupDuplicateCode(packageJsonPath) {
|
|
1358
1365
|
console.log(chalk20.blue("\nSetting up jscpd..."));
|
|
1359
|
-
const cwd =
|
|
1366
|
+
const cwd = path5.dirname(packageJsonPath);
|
|
1360
1367
|
const pkg = readPackageJson(packageJsonPath);
|
|
1361
1368
|
const hasJscpd = !!pkg.dependencies?.jscpd || !!pkg.devDependencies?.jscpd;
|
|
1362
1369
|
if (!hasJscpd && !installPackage("jscpd", cwd)) {
|
|
@@ -1370,11 +1377,11 @@ async function setupDuplicateCode(packageJsonPath) {
|
|
|
1370
1377
|
}
|
|
1371
1378
|
|
|
1372
1379
|
// src/commands/verify/setup/setupHardcodedColors.ts
|
|
1373
|
-
import * as
|
|
1380
|
+
import * as path6 from "path";
|
|
1374
1381
|
import chalk21 from "chalk";
|
|
1375
1382
|
async function setupHardcodedColors(packageJsonPath, hasOpenColor) {
|
|
1376
1383
|
console.log(chalk21.blue("\nSetting up hardcoded colors check..."));
|
|
1377
|
-
const cwd =
|
|
1384
|
+
const cwd = path6.dirname(packageJsonPath);
|
|
1378
1385
|
if (!hasOpenColor) {
|
|
1379
1386
|
installPackage("open-color", cwd);
|
|
1380
1387
|
}
|
|
@@ -1387,11 +1394,11 @@ async function setupHardcodedColors(packageJsonPath, hasOpenColor) {
|
|
|
1387
1394
|
}
|
|
1388
1395
|
|
|
1389
1396
|
// src/commands/verify/setup/setupKnip.ts
|
|
1390
|
-
import * as
|
|
1397
|
+
import * as path7 from "path";
|
|
1391
1398
|
import chalk22 from "chalk";
|
|
1392
1399
|
async function setupKnip(packageJsonPath) {
|
|
1393
1400
|
console.log(chalk22.blue("\nSetting up knip..."));
|
|
1394
|
-
const cwd =
|
|
1401
|
+
const cwd = path7.dirname(packageJsonPath);
|
|
1395
1402
|
const pkg = readPackageJson(packageJsonPath);
|
|
1396
1403
|
if (!pkg.devDependencies?.knip && !installPackage("knip", cwd)) {
|
|
1397
1404
|
return;
|
|
@@ -1404,7 +1411,7 @@ async function setupKnip(packageJsonPath) {
|
|
|
1404
1411
|
}
|
|
1405
1412
|
|
|
1406
1413
|
// src/commands/verify/setup/setupLint.ts
|
|
1407
|
-
import * as
|
|
1414
|
+
import * as path8 from "path";
|
|
1408
1415
|
import chalk24 from "chalk";
|
|
1409
1416
|
|
|
1410
1417
|
// src/commands/lint/init.ts
|
|
@@ -1533,7 +1540,7 @@ async function init2() {
|
|
|
1533
1540
|
// src/commands/verify/setup/setupLint.ts
|
|
1534
1541
|
async function setupLint(packageJsonPath) {
|
|
1535
1542
|
console.log(chalk24.blue("\nSetting up biome..."));
|
|
1536
|
-
const cwd =
|
|
1543
|
+
const cwd = path8.dirname(packageJsonPath);
|
|
1537
1544
|
const pkg = readPackageJson(packageJsonPath);
|
|
1538
1545
|
if (!pkg.devDependencies?.["@biomejs/biome"]) {
|
|
1539
1546
|
if (!installPackage("@biomejs/biome", cwd)) {
|
|
@@ -1549,11 +1556,11 @@ async function setupLint(packageJsonPath) {
|
|
|
1549
1556
|
}
|
|
1550
1557
|
|
|
1551
1558
|
// src/commands/verify/setup/setupTest.ts
|
|
1552
|
-
import * as
|
|
1559
|
+
import * as path9 from "path";
|
|
1553
1560
|
import chalk25 from "chalk";
|
|
1554
1561
|
async function setupTest(packageJsonPath) {
|
|
1555
1562
|
console.log(chalk25.blue("\nSetting up vitest..."));
|
|
1556
|
-
const cwd =
|
|
1563
|
+
const cwd = path9.dirname(packageJsonPath);
|
|
1557
1564
|
const pkg = readPackageJson(packageJsonPath);
|
|
1558
1565
|
if (!pkg.devDependencies?.vitest && !installPackage("vitest", cwd)) {
|
|
1559
1566
|
return;
|
|
@@ -1738,33 +1745,33 @@ Added ${selected.length} verify script(s):`));
|
|
|
1738
1745
|
}
|
|
1739
1746
|
|
|
1740
1747
|
// src/commands/vscode/init.ts
|
|
1741
|
-
import * as
|
|
1742
|
-
import * as
|
|
1748
|
+
import * as fs8 from "fs";
|
|
1749
|
+
import * as path11 from "path";
|
|
1743
1750
|
import chalk28 from "chalk";
|
|
1744
1751
|
|
|
1745
1752
|
// src/commands/vscode/createLaunchJson.ts
|
|
1746
|
-
import * as
|
|
1747
|
-
import * as
|
|
1753
|
+
import * as fs7 from "fs";
|
|
1754
|
+
import * as path10 from "path";
|
|
1748
1755
|
import chalk27 from "chalk";
|
|
1749
1756
|
function ensureVscodeFolder() {
|
|
1750
|
-
const vscodeDir =
|
|
1751
|
-
if (!
|
|
1752
|
-
|
|
1757
|
+
const vscodeDir = path10.join(process.cwd(), ".vscode");
|
|
1758
|
+
if (!fs7.existsSync(vscodeDir)) {
|
|
1759
|
+
fs7.mkdirSync(vscodeDir);
|
|
1753
1760
|
console.log(chalk27.dim("Created .vscode folder"));
|
|
1754
1761
|
}
|
|
1755
1762
|
}
|
|
1756
1763
|
function removeVscodeFromGitignore() {
|
|
1757
|
-
const gitignorePath =
|
|
1758
|
-
if (!
|
|
1764
|
+
const gitignorePath = path10.join(process.cwd(), ".gitignore");
|
|
1765
|
+
if (!fs7.existsSync(gitignorePath)) {
|
|
1759
1766
|
return;
|
|
1760
1767
|
}
|
|
1761
|
-
const content =
|
|
1768
|
+
const content = fs7.readFileSync(gitignorePath, "utf-8");
|
|
1762
1769
|
const lines = content.split("\n");
|
|
1763
1770
|
const filteredLines = lines.filter(
|
|
1764
1771
|
(line) => !line.trim().toLowerCase().includes(".vscode")
|
|
1765
1772
|
);
|
|
1766
1773
|
if (filteredLines.length !== lines.length) {
|
|
1767
|
-
|
|
1774
|
+
fs7.writeFileSync(gitignorePath, filteredLines.join("\n"));
|
|
1768
1775
|
console.log(chalk27.dim("Removed .vscode references from .gitignore"));
|
|
1769
1776
|
}
|
|
1770
1777
|
}
|
|
@@ -1780,8 +1787,8 @@ function createLaunchJson() {
|
|
|
1780
1787
|
}
|
|
1781
1788
|
]
|
|
1782
1789
|
};
|
|
1783
|
-
const launchPath =
|
|
1784
|
-
|
|
1790
|
+
const launchPath = path10.join(process.cwd(), ".vscode", "launch.json");
|
|
1791
|
+
fs7.writeFileSync(launchPath, `${JSON.stringify(launchConfig, null, " ")}
|
|
1785
1792
|
`);
|
|
1786
1793
|
console.log(chalk27.green("Created .vscode/launch.json"));
|
|
1787
1794
|
}
|
|
@@ -1793,8 +1800,8 @@ function createSettingsJson() {
|
|
|
1793
1800
|
"source.organizeImports.biome": "explicit"
|
|
1794
1801
|
}
|
|
1795
1802
|
};
|
|
1796
|
-
const settingsPath =
|
|
1797
|
-
|
|
1803
|
+
const settingsPath = path10.join(process.cwd(), ".vscode", "settings.json");
|
|
1804
|
+
fs7.writeFileSync(settingsPath, `${JSON.stringify(settings, null, " ")}
|
|
1798
1805
|
`);
|
|
1799
1806
|
console.log(chalk27.green("Created .vscode/settings.json"));
|
|
1800
1807
|
}
|
|
@@ -1802,8 +1809,8 @@ function createExtensionsJson() {
|
|
|
1802
1809
|
const extensions = {
|
|
1803
1810
|
recommendations: ["biomejs.biome"]
|
|
1804
1811
|
};
|
|
1805
|
-
const extensionsPath =
|
|
1806
|
-
|
|
1812
|
+
const extensionsPath = path10.join(process.cwd(), ".vscode", "extensions.json");
|
|
1813
|
+
fs7.writeFileSync(
|
|
1807
1814
|
extensionsPath,
|
|
1808
1815
|
`${JSON.stringify(extensions, null, " ")}
|
|
1809
1816
|
`
|
|
@@ -1813,11 +1820,11 @@ function createExtensionsJson() {
|
|
|
1813
1820
|
|
|
1814
1821
|
// src/commands/vscode/init.ts
|
|
1815
1822
|
function detectExistingSetup2(pkg) {
|
|
1816
|
-
const vscodeDir =
|
|
1823
|
+
const vscodeDir = path11.join(process.cwd(), ".vscode");
|
|
1817
1824
|
return {
|
|
1818
|
-
hasVscodeFolder:
|
|
1819
|
-
hasLaunchJson:
|
|
1820
|
-
hasSettingsJson:
|
|
1825
|
+
hasVscodeFolder: fs8.existsSync(vscodeDir),
|
|
1826
|
+
hasLaunchJson: fs8.existsSync(path11.join(vscodeDir, "launch.json")),
|
|
1827
|
+
hasSettingsJson: fs8.existsSync(path11.join(vscodeDir, "settings.json")),
|
|
1821
1828
|
hasVite: !!pkg.devDependencies?.vite || !!pkg.dependencies?.vite
|
|
1822
1829
|
};
|
|
1823
1830
|
}
|
|
@@ -1878,25 +1885,25 @@ async function init5() {
|
|
|
1878
1885
|
}
|
|
1879
1886
|
|
|
1880
1887
|
// src/commands/lint/runFileNameCheck.ts
|
|
1881
|
-
import
|
|
1882
|
-
import
|
|
1888
|
+
import fs10 from "fs";
|
|
1889
|
+
import path13 from "path";
|
|
1883
1890
|
import chalk29 from "chalk";
|
|
1884
1891
|
|
|
1885
1892
|
// src/shared/findSourceFiles.ts
|
|
1886
|
-
import
|
|
1887
|
-
import
|
|
1893
|
+
import fs9 from "fs";
|
|
1894
|
+
import path12 from "path";
|
|
1888
1895
|
var EXTENSIONS = [".ts", ".tsx"];
|
|
1889
|
-
function
|
|
1896
|
+
function findSourceFiles2(dir, options = {}) {
|
|
1890
1897
|
const { includeTests = true } = options;
|
|
1891
1898
|
const results = [];
|
|
1892
|
-
if (!
|
|
1899
|
+
if (!fs9.existsSync(dir)) {
|
|
1893
1900
|
return results;
|
|
1894
1901
|
}
|
|
1895
|
-
const entries =
|
|
1902
|
+
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
1896
1903
|
for (const entry of entries) {
|
|
1897
|
-
const fullPath =
|
|
1904
|
+
const fullPath = path12.join(dir, entry.name);
|
|
1898
1905
|
if (entry.isDirectory() && entry.name !== "node_modules") {
|
|
1899
|
-
results.push(...
|
|
1906
|
+
results.push(...findSourceFiles2(fullPath, options));
|
|
1900
1907
|
} else if (entry.isFile() && EXTENSIONS.some((ext) => entry.name.endsWith(ext))) {
|
|
1901
1908
|
if (!includeTests && entry.name.includes(".test.")) {
|
|
1902
1909
|
continue;
|
|
@@ -1915,13 +1922,13 @@ function hasClassOrComponent(content) {
|
|
|
1915
1922
|
return classPattern.test(content) || functionComponentPattern.test(content) || arrowComponentPattern.test(content);
|
|
1916
1923
|
}
|
|
1917
1924
|
function checkFileNames() {
|
|
1918
|
-
const sourceFiles =
|
|
1925
|
+
const sourceFiles = findSourceFiles2("src");
|
|
1919
1926
|
const violations = [];
|
|
1920
1927
|
for (const filePath of sourceFiles) {
|
|
1921
|
-
const fileName =
|
|
1928
|
+
const fileName = path13.basename(filePath);
|
|
1922
1929
|
const nameWithoutExt = fileName.replace(/\.(ts|tsx)$/, "");
|
|
1923
1930
|
if (/^[A-Z]/.test(nameWithoutExt)) {
|
|
1924
|
-
const content =
|
|
1931
|
+
const content = fs10.readFileSync(filePath, "utf-8");
|
|
1925
1932
|
if (!hasClassOrComponent(content)) {
|
|
1926
1933
|
violations.push({ filePath, fileName });
|
|
1927
1934
|
}
|
|
@@ -1958,7 +1965,7 @@ function runFileNameCheck() {
|
|
|
1958
1965
|
}
|
|
1959
1966
|
|
|
1960
1967
|
// src/commands/lint/runImportExtensionCheck.ts
|
|
1961
|
-
import
|
|
1968
|
+
import fs11 from "fs";
|
|
1962
1969
|
|
|
1963
1970
|
// src/commands/lint/shared.ts
|
|
1964
1971
|
import chalk30 from "chalk";
|
|
@@ -1984,7 +1991,7 @@ ${checkName} failed:
|
|
|
1984
1991
|
|
|
1985
1992
|
// src/commands/lint/runImportExtensionCheck.ts
|
|
1986
1993
|
function checkForImportExtensions(filePath) {
|
|
1987
|
-
const content =
|
|
1994
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
1988
1995
|
const lines = content.split("\n");
|
|
1989
1996
|
const violations = [];
|
|
1990
1997
|
const importExtensionPattern = /from\s+["']\..*\.(js|ts)["']/;
|
|
@@ -2001,7 +2008,7 @@ function checkForImportExtensions(filePath) {
|
|
|
2001
2008
|
return violations;
|
|
2002
2009
|
}
|
|
2003
2010
|
function checkImportExtensions() {
|
|
2004
|
-
const sourceFiles =
|
|
2011
|
+
const sourceFiles = findSourceFiles2("src");
|
|
2005
2012
|
const violations = [];
|
|
2006
2013
|
for (const filePath of sourceFiles) {
|
|
2007
2014
|
violations.push(...checkForImportExtensions(filePath));
|
|
@@ -2018,9 +2025,9 @@ function runImportExtensionCheck() {
|
|
|
2018
2025
|
}
|
|
2019
2026
|
|
|
2020
2027
|
// src/commands/lint/runStaticImportCheck.ts
|
|
2021
|
-
import
|
|
2028
|
+
import fs12 from "fs";
|
|
2022
2029
|
function checkForDynamicImports(filePath) {
|
|
2023
|
-
const content =
|
|
2030
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
2024
2031
|
const lines = content.split("\n");
|
|
2025
2032
|
const violations = [];
|
|
2026
2033
|
const requirePattern = /\brequire\s*\(/;
|
|
@@ -2038,7 +2045,7 @@ function checkForDynamicImports(filePath) {
|
|
|
2038
2045
|
return violations;
|
|
2039
2046
|
}
|
|
2040
2047
|
function checkStaticImports() {
|
|
2041
|
-
const sourceFiles =
|
|
2048
|
+
const sourceFiles = findSourceFiles2("src");
|
|
2042
2049
|
const violations = [];
|
|
2043
2050
|
for (const filePath of sourceFiles) {
|
|
2044
2051
|
violations.push(...checkForDynamicImports(filePath));
|
|
@@ -2134,19 +2141,19 @@ function detectPlatform() {
|
|
|
2134
2141
|
|
|
2135
2142
|
// src/commands/notify/showWindowsNotificationFromWsl.ts
|
|
2136
2143
|
import { spawn } from "child_process";
|
|
2137
|
-
import
|
|
2144
|
+
import fs13 from "fs";
|
|
2138
2145
|
import { createRequire } from "module";
|
|
2139
|
-
import
|
|
2146
|
+
import path14 from "path";
|
|
2140
2147
|
var require2 = createRequire(import.meta.url);
|
|
2141
2148
|
function getSnoreToastPath() {
|
|
2142
|
-
const notifierPath =
|
|
2143
|
-
return
|
|
2149
|
+
const notifierPath = path14.dirname(require2.resolve("node-notifier"));
|
|
2150
|
+
return path14.join(notifierPath, "vendor", "snoreToast", "snoretoast-x64.exe");
|
|
2144
2151
|
}
|
|
2145
2152
|
function showWindowsNotificationFromWsl(options) {
|
|
2146
2153
|
const { title, message, sound } = options;
|
|
2147
2154
|
const snoreToastPath = getSnoreToastPath();
|
|
2148
2155
|
try {
|
|
2149
|
-
|
|
2156
|
+
fs13.chmodSync(snoreToastPath, 493);
|
|
2150
2157
|
} catch {
|
|
2151
2158
|
}
|
|
2152
2159
|
const args = ["-t", title, "-m", message];
|
|
@@ -2347,7 +2354,6 @@ function fixed(commentId, sha) {
|
|
|
2347
2354
|
}
|
|
2348
2355
|
|
|
2349
2356
|
// src/commands/prs/listComments.ts
|
|
2350
|
-
import { execSync as execSync13 } from "child_process";
|
|
2351
2357
|
import { existsSync as existsSync12, mkdirSync as mkdirSync3, writeFileSync as writeFileSync11 } from "fs";
|
|
2352
2358
|
import { join as join11 } from "path";
|
|
2353
2359
|
import chalk31 from "chalk";
|
|
@@ -2358,8 +2364,53 @@ function isClaudeCode() {
|
|
|
2358
2364
|
return process.env.CLAUDECODE !== void 0;
|
|
2359
2365
|
}
|
|
2360
2366
|
|
|
2361
|
-
// src/commands/prs/
|
|
2367
|
+
// src/commands/prs/fetchReviewComments.ts
|
|
2362
2368
|
import { execSync as execSync12 } from "child_process";
|
|
2369
|
+
function fetchReviewComments(org, repo, prNumber) {
|
|
2370
|
+
const result = execSync12(
|
|
2371
|
+
`gh api repos/${org}/${repo}/pulls/${prNumber}/reviews`,
|
|
2372
|
+
{ encoding: "utf-8" }
|
|
2373
|
+
);
|
|
2374
|
+
if (!result.trim()) return [];
|
|
2375
|
+
const reviews = JSON.parse(result);
|
|
2376
|
+
return reviews.filter((r) => r.body).map(
|
|
2377
|
+
(r) => ({
|
|
2378
|
+
type: "review",
|
|
2379
|
+
id: r.id,
|
|
2380
|
+
user: r.user.login,
|
|
2381
|
+
state: r.state,
|
|
2382
|
+
body: r.body
|
|
2383
|
+
})
|
|
2384
|
+
);
|
|
2385
|
+
}
|
|
2386
|
+
function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
2387
|
+
const result = execSync12(
|
|
2388
|
+
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments`,
|
|
2389
|
+
{ encoding: "utf-8" }
|
|
2390
|
+
);
|
|
2391
|
+
if (!result.trim()) return [];
|
|
2392
|
+
const comments = JSON.parse(result);
|
|
2393
|
+
return comments.map(
|
|
2394
|
+
(c) => {
|
|
2395
|
+
const threadId = threadInfo.threadMap.get(c.id) ?? "";
|
|
2396
|
+
return {
|
|
2397
|
+
type: "line",
|
|
2398
|
+
id: c.id,
|
|
2399
|
+
threadId,
|
|
2400
|
+
user: c.user.login,
|
|
2401
|
+
path: c.path,
|
|
2402
|
+
line: c.line,
|
|
2403
|
+
body: c.body,
|
|
2404
|
+
diff_hunk: c.diff_hunk,
|
|
2405
|
+
html_url: c.html_url,
|
|
2406
|
+
resolved: threadInfo.resolvedThreadIds.has(threadId)
|
|
2407
|
+
};
|
|
2408
|
+
}
|
|
2409
|
+
);
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
// src/commands/prs/fetchThreadIds.ts
|
|
2413
|
+
import { execSync as execSync13 } from "child_process";
|
|
2363
2414
|
import { unlinkSync as unlinkSync3, writeFileSync as writeFileSync10 } from "fs";
|
|
2364
2415
|
import { tmpdir as tmpdir2 } from "os";
|
|
2365
2416
|
import { join as join10 } from "path";
|
|
@@ -2368,7 +2419,7 @@ function fetchThreadIds(org, repo, prNumber) {
|
|
|
2368
2419
|
const queryFile = join10(tmpdir2(), `gh-query-${Date.now()}.graphql`);
|
|
2369
2420
|
writeFileSync10(queryFile, THREAD_QUERY);
|
|
2370
2421
|
try {
|
|
2371
|
-
const result =
|
|
2422
|
+
const result = execSync13(
|
|
2372
2423
|
`gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
|
|
2373
2424
|
{ encoding: "utf-8" }
|
|
2374
2425
|
);
|
|
@@ -2439,48 +2490,6 @@ function writeCommentsCache(prNumber, comments) {
|
|
|
2439
2490
|
const cachePath = join11(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
2440
2491
|
writeFileSync11(cachePath, stringify(cacheData));
|
|
2441
2492
|
}
|
|
2442
|
-
function fetchReviewComments(org, repo, prNumber) {
|
|
2443
|
-
const result = execSync13(
|
|
2444
|
-
`gh api repos/${org}/${repo}/pulls/${prNumber}/reviews`,
|
|
2445
|
-
{ encoding: "utf-8" }
|
|
2446
|
-
);
|
|
2447
|
-
if (!result.trim()) return [];
|
|
2448
|
-
const reviews = JSON.parse(result);
|
|
2449
|
-
return reviews.filter((r) => r.body).map(
|
|
2450
|
-
(r) => ({
|
|
2451
|
-
type: "review",
|
|
2452
|
-
id: r.id,
|
|
2453
|
-
user: r.user.login,
|
|
2454
|
-
state: r.state,
|
|
2455
|
-
body: r.body
|
|
2456
|
-
})
|
|
2457
|
-
);
|
|
2458
|
-
}
|
|
2459
|
-
function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
2460
|
-
const result = execSync13(
|
|
2461
|
-
`gh api repos/${org}/${repo}/pulls/${prNumber}/comments`,
|
|
2462
|
-
{ encoding: "utf-8" }
|
|
2463
|
-
);
|
|
2464
|
-
if (!result.trim()) return [];
|
|
2465
|
-
const comments = JSON.parse(result);
|
|
2466
|
-
return comments.map(
|
|
2467
|
-
(c) => {
|
|
2468
|
-
const threadId = threadInfo.threadMap.get(c.id) ?? "";
|
|
2469
|
-
return {
|
|
2470
|
-
type: "line",
|
|
2471
|
-
id: c.id,
|
|
2472
|
-
threadId,
|
|
2473
|
-
user: c.user.login,
|
|
2474
|
-
path: c.path,
|
|
2475
|
-
line: c.line,
|
|
2476
|
-
body: c.body,
|
|
2477
|
-
diff_hunk: c.diff_hunk,
|
|
2478
|
-
html_url: c.html_url,
|
|
2479
|
-
resolved: threadInfo.resolvedThreadIds.has(threadId)
|
|
2480
|
-
};
|
|
2481
|
-
}
|
|
2482
|
-
);
|
|
2483
|
-
}
|
|
2484
2493
|
async function listComments() {
|
|
2485
2494
|
try {
|
|
2486
2495
|
const prNumber = getCurrentPrNumber();
|
|
@@ -2647,21 +2656,21 @@ function wontfix(commentId, reason) {
|
|
|
2647
2656
|
|
|
2648
2657
|
// src/commands/refactor/check.ts
|
|
2649
2658
|
import { spawn as spawn2 } from "child_process";
|
|
2650
|
-
import * as
|
|
2659
|
+
import * as path15 from "path";
|
|
2651
2660
|
|
|
2652
2661
|
// src/commands/refactor/getViolations.ts
|
|
2653
2662
|
import { execSync as execSync16 } from "child_process";
|
|
2654
|
-
import
|
|
2663
|
+
import fs15 from "fs";
|
|
2655
2664
|
import { minimatch as minimatch2 } from "minimatch";
|
|
2656
2665
|
|
|
2657
2666
|
// src/commands/refactor/getIgnoredFiles.ts
|
|
2658
|
-
import
|
|
2667
|
+
import fs14 from "fs";
|
|
2659
2668
|
var REFACTOR_YML_PATH = "refactor.yml";
|
|
2660
2669
|
function parseRefactorYml() {
|
|
2661
|
-
if (!
|
|
2670
|
+
if (!fs14.existsSync(REFACTOR_YML_PATH)) {
|
|
2662
2671
|
return [];
|
|
2663
2672
|
}
|
|
2664
|
-
const content =
|
|
2673
|
+
const content = fs14.readFileSync(REFACTOR_YML_PATH, "utf-8");
|
|
2665
2674
|
const entries = [];
|
|
2666
2675
|
const lines = content.split("\n");
|
|
2667
2676
|
let currentEntry = {};
|
|
@@ -2746,7 +2755,7 @@ Refactor check failed:
|
|
|
2746
2755
|
|
|
2747
2756
|
// src/commands/refactor/getViolations.ts
|
|
2748
2757
|
function countLines(filePath) {
|
|
2749
|
-
const content =
|
|
2758
|
+
const content = fs15.readFileSync(filePath, "utf-8");
|
|
2750
2759
|
return content.split("\n").length;
|
|
2751
2760
|
}
|
|
2752
2761
|
function getGitFiles(options) {
|
|
@@ -2771,7 +2780,7 @@ function getGitFiles(options) {
|
|
|
2771
2780
|
return files;
|
|
2772
2781
|
}
|
|
2773
2782
|
function getViolations(pattern2, options = {}, maxLines = DEFAULT_MAX_LINES) {
|
|
2774
|
-
let sourceFiles =
|
|
2783
|
+
let sourceFiles = findSourceFiles2("src", { includeTests: false });
|
|
2775
2784
|
const ignoredFiles = getIgnoredFiles();
|
|
2776
2785
|
const gitFiles = getGitFiles(options);
|
|
2777
2786
|
if (pattern2) {
|
|
@@ -2798,7 +2807,7 @@ async function runVerifyQuietly() {
|
|
|
2798
2807
|
return true;
|
|
2799
2808
|
}
|
|
2800
2809
|
const { packageJsonPath, verifyScripts } = result;
|
|
2801
|
-
const packageDir =
|
|
2810
|
+
const packageDir = path15.dirname(packageJsonPath);
|
|
2802
2811
|
const results = await Promise.all(
|
|
2803
2812
|
verifyScripts.map(
|
|
2804
2813
|
(script) => new Promise(
|
|
@@ -2851,25 +2860,25 @@ async function check(pattern2, options) {
|
|
|
2851
2860
|
}
|
|
2852
2861
|
|
|
2853
2862
|
// src/commands/refactor/ignore.ts
|
|
2854
|
-
import
|
|
2863
|
+
import fs16 from "fs";
|
|
2855
2864
|
import chalk34 from "chalk";
|
|
2856
2865
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
2857
2866
|
function ignore(file) {
|
|
2858
|
-
if (!
|
|
2867
|
+
if (!fs16.existsSync(file)) {
|
|
2859
2868
|
console.error(chalk34.red(`Error: File does not exist: ${file}`));
|
|
2860
2869
|
process.exit(1);
|
|
2861
2870
|
}
|
|
2862
|
-
const content =
|
|
2871
|
+
const content = fs16.readFileSync(file, "utf-8");
|
|
2863
2872
|
const lineCount = content.split("\n").length;
|
|
2864
2873
|
const maxLines = lineCount + 10;
|
|
2865
2874
|
const entry = `- file: ${file}
|
|
2866
2875
|
maxLines: ${maxLines}
|
|
2867
2876
|
`;
|
|
2868
|
-
if (
|
|
2869
|
-
const existing =
|
|
2870
|
-
|
|
2877
|
+
if (fs16.existsSync(REFACTOR_YML_PATH2)) {
|
|
2878
|
+
const existing = fs16.readFileSync(REFACTOR_YML_PATH2, "utf-8");
|
|
2879
|
+
fs16.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
|
|
2871
2880
|
} else {
|
|
2872
|
-
|
|
2881
|
+
fs16.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
2873
2882
|
}
|
|
2874
2883
|
console.log(
|
|
2875
2884
|
chalk34.green(
|
|
@@ -2963,21 +2972,21 @@ async function statusLine() {
|
|
|
2963
2972
|
}
|
|
2964
2973
|
|
|
2965
2974
|
// src/commands/sync.ts
|
|
2966
|
-
import * as
|
|
2975
|
+
import * as fs19 from "fs";
|
|
2967
2976
|
import * as os from "os";
|
|
2968
|
-
import * as
|
|
2977
|
+
import * as path18 from "path";
|
|
2969
2978
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2970
2979
|
|
|
2971
2980
|
// src/commands/sync/syncClaudeMd.ts
|
|
2972
|
-
import * as
|
|
2973
|
-
import * as
|
|
2981
|
+
import * as fs17 from "fs";
|
|
2982
|
+
import * as path16 from "path";
|
|
2974
2983
|
import chalk35 from "chalk";
|
|
2975
2984
|
async function syncClaudeMd(claudeDir, targetBase) {
|
|
2976
|
-
const source =
|
|
2977
|
-
const target =
|
|
2978
|
-
const sourceContent =
|
|
2979
|
-
if (
|
|
2980
|
-
const targetContent =
|
|
2985
|
+
const source = path16.join(claudeDir, "CLAUDE.md");
|
|
2986
|
+
const target = path16.join(targetBase, "CLAUDE.md");
|
|
2987
|
+
const sourceContent = fs17.readFileSync(source, "utf-8");
|
|
2988
|
+
if (fs17.existsSync(target)) {
|
|
2989
|
+
const targetContent = fs17.readFileSync(target, "utf-8");
|
|
2981
2990
|
if (sourceContent !== targetContent) {
|
|
2982
2991
|
console.log(
|
|
2983
2992
|
chalk35.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
@@ -2994,21 +3003,21 @@ async function syncClaudeMd(claudeDir, targetBase) {
|
|
|
2994
3003
|
}
|
|
2995
3004
|
}
|
|
2996
3005
|
}
|
|
2997
|
-
|
|
3006
|
+
fs17.copyFileSync(source, target);
|
|
2998
3007
|
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
2999
3008
|
}
|
|
3000
3009
|
|
|
3001
3010
|
// src/commands/sync/syncSettings.ts
|
|
3002
|
-
import * as
|
|
3003
|
-
import * as
|
|
3011
|
+
import * as fs18 from "fs";
|
|
3012
|
+
import * as path17 from "path";
|
|
3004
3013
|
import chalk36 from "chalk";
|
|
3005
3014
|
async function syncSettings(claudeDir, targetBase) {
|
|
3006
|
-
const source =
|
|
3007
|
-
const target =
|
|
3008
|
-
const sourceContent =
|
|
3015
|
+
const source = path17.join(claudeDir, "settings.json");
|
|
3016
|
+
const target = path17.join(targetBase, "settings.json");
|
|
3017
|
+
const sourceContent = fs18.readFileSync(source, "utf-8");
|
|
3009
3018
|
const normalizedSource = JSON.stringify(JSON.parse(sourceContent), null, 2);
|
|
3010
|
-
if (
|
|
3011
|
-
const targetContent =
|
|
3019
|
+
if (fs18.existsSync(target)) {
|
|
3020
|
+
const targetContent = fs18.readFileSync(target, "utf-8");
|
|
3012
3021
|
const normalizedTarget = JSON.stringify(JSON.parse(targetContent), null, 2);
|
|
3013
3022
|
if (normalizedSource !== normalizedTarget) {
|
|
3014
3023
|
console.log(
|
|
@@ -3026,27 +3035,27 @@ async function syncSettings(claudeDir, targetBase) {
|
|
|
3026
3035
|
}
|
|
3027
3036
|
}
|
|
3028
3037
|
}
|
|
3029
|
-
|
|
3038
|
+
fs18.copyFileSync(source, target);
|
|
3030
3039
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
3031
3040
|
}
|
|
3032
3041
|
|
|
3033
3042
|
// src/commands/sync.ts
|
|
3034
3043
|
var __filename2 = fileURLToPath3(import.meta.url);
|
|
3035
|
-
var __dirname4 =
|
|
3044
|
+
var __dirname4 = path18.dirname(__filename2);
|
|
3036
3045
|
async function sync() {
|
|
3037
|
-
const claudeDir =
|
|
3038
|
-
const targetBase =
|
|
3046
|
+
const claudeDir = path18.join(__dirname4, "..", "claude");
|
|
3047
|
+
const targetBase = path18.join(os.homedir(), ".claude");
|
|
3039
3048
|
syncCommands(claudeDir, targetBase);
|
|
3040
3049
|
await syncSettings(claudeDir, targetBase);
|
|
3041
3050
|
await syncClaudeMd(claudeDir, targetBase);
|
|
3042
3051
|
}
|
|
3043
3052
|
function syncCommands(claudeDir, targetBase) {
|
|
3044
|
-
const sourceDir =
|
|
3045
|
-
const targetDir =
|
|
3046
|
-
|
|
3047
|
-
const files =
|
|
3053
|
+
const sourceDir = path18.join(claudeDir, "commands");
|
|
3054
|
+
const targetDir = path18.join(targetBase, "commands");
|
|
3055
|
+
fs19.mkdirSync(targetDir, { recursive: true });
|
|
3056
|
+
const files = fs19.readdirSync(sourceDir);
|
|
3048
3057
|
for (const file of files) {
|
|
3049
|
-
|
|
3058
|
+
fs19.copyFileSync(path18.join(sourceDir, file), path18.join(targetDir, file));
|
|
3050
3059
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
3051
3060
|
}
|
|
3052
3061
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
@@ -3168,58 +3177,7 @@ async function configure() {
|
|
|
3168
3177
|
import { existsSync as existsSync16, mkdirSync as mkdirSync5, readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "fs";
|
|
3169
3178
|
import { basename as basename4, dirname as dirname11, join as join17 } from "path";
|
|
3170
3179
|
|
|
3171
|
-
// src/commands/transcript/
|
|
3172
|
-
function parseTimestamp(ts4) {
|
|
3173
|
-
const parts = ts4.split(":");
|
|
3174
|
-
let hours = 0;
|
|
3175
|
-
let minutes = 0;
|
|
3176
|
-
let seconds = 0;
|
|
3177
|
-
if (parts.length === 3) {
|
|
3178
|
-
hours = Number.parseInt(parts[0], 10);
|
|
3179
|
-
minutes = Number.parseInt(parts[1], 10);
|
|
3180
|
-
seconds = Number.parseFloat(parts[2]);
|
|
3181
|
-
} else if (parts.length === 2) {
|
|
3182
|
-
minutes = Number.parseInt(parts[0], 10);
|
|
3183
|
-
seconds = Number.parseFloat(parts[1]);
|
|
3184
|
-
}
|
|
3185
|
-
return Math.round((hours * 3600 + minutes * 60 + seconds) * 1e3);
|
|
3186
|
-
}
|
|
3187
|
-
function parseVtt(content) {
|
|
3188
|
-
const cues = [];
|
|
3189
|
-
const lines = content.split(/\r?\n/);
|
|
3190
|
-
let i = 0;
|
|
3191
|
-
while (i < lines.length && !lines[i].includes("-->")) {
|
|
3192
|
-
i++;
|
|
3193
|
-
}
|
|
3194
|
-
while (i < lines.length) {
|
|
3195
|
-
const line = lines[i].trim();
|
|
3196
|
-
if (line.includes("-->")) {
|
|
3197
|
-
const [startStr, endStr] = line.split("-->").map((s) => s.trim());
|
|
3198
|
-
const startMs = parseTimestamp(startStr);
|
|
3199
|
-
const endMs = parseTimestamp(endStr);
|
|
3200
|
-
const textLines = [];
|
|
3201
|
-
i++;
|
|
3202
|
-
while (i < lines.length && lines[i].trim() && !lines[i].includes("-->")) {
|
|
3203
|
-
textLines.push(lines[i].trim());
|
|
3204
|
-
i++;
|
|
3205
|
-
}
|
|
3206
|
-
const fullText = textLines.join(" ");
|
|
3207
|
-
const speakerMatch = fullText.match(/^<v\s+([^>]+)>/);
|
|
3208
|
-
let speaker = null;
|
|
3209
|
-
let text = fullText;
|
|
3210
|
-
if (speakerMatch) {
|
|
3211
|
-
speaker = speakerMatch[1];
|
|
3212
|
-
text = fullText.replace(/<v\s+[^>]+>/, "").trim();
|
|
3213
|
-
}
|
|
3214
|
-
if (text) {
|
|
3215
|
-
cues.push({ startMs, endMs, speaker, text });
|
|
3216
|
-
}
|
|
3217
|
-
} else {
|
|
3218
|
-
i++;
|
|
3219
|
-
}
|
|
3220
|
-
}
|
|
3221
|
-
return cues;
|
|
3222
|
-
}
|
|
3180
|
+
// src/commands/transcript/deduplicateCues.ts
|
|
3223
3181
|
function removeSubstringDuplicates(cues) {
|
|
3224
3182
|
const toRemove = /* @__PURE__ */ new Set();
|
|
3225
3183
|
for (let i = 0; i < cues.length; i++) {
|
|
@@ -3305,6 +3263,59 @@ function deduplicateCues(cues) {
|
|
|
3305
3263
|
}));
|
|
3306
3264
|
}
|
|
3307
3265
|
|
|
3266
|
+
// src/commands/transcript/parseVtt.ts
|
|
3267
|
+
function parseTimestamp(ts5) {
|
|
3268
|
+
const parts = ts5.split(":");
|
|
3269
|
+
let hours = 0;
|
|
3270
|
+
let minutes = 0;
|
|
3271
|
+
let seconds = 0;
|
|
3272
|
+
if (parts.length === 3) {
|
|
3273
|
+
hours = Number.parseInt(parts[0], 10);
|
|
3274
|
+
minutes = Number.parseInt(parts[1], 10);
|
|
3275
|
+
seconds = Number.parseFloat(parts[2]);
|
|
3276
|
+
} else if (parts.length === 2) {
|
|
3277
|
+
minutes = Number.parseInt(parts[0], 10);
|
|
3278
|
+
seconds = Number.parseFloat(parts[1]);
|
|
3279
|
+
}
|
|
3280
|
+
return Math.round((hours * 3600 + minutes * 60 + seconds) * 1e3);
|
|
3281
|
+
}
|
|
3282
|
+
function parseVtt(content) {
|
|
3283
|
+
const cues = [];
|
|
3284
|
+
const lines = content.split(/\r?\n/);
|
|
3285
|
+
let i = 0;
|
|
3286
|
+
while (i < lines.length && !lines[i].includes("-->")) {
|
|
3287
|
+
i++;
|
|
3288
|
+
}
|
|
3289
|
+
while (i < lines.length) {
|
|
3290
|
+
const line = lines[i].trim();
|
|
3291
|
+
if (line.includes("-->")) {
|
|
3292
|
+
const [startStr, endStr] = line.split("-->").map((s) => s.trim());
|
|
3293
|
+
const startMs = parseTimestamp(startStr);
|
|
3294
|
+
const endMs = parseTimestamp(endStr);
|
|
3295
|
+
const textLines = [];
|
|
3296
|
+
i++;
|
|
3297
|
+
while (i < lines.length && lines[i].trim() && !lines[i].includes("-->")) {
|
|
3298
|
+
textLines.push(lines[i].trim());
|
|
3299
|
+
i++;
|
|
3300
|
+
}
|
|
3301
|
+
const fullText = textLines.join(" ");
|
|
3302
|
+
const speakerMatch = fullText.match(/^<v\s+([^>]+)>/);
|
|
3303
|
+
let speaker = null;
|
|
3304
|
+
let text = fullText;
|
|
3305
|
+
if (speakerMatch) {
|
|
3306
|
+
speaker = speakerMatch[1];
|
|
3307
|
+
text = fullText.replace(/<v\s+[^>]+>/, "").trim();
|
|
3308
|
+
}
|
|
3309
|
+
if (text) {
|
|
3310
|
+
cues.push({ startMs, endMs, speaker, text });
|
|
3311
|
+
}
|
|
3312
|
+
} else {
|
|
3313
|
+
i++;
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
return cues;
|
|
3317
|
+
}
|
|
3318
|
+
|
|
3308
3319
|
// src/commands/transcript/formatChatLog.ts
|
|
3309
3320
|
function cuesToChatMessages(cues) {
|
|
3310
3321
|
const messages = [];
|
|
@@ -3618,7 +3629,7 @@ Total: ${lines.length} hardcoded color(s)`);
|
|
|
3618
3629
|
|
|
3619
3630
|
// src/commands/verify/run.ts
|
|
3620
3631
|
import { spawn as spawn4 } from "child_process";
|
|
3621
|
-
import * as
|
|
3632
|
+
import * as path19 from "path";
|
|
3622
3633
|
function formatDuration(ms) {
|
|
3623
3634
|
if (ms < 1e3) {
|
|
3624
3635
|
return `${ms}ms`;
|
|
@@ -3648,7 +3659,7 @@ async function run2(options = {}) {
|
|
|
3648
3659
|
return;
|
|
3649
3660
|
}
|
|
3650
3661
|
const { packageJsonPath, verifyScripts } = result;
|
|
3651
|
-
const packageDir =
|
|
3662
|
+
const packageDir = path19.dirname(packageJsonPath);
|
|
3652
3663
|
console.log(`Running ${verifyScripts.length} verify script(s) in parallel:`);
|
|
3653
3664
|
for (const script of verifyScripts) {
|
|
3654
3665
|
console.log(` - ${script}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@staff0rd/assist",
|
|
3
|
-
"version": "0.42.
|
|
3
|
+
"version": "0.42.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"verify:types": "tsc --noEmit",
|
|
22
22
|
"verify:knip": "knip --no-progress --treat-config-hints-as-errors",
|
|
23
23
|
"verify:duplicate-code": "jscpd --format 'typescript,tsx' --exitCode 1 --ignore '**/*.test.*' -r consoleFull src",
|
|
24
|
-
"verify:maintainability": "assist complexity maintainability ./src --threshold
|
|
24
|
+
"verify:maintainability": "assist complexity maintainability ./src --threshold 55",
|
|
25
25
|
"verify:custom-lint": "assist lint"
|
|
26
26
|
},
|
|
27
27
|
"keywords": [],
|