@gowelle/stint-agent 1.2.17 → 1.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  commitQueue,
4
+ versionService,
4
5
  websocketService
5
- } from "./chunk-VHCNMUHN.js";
6
+ } from "./chunk-ZUQRDCS2.js";
6
7
  import {
7
8
  apiService
8
- } from "./chunk-D6BP2Z5S.js";
9
+ } from "./chunk-6LQKDEQR.js";
9
10
  import {
10
11
  getPidFilePath,
11
12
  gitService,
@@ -14,20 +15,17 @@ import {
14
15
  projectService,
15
16
  spawnDetached,
16
17
  validatePidFile
17
- } from "./chunk-QQP6IASS.js";
18
- import {
19
- authService
20
- } from "./chunk-ES33YYVA.js";
21
- import "./chunk-DCY3EXDX.js";
18
+ } from "./chunk-NVQIKLOA.js";
22
19
  import {
20
+ authService,
23
21
  config,
24
22
  logger
25
- } from "./chunk-XHXSWLUC.js";
23
+ } from "./chunk-HZ4K7EPF.js";
26
24
 
27
25
  // src/index.ts
28
26
  import "dotenv/config";
29
27
  import { Command } from "commander";
30
- import chalk13 from "chalk";
28
+ import chalk14 from "chalk";
31
29
 
32
30
  // src/commands/login.ts
33
31
  import open from "open";
@@ -623,7 +621,7 @@ function registerStatusCommand(program2) {
623
621
  try {
624
622
  const { render } = await import("ink");
625
623
  const { createElement } = await import("react");
626
- const { StatusDashboard } = await import("./StatusDashboard-ATB5BFZR.js");
624
+ const { StatusDashboard } = await import("./StatusDashboard-I5DG5GEB.js");
627
625
  render(createElement(StatusDashboard, { cwd }));
628
626
  return;
629
627
  } catch (error) {
@@ -784,9 +782,8 @@ function getProcessStats(pid) {
784
782
  } else if (platform === "win32") {
785
783
  return getWindowsStats(pid);
786
784
  }
787
- throw new Error(`Unsupported platform: ${platform}`);
788
- } catch (error) {
789
- logger.error("monitor", `Failed to get process stats for PID ${pid}`, error);
785
+ return null;
786
+ } catch {
790
787
  return null;
791
788
  }
792
789
  }
@@ -1025,6 +1022,30 @@ function registerDaemonCommands(program2) {
1025
1022
  console.log(`${chalk8.bold("Threads:")} ${stats.threads}`);
1026
1023
  console.log(`${chalk8.bold("Uptime:")} ${formatUptime(stats.uptime)}`);
1027
1024
  }
