@staff0rd/assist 0.17.0 → 0.18.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.
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// Implements conventions not enforced by biomejs
|
|
2
2
|
import { runFileNameCheck } from "./runFileNameCheck";
|
|
3
|
+
import { runImportExtensionCheck } from "./runImportExtensionCheck";
|
|
3
4
|
import { runStaticImportCheck } from "./runStaticImportCheck";
|
|
4
5
|
|
|
5
6
|
export function lint(): void {
|
|
6
7
|
const fileNamePassed = runFileNameCheck();
|
|
7
8
|
const staticImportPassed = runStaticImportCheck();
|
|
9
|
+
const importExtensionPassed = runImportExtensionCheck();
|
|
8
10
|
|
|
9
|
-
if (!fileNamePassed || !staticImportPassed) {
|
|
11
|
+
if (!fileNamePassed || !staticImportPassed || !importExtensionPassed) {
|
|
10
12
|
process.exit(1);
|
|
11
13
|
}
|
|
12
14
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { findSourceFiles } from "../../shared/findSourceFiles";
|
|
3
|
+
import { type LintViolation, reportViolations } from "./shared";
|
|
4
|
+
|
|
5
|
+
function checkForImportExtensions(filePath: string): LintViolation[] {
|
|
6
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
7
|
+
const lines = content.split("\n");
|
|
8
|
+
const violations: LintViolation[] = [];
|
|
9
|
+
|
|
10
|
+
// Matches relative imports with .js or .ts extensions
|
|
11
|
+
const importExtensionPattern = /from\s+["']\..*\.(js|ts)["']/;
|
|
12
|
+
|
|
13
|
+
for (let i = 0; i < lines.length; i++) {
|
|
14
|
+
const line = lines[i];
|
|
15
|
+
if (importExtensionPattern.test(line)) {
|
|
16
|
+
violations.push({
|
|
17
|
+
filePath,
|
|
18
|
+
line: i + 1,
|
|
19
|
+
content: line.trim(),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return violations;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function checkImportExtensions(): LintViolation[] {
|
|
28
|
+
const sourceFiles = findSourceFiles("src");
|
|
29
|
+
const violations: LintViolation[] = [];
|
|
30
|
+
|
|
31
|
+
for (const filePath of sourceFiles) {
|
|
32
|
+
violations.push(...checkForImportExtensions(filePath));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return violations;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function runImportExtensionCheck(): boolean {
|
|
39
|
+
return reportViolations(
|
|
40
|
+
checkImportExtensions(),
|
|
41
|
+
"Import extension check",
|
|
42
|
+
"File extensions in imports are not allowed. Use extensionless imports instead.",
|
|
43
|
+
"Import extension check passed. No file extensions in imports found.",
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import chalk from "chalk";
|
|
3
2
|
import { findSourceFiles } from "../../shared/findSourceFiles";
|
|
3
|
+
import { type LintViolation, reportViolations } from "./shared";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
filePath: string;
|
|
7
|
-
line: number;
|
|
8
|
-
content: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
function checkForDynamicImports(filePath: string): ImportViolation[] {
|
|
5
|
+
function checkForDynamicImports(filePath: string): LintViolation[] {
|
|
12
6
|
const content = fs.readFileSync(filePath, "utf-8");
|
|
13
7
|
const lines = content.split("\n");
|
|
14
|
-
const violations:
|
|
8
|
+
const violations: LintViolation[] = [];
|
|
15
9
|
|
|
16
10
|
const requirePattern = /\brequire\s*\(/;
|
|
17
11
|
const dynamicImportPattern = /\bimport\s*\(/;
|
|
@@ -30,9 +24,9 @@ function checkForDynamicImports(filePath: string): ImportViolation[] {
|
|
|
30
24
|
return violations;
|
|
31
25
|
}
|
|
32
26
|
|
|
33
|
-
function checkStaticImports():
|
|
27
|
+
function checkStaticImports(): LintViolation[] {
|
|
34
28
|
const sourceFiles = findSourceFiles("src");
|
|
35
|
-
const violations:
|
|
29
|
+
const violations: LintViolation[] = [];
|
|
36
30
|
|
|
37
31
|
for (const filePath of sourceFiles) {
|
|
38
32
|
violations.push(...checkForDynamicImports(filePath));
|
|
@@ -42,23 +36,10 @@ function checkStaticImports(): ImportViolation[] {
|
|
|
42
36
|
}
|
|
43
37
|
|
|
44
38
|
export function runStaticImportCheck(): boolean {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
),
|
|
52
|
-
);
|
|
53
|
-
for (const violation of violations) {
|
|
54
|
-
console.error(chalk.red(` ${violation.filePath}:${violation.line}`));
|
|
55
|
-
console.error(chalk.gray(` ${violation.content}\n`));
|
|
56
|
-
}
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (!process.env.CLAUDECODE) {
|
|
61
|
-
console.log("Static import check passed. No dynamic imports found.");
|
|
62
|
-
}
|
|
63
|
-
return true;
|
|
39
|
+
return reportViolations(
|
|
40
|
+
checkStaticImports(),
|
|
41
|
+
"Static import check",
|
|
42
|
+
"Dynamic imports (require() and import()) are not allowed. Use static imports instead.",
|
|
43
|
+
"Static import check passed. No dynamic imports found.",
|
|
44
|
+
);
|
|
64
45
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
|
|
3
|
+
export type LintViolation = {
|
|
4
|
+
filePath: string;
|
|
5
|
+
line: number;
|
|
6
|
+
content: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function reportViolations(
|
|
10
|
+
violations: LintViolation[],
|
|
11
|
+
checkName: string,
|
|
12
|
+
errorMessage: string,
|
|
13
|
+
successMessage: string,
|
|
14
|
+
): boolean {
|
|
15
|
+
if (violations.length > 0) {
|
|
16
|
+
console.error(chalk.red(`\n${checkName} failed:\n`));
|
|
17
|
+
console.error(chalk.red(` ${errorMessage}\n`));
|
|
18
|
+
for (const violation of violations) {
|
|
19
|
+
console.error(chalk.red(` ${violation.filePath}:${violation.line}`));
|
|
20
|
+
console.error(chalk.gray(` ${violation.content}\n`));
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!process.env.CLAUDECODE) {
|
|
26
|
+
console.log(successMessage);
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -453,9 +453,6 @@ function getLastVersionInfoFromGit() {
|
|
|
453
453
|
}
|
|
454
454
|
}
|
|
455
455
|
function getLastVersionInfo(repoName, config) {
|
|
456
|
-
if (config?.commit?.conventional) {
|
|
457
|
-
return getLastVersionInfoFromGit();
|
|
458
|
-
}
|
|
459
456
|
const entries = loadDevlogEntries(repoName);
|
|
460
457
|
if (entries.size === 0) {
|
|
461
458
|
return null;
|
|
@@ -465,6 +462,12 @@ function getLastVersionInfo(repoName, config) {
|
|
|
465
462
|
if (!lastDate) {
|
|
466
463
|
return null;
|
|
467
464
|
}
|
|
465
|
+
if (config?.commit?.conventional) {
|
|
466
|
+
const gitInfo = getLastVersionInfoFromGit();
|
|
467
|
+
if (gitInfo) {
|
|
468
|
+
return { date: lastDate, version: gitInfo.version };
|
|
469
|
+
}
|
|
470
|
+
}
|
|
468
471
|
const lastEntries = entries.get(lastDate);
|
|
469
472
|
const lastVersion = lastEntries?.[0]?.version;
|
|
470
473
|
if (!lastVersion) {
|
|
@@ -529,7 +532,14 @@ function next(options) {
|
|
|
529
532
|
}
|
|
530
533
|
const commits = commitsByDate.get(targetDate) ?? [];
|
|
531
534
|
console.log(`${chalk6.bold("name:")} ${repoName}`);
|
|
532
|
-
if (
|
|
535
|
+
if (config.commit?.conventional && commits.length > 0) {
|
|
536
|
+
const version2 = getVersionAtCommit(commits[0].hash);
|
|
537
|
+
if (version2) {
|
|
538
|
+
console.log(`${chalk6.bold("version:")} ${stripToMinor(version2)}`);
|
|
539
|
+
} else {
|
|
540
|
+
console.log(`${chalk6.bold("version:")} ${chalk6.red("unknown")}`);
|
|
541
|
+
}
|
|
542
|
+
} else if (patchVersion && minorVersion) {
|
|
533
543
|
console.log(
|
|
534
544
|
`${chalk6.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
535
545
|
);
|
|
@@ -1399,13 +1409,72 @@ function runFileNameCheck() {
|
|
|
1399
1409
|
return true;
|
|
1400
1410
|
}
|
|
1401
1411
|
|
|
1402
|
-
// src/commands/lint/
|
|
1412
|
+
// src/commands/lint/runImportExtensionCheck.ts
|
|
1403
1413
|
import fs8 from "fs";
|
|
1414
|
+
|
|
1415
|
+
// src/commands/lint/shared.ts
|
|
1404
1416
|
import chalk24 from "chalk";
|
|
1405
|
-
function
|
|
1417
|
+
function reportViolations(violations, checkName, errorMessage, successMessage) {
|
|
1418
|
+
if (violations.length > 0) {
|
|
1419
|
+
console.error(chalk24.red(`
|
|
1420
|
+
${checkName} failed:
|
|
1421
|
+
`));
|
|
1422
|
+
console.error(chalk24.red(` ${errorMessage}
|
|
1423
|
+
`));
|
|
1424
|
+
for (const violation of violations) {
|
|
1425
|
+
console.error(chalk24.red(` ${violation.filePath}:${violation.line}`));
|
|
1426
|
+
console.error(chalk24.gray(` ${violation.content}
|
|
1427
|
+
`));
|
|
1428
|
+
}
|
|
1429
|
+
return false;
|
|
1430
|
+
}
|
|
1431
|
+
if (!process.env.CLAUDECODE) {
|
|
1432
|
+
console.log(successMessage);
|
|
1433
|
+
}
|
|
1434
|
+
return true;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
// src/commands/lint/runImportExtensionCheck.ts
|
|
1438
|
+
function checkForImportExtensions(filePath) {
|
|
1406
1439
|
const content = fs8.readFileSync(filePath, "utf-8");
|
|
1407
1440
|
const lines = content.split("\n");
|
|
1408
1441
|
const violations = [];
|
|
1442
|
+
const importExtensionPattern = /from\s+["']\..*\.(js|ts)["']/;
|
|
1443
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1444
|
+
const line = lines[i];
|
|
1445
|
+
if (importExtensionPattern.test(line)) {
|
|
1446
|
+
violations.push({
|
|
1447
|
+
filePath,
|
|
1448
|
+
line: i + 1,
|
|
1449
|
+
content: line.trim()
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
return violations;
|
|
1454
|
+
}
|
|
1455
|
+
function checkImportExtensions() {
|
|
1456
|
+
const sourceFiles = findSourceFiles("src");
|
|
1457
|
+
const violations = [];
|
|
1458
|
+
for (const filePath of sourceFiles) {
|
|
1459
|
+
violations.push(...checkForImportExtensions(filePath));
|
|
1460
|
+
}
|
|
1461
|
+
return violations;
|
|
1462
|
+
}
|
|
1463
|
+
function runImportExtensionCheck() {
|
|
1464
|
+
return reportViolations(
|
|
1465
|
+
checkImportExtensions(),
|
|
1466
|
+
"Import extension check",
|
|
1467
|
+
"File extensions in imports are not allowed. Use extensionless imports instead.",
|
|
1468
|
+
"Import extension check passed. No file extensions in imports found."
|
|
1469
|
+
);
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
// src/commands/lint/runStaticImportCheck.ts
|
|
1473
|
+
import fs9 from "fs";
|
|
1474
|
+
function checkForDynamicImports(filePath) {
|
|
1475
|
+
const content = fs9.readFileSync(filePath, "utf-8");
|
|
1476
|
+
const lines = content.split("\n");
|
|
1477
|
+
const violations = [];
|
|
1409
1478
|
const requirePattern = /\brequire\s*\(/;
|
|
1410
1479
|
const dynamicImportPattern = /\bimport\s*\(/;
|
|
1411
1480
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -1429,32 +1498,20 @@ function checkStaticImports() {
|
|
|
1429
1498
|
return violations;
|
|
1430
1499
|
}
|
|
1431
1500
|
function runStaticImportCheck() {
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
)
|
|
1439
|
-
);
|
|
1440
|
-
for (const violation of violations) {
|
|
1441
|
-
console.error(chalk24.red(` ${violation.filePath}:${violation.line}`));
|
|
1442
|
-
console.error(chalk24.gray(` ${violation.content}
|
|
1443
|
-
`));
|
|
1444
|
-
}
|
|
1445
|
-
return false;
|
|
1446
|
-
}
|
|
1447
|
-
if (!process.env.CLAUDECODE) {
|
|
1448
|
-
console.log("Static import check passed. No dynamic imports found.");
|
|
1449
|
-
}
|
|
1450
|
-
return true;
|
|
1501
|
+
return reportViolations(
|
|
1502
|
+
checkStaticImports(),
|
|
1503
|
+
"Static import check",
|
|
1504
|
+
"Dynamic imports (require() and import()) are not allowed. Use static imports instead.",
|
|
1505
|
+
"Static import check passed. No dynamic imports found."
|
|
1506
|
+
);
|
|
1451
1507
|
}
|
|
1452
1508
|
|
|
1453
1509
|
// src/commands/lint/lint.ts
|
|
1454
1510
|
function lint() {
|
|
1455
1511
|
const fileNamePassed = runFileNameCheck();
|
|
1456
1512
|
const staticImportPassed = runStaticImportCheck();
|
|
1457
|
-
|
|
1513
|
+
const importExtensionPassed = runImportExtensionCheck();
|
|
1514
|
+
if (!fileNamePassed || !staticImportPassed || !importExtensionPassed) {
|
|
1458
1515
|
process.exit(1);
|
|
1459
1516
|
}
|
|
1460
1517
|
}
|
|
@@ -1529,7 +1586,7 @@ function detectPlatform() {
|
|
|
1529
1586
|
|
|
1530
1587
|
// src/commands/notify/showWindowsNotificationFromWsl.ts
|
|
1531
1588
|
import { spawn } from "child_process";
|
|
1532
|
-
import
|
|
1589
|
+
import fs10 from "fs";
|
|
1533
1590
|
import { createRequire } from "module";
|
|
1534
1591
|
import path13 from "path";
|
|
1535
1592
|
var require2 = createRequire(import.meta.url);
|
|
@@ -1541,7 +1598,7 @@ function showWindowsNotificationFromWsl(options) {
|
|
|
1541
1598
|
const { title, message, sound } = options;
|
|
1542
1599
|
const snoreToastPath = getSnoreToastPath();
|
|
1543
1600
|
try {
|
|
1544
|
-
|
|
1601
|
+
fs10.chmodSync(snoreToastPath, 493);
|
|
1545
1602
|
} catch {
|
|
1546
1603
|
}
|
|
1547
1604
|
const args = ["-t", title, "-m", message];
|
|
@@ -1710,17 +1767,17 @@ import * as path14 from "path";
|
|
|
1710
1767
|
|
|
1711
1768
|
// src/commands/refactor/getViolations.ts
|
|
1712
1769
|
import { execSync as execSync12 } from "child_process";
|
|
1713
|
-
import
|
|
1770
|
+
import fs12 from "fs";
|
|
1714
1771
|
import { minimatch } from "minimatch";
|
|
1715
1772
|
|
|
1716
1773
|
// src/commands/refactor/getIgnoredFiles.ts
|
|
1717
|
-
import
|
|
1774
|
+
import fs11 from "fs";
|
|
1718
1775
|
var REFACTOR_YML_PATH = "refactor.yml";
|
|
1719
1776
|
function parseRefactorYml() {
|
|
1720
|
-
if (!
|
|
1777
|
+
if (!fs11.existsSync(REFACTOR_YML_PATH)) {
|
|
1721
1778
|
return [];
|
|
1722
1779
|
}
|
|
1723
|
-
const content =
|
|
1780
|
+
const content = fs11.readFileSync(REFACTOR_YML_PATH, "utf-8");
|
|
1724
1781
|
const entries = [];
|
|
1725
1782
|
const lines = content.split("\n");
|
|
1726
1783
|
let currentEntry = {};
|
|
@@ -1805,7 +1862,7 @@ Refactor check failed:
|
|
|
1805
1862
|
|
|
1806
1863
|
// src/commands/refactor/getViolations.ts
|
|
1807
1864
|
function countLines(filePath) {
|
|
1808
|
-
const content =
|
|
1865
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
1809
1866
|
return content.split("\n").length;
|
|
1810
1867
|
}
|
|
1811
1868
|
function getGitFiles(options) {
|
|
@@ -1910,25 +1967,25 @@ async function check(pattern2, options) {
|
|
|
1910
1967
|
}
|
|
1911
1968
|
|
|
1912
1969
|
// src/commands/refactor/ignore.ts
|
|
1913
|
-
import
|
|
1970
|
+
import fs13 from "fs";
|
|
1914
1971
|
import chalk27 from "chalk";
|
|
1915
1972
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
1916
1973
|
function ignore(file) {
|
|
1917
|
-
if (!
|
|
1974
|
+
if (!fs13.existsSync(file)) {
|
|
1918
1975
|
console.error(chalk27.red(`Error: File does not exist: ${file}`));
|
|
1919
1976
|
process.exit(1);
|
|
1920
1977
|
}
|
|
1921
|
-
const content =
|
|
1978
|
+
const content = fs13.readFileSync(file, "utf-8");
|
|
1922
1979
|
const lineCount = content.split("\n").length;
|
|
1923
1980
|
const maxLines = lineCount + 10;
|
|
1924
1981
|
const entry = `- file: ${file}
|
|
1925
1982
|
maxLines: ${maxLines}
|
|
1926
1983
|
`;
|
|
1927
|
-
if (
|
|
1928
|
-
const existing =
|
|
1929
|
-
|
|
1984
|
+
if (fs13.existsSync(REFACTOR_YML_PATH2)) {
|
|
1985
|
+
const existing = fs13.readFileSync(REFACTOR_YML_PATH2, "utf-8");
|
|
1986
|
+
fs13.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
|
|
1930
1987
|
} else {
|
|
1931
|
-
|
|
1988
|
+
fs13.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
1932
1989
|
}
|
|
1933
1990
|
console.log(
|
|
1934
1991
|
chalk27.green(
|
|
@@ -2022,22 +2079,22 @@ async function statusLine() {
|
|
|
2022
2079
|
}
|
|
2023
2080
|
|
|
2024
2081
|
// src/commands/sync.ts
|
|
2025
|
-
import * as
|
|
2082
|
+
import * as fs15 from "fs";
|
|
2026
2083
|
import * as os from "os";
|
|
2027
2084
|
import * as path16 from "path";
|
|
2028
2085
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
2029
2086
|
|
|
2030
2087
|
// src/commands/sync/syncSettings.ts
|
|
2031
|
-
import * as
|
|
2088
|
+
import * as fs14 from "fs";
|
|
2032
2089
|
import * as path15 from "path";
|
|
2033
2090
|
import chalk28 from "chalk";
|
|
2034
2091
|
async function syncSettings(claudeDir, targetBase) {
|
|
2035
2092
|
const source = path15.join(claudeDir, "settings.json");
|
|
2036
2093
|
const target = path15.join(targetBase, "settings.json");
|
|
2037
|
-
const sourceContent =
|
|
2094
|
+
const sourceContent = fs14.readFileSync(source, "utf-8");
|
|
2038
2095
|
const normalizedSource = JSON.stringify(JSON.parse(sourceContent), null, 2);
|
|
2039
|
-
if (
|
|
2040
|
-
const targetContent =
|
|
2096
|
+
if (fs14.existsSync(target)) {
|
|
2097
|
+
const targetContent = fs14.readFileSync(target, "utf-8");
|
|
2041
2098
|
const normalizedTarget = JSON.stringify(JSON.parse(targetContent), null, 2);
|
|
2042
2099
|
if (normalizedSource !== normalizedTarget) {
|
|
2043
2100
|
console.log(
|
|
@@ -2055,7 +2112,7 @@ async function syncSettings(claudeDir, targetBase) {
|
|
|
2055
2112
|
}
|
|
2056
2113
|
}
|
|
2057
2114
|
}
|
|
2058
|
-
|
|
2115
|
+
fs14.copyFileSync(source, target);
|
|
2059
2116
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
2060
2117
|
}
|
|
2061
2118
|
|
|
@@ -2071,10 +2128,10 @@ async function sync() {
|
|
|
2071
2128
|
function syncCommands(claudeDir, targetBase) {
|
|
2072
2129
|
const sourceDir = path16.join(claudeDir, "commands");
|
|
2073
2130
|
const targetDir = path16.join(targetBase, "commands");
|
|
2074
|
-
|
|
2075
|
-
const files =
|
|
2131
|
+
fs15.mkdirSync(targetDir, { recursive: true });
|
|
2132
|
+
const files = fs15.readdirSync(sourceDir);
|
|
2076
2133
|
for (const file of files) {
|
|
2077
|
-
|
|
2134
|
+
fs15.copyFileSync(path16.join(sourceDir, file), path16.join(targetDir, file));
|
|
2078
2135
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
2079
2136
|
}
|
|
2080
2137
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|