@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
- type ImportViolation = {
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: ImportViolation[] = [];
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(): ImportViolation[] {
27
+ function checkStaticImports(): LintViolation[] {
34
28
  const sourceFiles = findSourceFiles("src");
35
- const violations: ImportViolation[] = [];
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
- const violations = checkStaticImports();
46
- if (violations.length > 0) {
47
- console.error(chalk.red("\nStatic import check failed:\n"));
48
- console.error(
49
- chalk.red(
50
- " Dynamic imports (require() and import()) are not allowed. Use static imports instead.\n",
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 (patchVersion && minorVersion) {
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/runStaticImportCheck.ts
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 checkForDynamicImports(filePath) {
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
- const violations = checkStaticImports();
1433
- if (violations.length > 0) {
1434
- console.error(chalk24.red("\nStatic import check failed:\n"));
1435
- console.error(
1436
- chalk24.red(
1437
- " Dynamic imports (require() and import()) are not allowed. Use static imports instead.\n"
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
- if (!fileNamePassed || !staticImportPassed) {
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 fs9 from "fs";
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
- fs9.chmodSync(snoreToastPath, 493);
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 fs11 from "fs";
1770
+ import fs12 from "fs";
1714
1771
  import { minimatch } from "minimatch";
1715
1772
 
1716
1773
  // src/commands/refactor/getIgnoredFiles.ts
1717
- import fs10 from "fs";
1774
+ import fs11 from "fs";
1718
1775
  var REFACTOR_YML_PATH = "refactor.yml";
1719
1776
  function parseRefactorYml() {
1720
- if (!fs10.existsSync(REFACTOR_YML_PATH)) {
1777
+ if (!fs11.existsSync(REFACTOR_YML_PATH)) {
1721
1778
  return [];
1722
1779
  }
1723
- const content = fs10.readFileSync(REFACTOR_YML_PATH, "utf-8");
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 = fs11.readFileSync(filePath, "utf-8");
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 fs12 from "fs";
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 (!fs12.existsSync(file)) {
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 = fs12.readFileSync(file, "utf-8");
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 (fs12.existsSync(REFACTOR_YML_PATH2)) {
1928
- const existing = fs12.readFileSync(REFACTOR_YML_PATH2, "utf-8");
1929
- fs12.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
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
- fs12.writeFileSync(REFACTOR_YML_PATH2, entry);
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 fs14 from "fs";
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 fs13 from "fs";
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 = fs13.readFileSync(source, "utf-8");
2094
+ const sourceContent = fs14.readFileSync(source, "utf-8");
2038
2095
  const normalizedSource = JSON.stringify(JSON.parse(sourceContent), null, 2);
2039
- if (fs13.existsSync(target)) {
2040
- const targetContent = fs13.readFileSync(target, "utf-8");
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
- fs13.copyFileSync(source, target);
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
- fs14.mkdirSync(targetDir, { recursive: true });
2075
- const files = fs14.readdirSync(sourceDir);
2131
+ fs15.mkdirSync(targetDir, { recursive: true });
2132
+ const files = fs15.readdirSync(sourceDir);
2076
2133
  for (const file of files) {
2077
- fs14.copyFileSync(path16.join(sourceDir, file), path16.join(targetDir, file));
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`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {