@staff0rd/assist 0.16.0 → 0.17.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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +72 -66
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -51,5 +51,6 @@ After installation, the `assist` command will be available globally.
51
51
  - `assist devlog version` - Show current repo name and version info
52
52
  - `assist vscode init` - Add VS Code configuration files
53
53
  - `assist deploy init` - Initialize Netlify project and configure deployment
54
+ - `assist notify` - Show desktop notification from JSON stdin (supports macOS, Windows, WSL)
54
55
  - `assist status-line` - Format Claude Code status line from JSON stdin
55
56
 
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { execSync as execSync13 } from "child_process";
4
+ import { execSync as execSync14 } from "child_process";
5
5
  import { Command } from "commander";
6
6
 
7
7
  // src/commands/commit.ts
@@ -414,12 +414,48 @@ function list(options) {
414
414
  }
415
415
 
416
416
  // src/commands/devlog/next.ts
417
- import { execSync as execSync5 } from "child_process";
417
+ import { execSync as execSync6 } from "child_process";
418
418
  import chalk6 from "chalk";
419
419
 
420
420
  // src/commands/devlog/getLastVersionInfo.ts
421
+ import { execSync as execSync5 } from "child_process";
421
422
  import semver from "semver";
422
- function getLastVersionInfo(repoName) {
423
+ function getVersionAtCommit(hash) {
424
+ try {
425
+ const content = execSync5(`git show ${hash}:package.json`, {
426
+ encoding: "utf-8"
427
+ });
428
+ const pkg = JSON.parse(content);
429
+ return pkg.version ?? null;
430
+ } catch {
431
+ return null;
432
+ }
433
+ }
434
+ function stripToMinor(version2) {
435
+ const parsed = semver.parse(semver.coerce(version2));
436
+ return parsed ? `v${parsed.major}.${parsed.minor}` : `v${version2}`;
437
+ }
438
+ function getLastVersionInfoFromGit() {
439
+ try {
440
+ const output = execSync5(
441
+ "git log -1 --pretty=format:'%ad|%h' --date=short",
442
+ {
443
+ encoding: "utf-8"
444
+ }
445
+ ).trim();
446
+ const [date, hash] = output.split("|");
447
+ if (!date || !hash) return null;
448
+ const version2 = getVersionAtCommit(hash);
449
+ if (!version2) return null;
450
+ return { date, version: stripToMinor(version2) };
451
+ } catch {
452
+ return null;
453
+ }
454
+ }
455
+ function getLastVersionInfo(repoName, config) {
456
+ if (config?.commit?.conventional) {
457
+ return getLastVersionInfoFromGit();
458
+ }
423
459
  const entries = loadDevlogEntries(repoName);
424
460
  if (entries.size === 0) {
425
461
  return null;
@@ -458,11 +494,11 @@ function next(options) {
458
494
  const ignore2 = options.ignore ?? config.devlog?.ignore ?? [];
459
495
  const skipDays = new Set(config.devlog?.skip?.days ?? []);
460
496
  const repoName = getRepoName();
461
- const lastInfo = getLastVersionInfo(repoName);
497
+ const lastInfo = getLastVersionInfo(repoName, config);
462
498
  const lastDate = lastInfo?.date ?? null;
463
499
  const patchVersion = lastInfo ? bumpVersion(lastInfo.version, "patch") : null;
464
500
  const minorVersion = lastInfo ? bumpVersion(lastInfo.version, "minor") : null;
465
- const output = execSync5(
501
+ const output = execSync6(
466
502
  "git log --pretty=format:'%ad|%h|%s' --date=short -n 500",
467
503
  { encoding: "utf-8" }
468
504
  );
@@ -531,45 +567,13 @@ function skip(date) {
531
567
  }
532
568
 
533
569
  // src/commands/devlog/version.ts
534
- import { readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
535
- import { join as join4 } from "path";
536
570
  import chalk8 from "chalk";
537
- import semver2 from "semver";
538
- function getLatestVersion(repoName) {
539
- try {
540
- const files = readdirSync2(DEVLOG_DIR).filter((f) => f.endsWith(".md")).sort().reverse();
541
- for (const file of files) {
542
- const content = readFileSync5(join4(DEVLOG_DIR, file), "utf-8");
543
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
544
- if (frontmatterMatch) {
545
- const frontmatter = frontmatterMatch[1];
546
- const versionMatch = frontmatter.match(/version:\s*(.+)/);
547
- const tagsMatch = frontmatter.match(/tags:\s*\[([^\]]*)\]/);
548
- if (versionMatch && tagsMatch) {
549
- const tags = tagsMatch[1].split(",").map((t) => t.trim());
550
- const firstTag = tags[0];
551
- if (firstTag === repoName) {
552
- return versionMatch[1].trim();
553
- }
554
- }
555
- }
556
- }
557
- } catch {
558
- }
559
- return null;
560
- }
561
- function bumpPatchVersion(version2) {
562
- const cleaned = semver2.clean(version2) ?? semver2.coerce(version2)?.version;
563
- if (!cleaned) {
564
- return version2;
565
- }
566
- const bumped = semver2.inc(cleaned, "patch");
567
- return bumped ? `v${bumped}` : version2;
568
- }
569
571
  function version() {
572
+ const config = loadConfig();
570
573
  const name = getRepoName();
571
- const lastVersion = getLatestVersion(name);
572
- const nextVersion = lastVersion ? bumpPatchVersion(lastVersion) : null;
574
+ const lastInfo = getLastVersionInfo(name, config);
575
+ const lastVersion = lastInfo?.version ?? null;
576
+ const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
573
577
  console.log(`${chalk8.bold("name:")} ${name}`);
574
578
  console.log(`${chalk8.bold("last:")} ${lastVersion ?? chalk8.dim("none")}`);
575
579
  console.log(`${chalk8.bold("next:")} ${nextVersion ?? chalk8.dim("none")}`);
@@ -716,7 +720,7 @@ var EXPECTED_SCRIPTS = {
716
720
  import chalk13 from "chalk";
717
721
 
718
722
  // src/commands/verify/installPackage.ts
719
- import { execSync as execSync6 } from "child_process";
723
+ import { execSync as execSync7 } from "child_process";
720
724
  import * as fs3 from "fs";
721
725
  import * as path3 from "path";
722
726
  import chalk12 from "chalk";
@@ -736,7 +740,7 @@ function addScript(pkg, name, command) {
736
740
  function installPackage(name, cwd) {
737
741
  console.log(chalk12.dim(`Installing ${name}...`));
738
742
  try {
739
- execSync6(`npm install -D ${name}`, { stdio: "inherit", cwd });
743
+ execSync7(`npm install -D ${name}`, { stdio: "inherit", cwd });
740
744
  return true;
741
745
  } catch {
742
746
  console.error(chalk12.red(`Failed to install ${name}`));
@@ -846,21 +850,21 @@ import * as path7 from "path";
846
850
  import chalk18 from "chalk";
847
851
 
848
852
  // src/commands/lint/init.ts
849
- import { execSync as execSync8 } from "child_process";
850
- import { existsSync as existsSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "fs";
851
- import { dirname as dirname7, join as join8 } from "path";
853
+ import { execSync as execSync9 } from "child_process";
854
+ import { existsSync as existsSync8, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
855
+ import { dirname as dirname7, join as join7 } from "path";
852
856
  import { fileURLToPath as fileURLToPath3 } from "url";
853
857
  import chalk17 from "chalk";
854
858
 
855
859
  // src/shared/removeEslint.ts
856
- import { execSync as execSync7 } from "child_process";
857
- import { existsSync as existsSync7, readFileSync as readFileSync9, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
860
+ import { execSync as execSync8 } from "child_process";
861
+ import { existsSync as existsSync7, readFileSync as readFileSync8, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
858
862
  function removeEslint(options = {}) {
859
863
  const removedFromPackageJson = removeEslintFromPackageJson(options);
860
864
  const removedConfigFiles = removeEslintConfigFiles();
861
865
  if (removedFromPackageJson || removedConfigFiles) {
862
866
  console.log("Running npm install...");
863
- execSync7("npm install", { stdio: "inherit" });
867
+ execSync8("npm install", { stdio: "inherit" });
864
868
  return true;
865
869
  }
866
870
  return false;
@@ -870,7 +874,7 @@ function removeEslintFromPackageJson(options) {
870
874
  if (!existsSync7(packageJsonPath)) {
871
875
  return false;
872
876
  }
873
- const packageJson = JSON.parse(readFileSync9(packageJsonPath, "utf-8"));
877
+ const packageJson = JSON.parse(readFileSync8(packageJsonPath, "utf-8"));
874
878
  let modified = false;
875
879
  if (packageJson.dependencies) {
876
880
  for (const key of Object.keys(packageJson.dependencies)) {
@@ -935,15 +939,15 @@ async function init2() {
935
939
  const biomeConfigPath = "biome.json";
936
940
  if (!existsSync8(biomeConfigPath)) {
937
941
  console.log("Initializing Biome...");
938
- execSync8("npx @biomejs/biome init", { stdio: "inherit" });
942
+ execSync9("npx @biomejs/biome init", { stdio: "inherit" });
939
943
  }
940
944
  if (!existsSync8(biomeConfigPath)) {
941
945
  console.log("No biome.json found, skipping linter config");
942
946
  return;
943
947
  }
944
- const linterConfigPath = join8(__dirname4, "commands/lint/biome.linter.json");
945
- const linterConfig = JSON.parse(readFileSync10(linterConfigPath, "utf-8"));
946
- const biomeConfig = JSON.parse(readFileSync10(biomeConfigPath, "utf-8"));
948
+ const linterConfigPath = join7(__dirname4, "commands/lint/biome.linter.json");
949
+ const linterConfig = JSON.parse(readFileSync9(linterConfigPath, "utf-8"));
950
+ const biomeConfig = JSON.parse(readFileSync9(biomeConfigPath, "utf-8"));
947
951
  const oldContent = `${JSON.stringify(biomeConfig, null, 2)}
948
952
  `;
949
953
  biomeConfig.linter = linterConfig.linter;
@@ -1456,11 +1460,11 @@ function lint() {
1456
1460
  }
1457
1461
 
1458
1462
  // src/commands/new/newProject.ts
1459
- import { execSync as execSync9 } from "child_process";
1460
- import { existsSync as existsSync11, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
1463
+ import { execSync as execSync10 } from "child_process";
1464
+ import { existsSync as existsSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
1461
1465
  async function newProject() {
1462
1466
  console.log("Initializing Vite with react-ts template...");
1463
- execSync9("npm create vite@latest . -- --template react-ts", {
1467
+ execSync10("npm create vite@latest . -- --template react-ts", {
1464
1468
  stdio: "inherit"
1465
1469
  });
1466
1470
  removeEslint({ removeLintScripts: true });
@@ -1474,7 +1478,7 @@ function addViteBaseConfig() {
1474
1478
  console.log("No vite.config.ts found, skipping base config");
1475
1479
  return;
1476
1480
  }
1477
- const content = readFileSync12(viteConfigPath, "utf-8");
1481
+ const content = readFileSync11(viteConfigPath, "utf-8");
1478
1482
  if (content.includes("base:")) {
1479
1483
  console.log("vite.config.ts already has base config");
1480
1484
  return;
@@ -1571,6 +1575,8 @@ function showNotification(options) {
1571
1575
  }
1572
1576
  if (platform === "macos") {
1573
1577
  notificationOptions.sound = sound === "Alarm" ? "Basso" : "Submarine";
1578
+ notificationOptions.timeout = 99999999999;
1579
+ notificationOptions.wait = true;
1574
1580
  }
1575
1581
  notifier.notify(notificationOptions);
1576
1582
  return true;
@@ -1606,14 +1612,14 @@ async function notify() {
1606
1612
  }
1607
1613
 
1608
1614
  // src/commands/prs.ts
1609
- import { execSync as execSync10 } from "child_process";
1615
+ import { execSync as execSync11 } from "child_process";
1610
1616
  import chalk25 from "chalk";
1611
1617
  import enquirer4 from "enquirer";
1612
1618
  var PAGE_SIZE = 10;
1613
1619
  async function prs(options) {
1614
1620
  const state = options.open ? "open" : options.closed ? "closed" : "all";
1615
1621
  try {
1616
- const result = execSync10(
1622
+ const result = execSync11(
1617
1623
  `gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100`,
1618
1624
  { encoding: "utf-8" }
1619
1625
  );
@@ -1703,7 +1709,7 @@ import { spawn as spawn2 } from "child_process";
1703
1709
  import * as path14 from "path";
1704
1710
 
1705
1711
  // src/commands/refactor/getViolations.ts
1706
- import { execSync as execSync11 } from "child_process";
1712
+ import { execSync as execSync12 } from "child_process";
1707
1713
  import fs11 from "fs";
1708
1714
  import { minimatch } from "minimatch";
1709
1715
 
@@ -1808,7 +1814,7 @@ function getGitFiles(options) {
1808
1814
  }
1809
1815
  const files = /* @__PURE__ */ new Set();
1810
1816
  if (options.staged || options.modified) {
1811
- const staged = execSync11("git diff --cached --name-only", {
1817
+ const staged = execSync12("git diff --cached --name-only", {
1812
1818
  encoding: "utf-8"
1813
1819
  });
1814
1820
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -1816,7 +1822,7 @@ function getGitFiles(options) {
1816
1822
  }
1817
1823
  }
1818
1824
  if (options.unstaged || options.modified) {
1819
- const unstaged = execSync11("git diff --name-only", { encoding: "utf-8" });
1825
+ const unstaged = execSync12("git diff --name-only", { encoding: "utf-8" });
1820
1826
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
1821
1827
  files.add(file);
1822
1828
  }
@@ -2075,11 +2081,11 @@ function syncCommands(claudeDir, targetBase) {
2075
2081
  }
2076
2082
 
2077
2083
  // src/commands/verify/hardcodedColors.ts
2078
- import { execSync as execSync12 } from "child_process";
2084
+ import { execSync as execSync13 } from "child_process";
2079
2085
  var pattern = "0x[0-9a-fA-F]{6}|#[0-9a-fA-F]{3,6}";
2080
2086
  function hardcodedColors() {
2081
2087
  try {
2082
- const output = execSync12(`grep -rEnH '${pattern}' src/`, {
2088
+ const output = execSync13(`grep -rEnH '${pattern}' src/`, {
2083
2089
  encoding: "utf-8"
2084
2090
  });
2085
2091
  const lines = output.trim().split("\n");
@@ -2189,7 +2195,7 @@ program.command("init").description("Initialize VS Code and verify configuration
2189
2195
  program.command("commit <message>").description("Create a git commit with validation").action(commit);
2190
2196
  program.command("update").description("Update claude-code to the latest version").action(() => {
2191
2197
  console.log("Updating claude-code...");
2192
- execSync13("npm install -g @anthropic-ai/claude-code", { stdio: "inherit" });
2198
+ execSync14("npm install -g @anthropic-ai/claude-code", { stdio: "inherit" });
2193
2199
  });
2194
2200
  program.command("prs").description("List pull requests for the current repository").option("--open", "List only open pull requests").option("--closed", "List only closed pull requests").action(prs);
2195
2201
  var runCommand = program.command("run").description("Run a configured command from assist.yml").argument("<name>", "Name of the configured command").argument("[args...]", "Arguments to pass to the command").allowUnknownOption().action((name, args) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {