@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/{StatusDashboard-ATB5BFZR.js → StatusDashboard-I5DG5GEB.js} +2 -3
- package/dist/api-76OMVWNR.js +7 -0
- package/dist/{chunk-D6BP2Z5S.js → chunk-6LQKDEQR.js} +3 -5
- package/dist/{chunk-XHXSWLUC.js → chunk-HZ4K7EPF.js} +120 -2
- package/dist/{chunk-QQP6IASS.js → chunk-NVQIKLOA.js} +1 -1
- package/dist/chunk-ZUQRDCS2.js +2618 -0
- package/dist/daemon/runner.js +45 -149
- package/dist/index.js +199 -133
- package/package.json +5 -1
- package/dist/api-ORVLKYAQ.js +0 -8
- package/dist/chunk-DCY3EXDX.js +0 -40
- package/dist/chunk-ES33YYVA.js +0 -95
- package/dist/chunk-VHCNMUHN.js +0 -477
- package/dist/notify-NXUEEO7M.js +0 -7
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-
|
|
6
|
+
} from "./chunk-ZUQRDCS2.js";
|
|
6
7
|
import {
|
|
7
8
|
apiService
|
|
8
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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
|
|
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-
|
|
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
|
-
|
|
788
|
-
} catch
|
|
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
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
1667
|
-
const
|
|
1668
|
-
const
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
1730
|
-
import
|
|
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
|
|
1823
|
-
import { promisify as
|
|
1888
|
+
import { exec as exec2 } from "child_process";
|
|
1889
|
+
import { promisify as promisify2 } from "util";
|
|
1824
1890
|
import process7 from "process";
|
|
1825
|
-
var
|
|
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 =
|
|
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
|
|
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
|
|
1858
|
-
const { stdout: userEmail } = await
|
|
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(
|
|
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(`${
|
|
2037
|
+
console.log(`${chalk13.green("\u2713")} ${chalk13.bold(check.name)}: ${result.message}`);
|
|
1972
2038
|
} else {
|
|
1973
2039
|
hasErrors = true;
|
|
1974
|
-
console.log(`${
|
|
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(
|
|
2043
|
+
console.log(chalk13.gray(` ${detail}`));
|
|
1978
2044
|
});
|
|
1979
2045
|
}
|
|
1980
2046
|
}
|
|
1981
2047
|
} catch (error) {
|
|
1982
2048
|
hasErrors = true;
|
|
1983
|
-
console.log(`${
|
|
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(
|
|
2055
|
+
console.log(chalk13.yellow("Some checks failed. Please address the issues above."));
|
|
1990
2056
|
process7.exit(1);
|
|
1991
2057
|
} else {
|
|
1992
|
-
console.log(
|
|
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(
|
|
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.
|
|
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
|
-
${
|
|
2010
|
-
${
|
|
2011
|
-
${
|
|
2012
|
-
${
|
|
2013
|
-
${
|
|
2014
|
-
${
|
|
2015
|
-
${
|
|
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
|
-
${
|
|
2018
|
-
For more information, visit: ${
|
|
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(
|
|
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.
|
|
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",
|
package/dist/api-ORVLKYAQ.js
DELETED
package/dist/chunk-DCY3EXDX.js
DELETED
|
@@ -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
|
-
};
|
package/dist/chunk-ES33YYVA.js
DELETED
|
@@ -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
|
-
};
|