1025
+ const statusPath = path3.join(os3.homedir(), ".config", "stint", "daemon.status.json");
1026
+ if (fs.existsSync(statusPath)) {
1027
+ try {
1028
+ const statusData = JSON.parse(fs.readFileSync(statusPath, "utf8"));
1029
+ console.log(chalk8.blue("\n\u{1F4E1} WebSocket Status:"));
1030
+ console.log(chalk8.gray("\u2500".repeat(50)));
1031
+ if (statusData.websocket?.connected) {
1032
+ console.log(`${chalk8.bold("Connected:")} ${chalk8.green("\u2713 Yes")}`);
1033
+ if (statusData.websocket.channel) {
1034
+ console.log(`${chalk8.bold("Channel:")} ${statusData.websocket.channel}`);
1035
+ }
1036
+ } else {
1037
+ console.log(`${chalk8.bold("Connected:")} ${chalk8.yellow("\u2717 No")}`);
1038
+ }
1039
+ if (statusData.websocket?.lastEvent) {
1040
+ console.log(`${chalk8.bold("Last Event:")} ${statusData.websocket.lastEvent}`);
1041
+ if (statusData.websocket.lastEventTime) {
1042
+ const ago = Math.floor((Date.now() - new Date(statusData.websocket.lastEventTime).getTime()) / 1e3);
1043
+ console.log(`${chalk8.bold("Event Time:")} ${formatUptime(ago)} ago`);
1044
+ }
1045
+ }
1046
+ } catch {
1047
+ }
1048
+ }
1028
1049
  } else {
1029
1050
  console.log(`${chalk8.bold("Status:")} ${chalk8.yellow("Not running")}`);
1030
1051
  console.log(chalk8.gray('Run "stint daemon start" to start the daemon.'));
@@ -1611,113 +1632,158 @@ function registerUninstallCommand(program2) {
1611
1632
  }
1612
1633
 
1613
1634
  // src/commands/update.ts
1635
+ import ora12 from "ora";
1636
+ import chalk12 from "chalk";
1637
+
1638
+ // src/services/update.ts
1639
+ import { execSync as execSync2 } from "child_process";
1614
1640
  import ora11 from "ora";
1615
1641
  import chalk11 from "chalk";
1616
- import { exec as exec2 } from "child_process";
1617
- import { promisify as promisify2 } from "util";
1618
- import { join } from "path";
1619
- import { readFileSync as readFileSync2 } from "fs";
1620
- import { fileURLToPath as fileURLToPath2 } from "url";
1621
- import { dirname as dirname2 } from "path";
1622
- var execAsync2 = promisify2(exec2);
1623
- var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
1624
- function getChannelConfig() {
1625
- try {
1626
- const packagePath = join(__dirname2, "..", "..", "package.json");
1627
- const packageJson = JSON.parse(readFileSync2(packagePath, "utf-8"));
1628
- return packageJson.stint;
1629
- } catch {
1630
- return {
1631
- channels: {
1632
- stable: {
1633
- pattern: "^\\d+\\.\\d+\\.\\d+$",
1634
- description: "Production-ready releases"
1642
+ var UpdateService = class {
1643
+ /**
1644
+ * Perform update to latest version
1645
+ * @param channel - Release channel to update to (stable or beta)
1646
+ * @returns Update result
1647
+ */
1648
+ async performUpdate(channel = "stable") {
1649
+ const spinner = ora11("Preparing update...").start();
1650
+ try {
1651
+ const { valid, pid } = validatePidFile();
1652
+ const daemonWasRunning = valid && pid !== null;
1653
+ if (daemonWasRunning) {
1654
+ spinner.text = "Stopping daemon...";
1655
+ await this.stopDaemonForUpdate(pid);
1656
+ }
1657
+ spinner.text = `Installing latest ${channel} version...`;
1658
+ const packageSpec = channel === "beta" ? "@gowelle/stint-agent@beta" : "@gowelle/stint-agent@latest";
1659
+ try {
1660
+ execSync2(`npm install -g ${packageSpec}`, {
1661
+ stdio: "pipe",
1662
+ encoding: "utf8"
1663
+ });
1664
+ } catch (error) {
1665
+ const errorMessage = error.message;
1666
+ if (errorMessage.includes("EACCES") || errorMessage.includes("EPERM")) {
1667
+ spinner.fail("Permission denied");
1668
+ throw new Error(
1669
+ "Permission denied. Try running with elevated privileges:\n" + (process.platform === "win32" ? " Run PowerShell as Administrator" : " sudo npm install -g @gowelle/stint-agent")
1670
+ );
1635
1671
  }
1636
- },
1637
- defaultChannel: "stable"
1638
- };
1672
+ throw error;
1673
+ }
1674
+ if (daemonWasRunning) {
1675
+ spinner.text = "Restarting daemon...";
1676
+ await this.restartDaemonAfterUpdate();
1677
+ }
1678
+ spinner.succeed("Update completed successfully!");
1679
+ return { success: true };
1680
+ } catch (error) {
1681
+ spinner.fail("Update failed");
1682
+ logger.error("update", "Update failed", error);
1683
+ return {
1684
+ success: false,
1685
+ error: error.message
1686
+ };
1687
+ }
1639
1688
  }
1640
- }
1641
- function getVersionPattern(channel) {
1642
- const config2 = getChannelConfig();
1643
- return config2.channels[channel]?.pattern || config2.channels[config2.defaultChannel].pattern;
1644
- }
1645
- async function getLatestVersionForChannel(channel) {
1646
- const pattern = getVersionPattern(channel);
1647
- const regex = new RegExp(pattern);
1648
- const { stdout } = await execAsync2("npm view @gowelle/stint-agent versions --json");
1649
- const versions = JSON.parse(stdout);
1650
- const channelVersions = versions.filter((v) => regex.test(v)).sort((a, b) => {
1651
- const [aMajor, aMinor, aPatch] = a.split(".").map((part) => parseInt(part.split("-")[0]));
1652
- const [bMajor, bMinor, bPatch] = b.split(".").map((part) => parseInt(part.split("-")[0]));
1653
- if (aMajor !== bMajor) return bMajor - aMajor;
1654
- if (aMinor !== bMinor) return bMinor - aMinor;
1655
- return bPatch - aPatch;
1656
- });
1657
- if (channelVersions.length === 0) {
1658
- throw new Error(`No versions found for channel: ${channel}`);
1689
+ /**
1690
+ * Stop daemon before update
1691
+ * @param pid - Process ID of daemon
1692
+ */
1693
+ async stopDaemonForUpdate(pid) {
1694
+ try {
1695
+ killProcess(pid, "SIGTERM");
1696
+ let attempts = 0;
1697
+ const maxAttempts = 10;
1698
+ while (attempts < maxAttempts) {
1699
+ await new Promise((resolve) => setTimeout(resolve, 500));
1700
+ if (!isProcessRunning(pid)) {
1701
+ logger.info("update", "Daemon stopped successfully");
1702
+ return;
1703
+ }
1704
+ attempts++;
1705
+ }
1706
+ if (isProcessRunning(pid)) {
1707
+ logger.warn("update", "Daemon did not stop gracefully, forcing shutdown");
1708
+ killProcess(pid, "SIGKILL");
1709
+ await new Promise((resolve) => setTimeout(resolve, 500));
1710
+ }
1711
+ } catch (error) {
1712
+ logger.error("update", "Failed to stop daemon", error);
1713
+ throw new Error("Failed to stop daemon before update");
1714
+ }
1659
1715
  }
1660
- return channelVersions[0];
1661
- }
1716
+ /**
1717
+ * Restart daemon after update
1718
+ */
1719
+ async restartDaemonAfterUpdate() {
1720
+ try {
1721
+ execSync2("stint daemon start", {
1722
+ stdio: "pipe",
1723
+ encoding: "utf8"
1724
+ });
1725
+ logger.info("update", "Daemon restarted successfully");
1726
+ } catch (error) {
1727
+ logger.error("update", "Failed to restart daemon", error);
1728
+ console.log(chalk11.yellow("\n\u26A0 Failed to restart daemon automatically."));
1729
+ console.log(chalk11.gray('Run "stint daemon start" to start it manually.\n'));
1730
+ }
1731
+ }
1732
+ };
1733
+ var updateService = new UpdateService();
1734
+
1735
+ // src/commands/update.ts
1736
+ import prompts from "prompts";
1662
1737
  function registerUpdateCommand(program2) {
1663
- program2.command("update").description("Update stint agent to the latest version").option("-c, --channel <channel>", "Release channel (stable, beta, nightly)").action(async (options) => {
1664
- const spinner = ora11("Checking for updates...").start();
1738
+ program2.command("update").description("Update stint-agent to the latest version").option("--check", "Check for updates without installing").option("--channel <channel>", "Release channel (stable or beta)", "stable").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
1665
1739
  try {
1666
- const currentVersion = program2.version();
1667
- const config2 = getChannelConfig();
1668
- const channel = (options.channel || config2.defaultChannel).toLowerCase();
1669
- if (!config2.channels[channel]) {
1670
- spinner.fail(`Invalid channel: ${channel}`);
1671
- console.log(chalk11.gray("\nAvailable channels:"));
1672
- Object.entries(config2.channels).forEach(([name, info]) => {
1673
- console.log(chalk11.gray(` ${name.padEnd(10)} ${info.description}`));
1674
- });
1675
- console.log();
1676
- process.exit(1);
1740
+ const channel = options.channel === "beta" ? "beta" : "stable";
1741
+ const spinner = ora12("Checking for updates...").start();
1742
+ const versionInfo = await versionService.checkForUpdates(channel);
1743
+ spinner.stop();
1744
+ console.log(chalk12.blue("\n\u{1F4E6} Version Information:"));
1745
+ console.log(chalk12.gray("\u2500".repeat(50)));
1746
+ console.log(`${chalk12.bold("Current:")} ${versionInfo.current}`);
1747
+ console.log(`${chalk12.bold("Latest:")} ${versionInfo.latest} (${channel})`);
1748
+ console.log();
1749
+ if (!versionInfo.hasUpdate) {
1750
+ console.log(chalk12.green("\u2713 You are already on the latest version!\n"));
1751
+ return;
1677
1752
  }
1678
- spinner.text = `Checking for updates in ${channel} channel...`;
1679
- const cleanLatestVersion = await getLatestVersionForChannel(channel);
1680
- if (currentVersion === cleanLatestVersion) {
1681
- spinner.succeed("Already up to date");
1682
- console.log(chalk11.gray(`
1683
- Current version: ${currentVersion}`));
1684
- console.log(chalk11.gray(`Latest version: ${cleanLatestVersion}
1753
+ console.log(chalk12.yellow(`\u26A0 Update available: ${versionInfo.current} \u2192 ${versionInfo.latest}
1685
1754
  `));
1755
+ if (options.check) {
1756
+ console.log(chalk12.gray('Run "stint update" to install the latest version.\n'));
1686
1757
  return;
1687
1758
  }
1688
- spinner.info(`Update available: ${currentVersion} \u2192 ${cleanLatestVersion}`);
1689
- spinner.text = "Installing update...";
1690
- await execAsync2(`npm install -g @gowelle/stint-agent@${cleanLatestVersion}`);
1691
- spinner.succeed(`Updated to version ${cleanLatestVersion}`);
1692
- const { valid, pid } = validatePidFile();
1693
- if (valid && pid) {
1694
- console.log(chalk11.blue("\n\u{1F504} Restarting daemon with new version..."));
1695
- const restartSpinner = ora11("Restarting daemon...").start();
1696
- try {
1697
- killProcess(pid, "SIGTERM");
1698
- let attempts = 0;
1699
- while (attempts < 10 && isProcessRunning(pid)) {
1700
- await new Promise((resolve) => setTimeout(resolve, 500));
1701
- attempts++;
1702
- }
1703
- if (isProcessRunning(pid)) {
1704
- killProcess(pid, "SIGKILL");
1705
- }
1706
- await new Promise((resolve) => setTimeout(resolve, 1e3));
1707
- await execAsync2("stint daemon start");
1708
- restartSpinner.succeed("Daemon restarted successfully");
1709
- logger.success("update", `Daemon restarted after update`);
1710
- } catch (error) {
1711
- restartSpinner.fail("Failed to restart daemon");
1712
- logger.error("update", "Daemon restart failed", error);
1713
- console.log(chalk11.yellow('\nPlease run "stint daemon start" manually.\n'));
1759
+ if (!options.yes) {
1760
+ const response = await prompts({
1761
+ type: "confirm",
1762
+ name: "proceed",
1763
+ message: "Do you want to update now?",
1764
+ initial: true
1765
+ });
1766
+ if (!response.proceed) {
1767
+ console.log(chalk12.gray("\nUpdate cancelled.\n"));
1768
+ return;
1714
1769
  }
1715
1770
  }
1716
- logger.success("update", `Updated to version ${cleanLatestVersion}`);
1771
+ console.log();
1772
+ const result = await updateService.performUpdate(channel);
1773
+ if (result.success) {
1774
+ console.log(chalk12.green(`
1775
+ \u2713 Successfully updated to ${versionInfo.latest}!
1776
+ `));
1777
+ logger.success("update", `Updated to ${versionInfo.latest}`);
1778
+ } else {
1779
+ console.log(chalk12.red(`
1780
+ \u2716 Update failed: ${result.error}
1781
+ `));
1782
+ process.exit(1);
1783
+ }
1717
1784
  } catch (error) {
1718
- spinner.fail("Update failed");
1719
1785
  logger.error("update", "Update command failed", error);
1720
- console.error(chalk11.red(`
1786
+ console.error(chalk12.red(`
1721
1787
  \u2716 Error: ${error.message}
1722
1788
  `));
1723
1789
  process.exit(1);
@@ -1726,8 +1792,8 @@ Current version: ${currentVersion}`));
1726
1792
  }
1727
1793
 
1728
1794
  // src/commands/doctor.ts
1729
- import ora12 from "ora";
1730
- import chalk12 from "chalk";
1795
+ import ora13 from "ora";
1796
+ import chalk13 from "chalk";
1731
1797
 
1732
1798
  // src/utils/api-errors.ts
1733
1799
  function formatApiError(error) {
@@ -1819,13 +1885,13 @@ function isServiceUnavailable(error) {
1819
1885
  }
1820
1886
 
1821
1887
  // src/commands/doctor.ts
1822
- import { exec as exec3 } from "child_process";
1823
- import { promisify as promisify3 } from "util";
1888
+ import { exec as exec2 } from "child_process";
1889
+ import { promisify as promisify2 } from "util";
1824
1890
  import process7 from "process";
1825
- var execAsync3 = promisify3(exec3);
1891
+ var execAsync2 = promisify2(exec2);
1826
1892
  function registerDoctorCommand(program2) {
1827
1893
  program2.command("doctor").description("Run diagnostics to check environment health").action(async () => {
1828
- const spinner = ora12("Running diagnostics...").start();
1894
+ const spinner = ora13("Running diagnostics...").start();
1829
1895
  let hasErrors = false;
1830
1896
  try {
1831
1897
  const checks = [
@@ -1833,7 +1899,7 @@ function registerDoctorCommand(program2) {
1833
1899
  name: "Git Installation",
1834
1900
  check: async () => {
1835
1901
  try {
1836
- const { stdout } = await execAsync3("git --version");
1902
+ const { stdout } = await execAsync2("git --version");
1837
1903
  return {
1838
1904
  success: true,
1839
1905
  message: `Git ${stdout.trim()} found`
@@ -1854,8 +1920,8 @@ function registerDoctorCommand(program2) {
1854
1920
  name: "Git Configuration",
1855
1921
  check: async () => {
1856
1922
  try {
1857
- const { stdout: userName } = await execAsync3("git config --global user.name");
1858
- const { stdout: userEmail } = await execAsync3("git config --global user.email");
1923
+ const { stdout: userName } = await execAsync2("git config --global user.name");
1924
+ const { stdout: userEmail } = await execAsync2("git config --global user.email");
1859
1925
  if (!userName.trim() || !userEmail.trim()) {
1860
1926
  return {
1861
1927
  success: false,
@@ -1962,39 +2028,39 @@ function registerDoctorCommand(program2) {
1962
2028
  }
1963
2029
  }
1964
2030
  ];
1965
- console.log(chalk12.blue("\n\u{1F50D} Running environment diagnostics...\n"));
2031
+ console.log(chalk13.blue("\n\u{1F50D} Running environment diagnostics...\n"));
1966
2032
  for (const check of checks) {
1967
2033
  spinner.text = `Checking ${check.name.toLowerCase()}...`;
1968
2034
  try {
1969
2035
  const result = await check.check();
1970
2036
  if (result.success) {
1971
- console.log(`${chalk12.green("\u2713")} ${chalk12.bold(check.name)}: ${result.message}`);
2037
+ console.log(`${chalk13.green("\u2713")} ${chalk13.bold(check.name)}: ${result.message}`);
1972
2038
  } else {
1973
2039
  hasErrors = true;
1974
- console.log(`${chalk12.red("\u2716")} ${chalk12.bold(check.name)}: ${result.message}`);
2040
+ console.log(`${chalk13.red("\u2716")} ${chalk13.bold(check.name)}: ${result.message}`);
1975
2041
  if (result.details) {
1976
2042
  result.details.forEach((detail) => {
1977
- console.log(chalk12.gray(` ${detail}`));
2043
+ console.log(chalk13.gray(` ${detail}`));
1978
2044
  });
1979
2045
  }
1980
2046
  }
1981
2047
  } catch (error) {
1982
2048
  hasErrors = true;
1983
- console.log(`${chalk12.red("\u2716")} ${chalk12.bold(check.name)}: Check failed - ${error.message}`);
2049
+ console.log(`${chalk13.red("\u2716")} ${chalk13.bold(check.name)}: Check failed - ${error.message}`);
1984
2050
  }
1985
2051
  }
1986
2052
  spinner.stop();
1987
2053
  console.log();
1988
2054
  if (hasErrors) {
1989
- console.log(chalk12.yellow("Some checks failed. Please address the issues above."));
2055
+ console.log(chalk13.yellow("Some checks failed. Please address the issues above."));
1990
2056
  process7.exit(1);
1991
2057
  } else {
1992
- console.log(chalk12.green("All checks passed! Your environment is healthy."));
2058
+ console.log(chalk13.green("All checks passed! Your environment is healthy."));
1993
2059
  }
1994
2060
  } catch (error) {
1995
2061
  spinner.fail("Diagnostics failed");
1996
2062
  logger.error("doctor", "Diagnostics failed", error);
1997
- console.error(chalk12.red(`
2063
+ console.error(chalk13.red(`
1998
2064
  \u2716 Error: ${error.message}
1999
2065
  `));
2000
2066
  process7.exit(1);
@@ -2003,19 +2069,19 @@ function registerDoctorCommand(program2) {
2003
2069
  }
2004
2070
 
2005
2071
  // src/index.ts
2006
- var AGENT_VERSION = "1.2.17";
2072
+ var AGENT_VERSION = "1.2.19";
2007
2073
  var program = new Command();
2008
2074
  program.name("stint").description("Stint Agent - Local daemon for Stint Project Assistant").version(AGENT_VERSION, "-v, --version", "output the current version").addHelpText("after", `
2009
- ${chalk13.bold("Examples:")}
2010
- ${chalk13.cyan("$")} stint login ${chalk13.gray("# Authenticate with Stint")}
2011
- ${chalk13.cyan("$")} stint install ${chalk13.gray("# Install agent to run on startup")}
2012
- ${chalk13.cyan("$")} stint link ${chalk13.gray("# Link current directory to a project")}
2013
- ${chalk13.cyan("$")} stint daemon start ${chalk13.gray("# Start background daemon")}
2014
- ${chalk13.cyan("$")} stint status ${chalk13.gray("# Check status")}
2015
- ${chalk13.cyan("$")} stint commits ${chalk13.gray("# List pending commits")}
2075
+ ${chalk14.bold("Examples:")}
2076
+ ${chalk14.cyan("$")} stint login ${chalk14.gray("# Authenticate with Stint")}
2077
+ ${chalk14.cyan("$")} stint install ${chalk14.gray("# Install agent to run on startup")}
2078
+ ${chalk14.cyan("$")} stint link ${chalk14.gray("# Link current directory to a project")}
2079
+ ${chalk14.cyan("$")} stint daemon start ${chalk14.gray("# Start background daemon")}
2080
+ ${chalk14.cyan("$")} stint status ${chalk14.gray("# Check status")}
2081
+ ${chalk14.cyan("$")} stint commits ${chalk14.gray("# List pending commits")}
2016
2082
 
2017
- ${chalk13.bold("Documentation:")}
2018
- For more information, visit: ${chalk13.blue("https://stint.codes/docs")}
2083
+ ${chalk14.bold("Documentation:")}
2084
+ For more information, visit: ${chalk14.blue("https://stint.codes/docs")}
2019
2085
  `);
2020
2086
  registerLoginCommand(program);
2021
2087
  registerLogoutCommand(program);
@@ -2037,7 +2103,7 @@ try {
2037
2103
  const commanderError = error;
2038
2104
  if (commanderError.code !== "commander.help" && commanderError.code !== "commander.version" && commanderError.code !== "commander.helpDisplayed") {
2039
2105
  logger.error("cli", "Command execution failed", error);
2040
- console.error(chalk13.red(`
2106
+ console.error(chalk14.red(`
2041
2107
  \u2716 Error: ${error.message}
2042
2108
  `));
2043
2109
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gowelle/stint-agent",
3
- "version": "1.2.17",
3
+ "version": "1.2.19",
4
4
  "description": "Local agent for Stint - Project Assistant",
5
5
  "author": "Gowelle John <gowelle.john@icloud.com>",
6
6
  "license": "MIT",
@@ -44,10 +44,13 @@
44
44
  "conf": "^12.0.0",
45
45
  "dotenv": "^17.2.3",
46
46
  "ink": "^5.2.1",
47
+ "laravel-echo": "^2.2.6",
47
48
  "node-fetch": "^3.3.2",
48
49
  "node-notifier": "^10.0.1",
49
50
  "open": "^10.0.0",
50
51
  "ora": "^8.0.1",
52
+ "prompts": "^2.4.2",
53
+ "pusher-js": "^8.4.0",
51
54
  "react": "^18.3.1",
52
55
  "simple-git": "^3.22.0",
53
56
  "ws": "^8.16.0"
@@ -55,6 +58,7 @@
55
58
  "devDependencies": {
56
59
  "@types/node": "^20.11.0",
57
60
  "@types/node-notifier": "^8.0.5",
61
+ "@types/prompts": "^2.4.9",
58
62
  "@types/react": "^18.3.27",
59
63
  "@types/ws": "^8.5.10",
60
64
  "@typescript-eslint/eslint-plugin": "^8.50.0",
@@ -1,8 +0,0 @@
1
- import {
2
- apiService
3
- } from "./chunk-D6BP2Z5S.js";
4
- import "./chunk-ES33YYVA.js";
5
- import "./chunk-XHXSWLUC.js";
6
- export {
7
- apiService
8
- };
@@ -1,40 +0,0 @@
1
- import {
2
- config,
3
- logger
4
- } from "./chunk-XHXSWLUC.js";
5
-
6
- // src/utils/notify.ts
7
- import notifier from "node-notifier";
8
- import path from "path";
9
- import { fileURLToPath } from "url";
10
- var __filename = fileURLToPath(import.meta.url);
11
- var __dirname = path.dirname(__filename);
12
- var DEFAULT_ICON = path.resolve(__dirname, "../assets/logo.png");
13
- function notify(options) {
14
- if (!config.areNotificationsEnabled()) {
15
- logger.debug("notify", "Notifications disabled, skipping notification");
16
- return;
17
- }
18
- try {
19
- notifier.notify({
20
- title: options.title,
21
- message: options.message,
22
- open: options.open,
23
- icon: options.icon || DEFAULT_ICON,
24
- sound: true,
25
- wait: false,
26
- appID: "Stint Agent"
27
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- }, (error) => {
29
- if (error) {
30
- logger.error("notify", "Failed to send notification", error);
31
- }
32
- });
33
- } catch (error) {
34
- logger.error("notify", "Failed to send notification", error);
35
- }
36
- }
37
-
38
- export {
39
- notify
40
- };
@@ -1,95 +0,0 @@
1
- import {
2
- config,
3
- logger
4
- } from "./chunk-XHXSWLUC.js";
5
-
6
- // src/utils/crypto.ts
7
- import crypto from "crypto";
8
- import os from "os";
9
- function getMachineKey() {
10
- const machineInfo = `${os.hostname()}-${os.platform()}-${os.arch()}`;
11
- return crypto.createHash("sha256").update(machineInfo).digest();
12
- }
13
- var ALGORITHM = "aes-256-gcm";
14
- var IV_LENGTH = 16;
15
- var AUTH_TAG_LENGTH = 16;
16
- function encrypt(text) {
17
- const key = getMachineKey();
18
- const iv = crypto.randomBytes(IV_LENGTH);
19
- const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
20
- let encrypted = cipher.update(text, "utf8", "hex");
21
- encrypted += cipher.final("hex");
22
- const authTag = cipher.getAuthTag();
23
- return iv.toString("hex") + authTag.toString("hex") + encrypted;
24
- }
25
- function decrypt(encryptedText) {
26
- const key = getMachineKey();
27
- const iv = Buffer.from(encryptedText.slice(0, IV_LENGTH * 2), "hex");
28
- const authTag = Buffer.from(
29
- encryptedText.slice(IV_LENGTH * 2, (IV_LENGTH + AUTH_TAG_LENGTH) * 2),
30
- "hex"
31
- );
32
- const encrypted = encryptedText.slice((IV_LENGTH + AUTH_TAG_LENGTH) * 2);
33
- const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
34
- decipher.setAuthTag(authTag);
35
- let decrypted = decipher.update(encrypted, "hex", "utf8");
36
- decrypted += decipher.final("utf8");
37
- return decrypted;
38
- }
39
-
40
- // src/services/auth.ts
41
- var AuthServiceImpl = class {
42
- async saveToken(token) {
43
- try {
44
- const encryptedToken = encrypt(token);
45
- config.setToken(encryptedToken);
46
- logger.info("auth", "Token saved successfully");
47
- } catch (error) {
48
- logger.error("auth", "Failed to save token", error);
49
- throw error;
50
- }
51
- }
52
- async getToken() {
53
- try {
54
- const encryptedToken = config.getToken();
55
- if (!encryptedToken) {
56
- return null;
57
- }
58
- return decrypt(encryptedToken);
59
- } catch (error) {
60
- logger.error("auth", "Failed to decrypt token", error);
61
- return null;
62
- }
63
- }
64
- async clearToken() {
65
- config.clearToken();
66
- logger.info("auth", "Token cleared");
67
- }
68
- async validateToken() {
69
- const token = await this.getToken();
70
- if (!token) {
71
- return null;
72
- }
73
- try {
74
- const { apiService } = await import("./api-ORVLKYAQ.js");
75
- const user = await apiService.getCurrentUser();
76
- logger.info("auth", `Token validated for user: ${user.email}`);
77
- return user;
78
- } catch (error) {
79
- logger.warn("auth", "Token validation failed");
80
- logger.error("auth", "Failed to validate token", error);
81
- return null;
82
- }
83
- }
84
- getMachineId() {
85
- return config.getMachineId();
86
- }
87
- getMachineName() {
88
- return config.getMachineName();
89
- }
90
- };
91
- var authService = new AuthServiceImpl();
92
-
93
- export {
94
- authService
95
- };