@gowelle/stint-agent 1.2.2 → 1.2.4
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/README.md +12 -4
- package/dist/{StatusDashboard-NTJAONDR.js → StatusDashboard-3OVDAOMH.js} +2 -2
- package/dist/api-DWEOHMQO.js +7 -0
- package/dist/{chunk-XLTOQPAD.js → chunk-G63H6RU4.js} +12 -12
- package/dist/{chunk-GG6LVSVC.js → chunk-MEK4CIRY.js} +4 -3
- package/dist/{chunk-FY5S22C3.js → chunk-QT6T5CAF.js} +1 -1
- package/dist/{chunk-2QJPWC56.js → chunk-XWCW6VSC.js} +1 -1
- package/dist/daemon/runner.js +17 -4
- package/dist/index.js +117 -13
- package/package.json +1 -1
- package/dist/api-XYDQ3I2Y.js +0 -7
package/README.md
CHANGED
|
@@ -92,10 +92,18 @@ stint daemon status
|
|
|
92
92
|
|
|
93
93
|
### Commit Operations
|
|
94
94
|
|
|
95
|
-
| Command
|
|
96
|
-
|
|
|
97
|
-
| `stint commits`
|
|
98
|
-
| `stint commit <id>`
|
|
95
|
+
| Command | Description |
|
|
96
|
+
| -------------------------- | ------------------------------------------------------ |
|
|
97
|
+
| `stint commits` | List pending commits for this repository |
|
|
98
|
+
| `stint commit <id>` | Execute a specific pending commit (supports partial ID)|
|
|
99
|
+
|
|
100
|
+
**`stint commit` Options:**
|
|
101
|
+
|
|
102
|
+
| Option | Description |
|
|
103
|
+
| -------------- | --------------------------------------------------- |
|
|
104
|
+
| `--auto-stage` | Automatically stage files specified in the commit |
|
|
105
|
+
| `--push` | Push changes to remote after committing |
|
|
106
|
+
| `--force` | Skip file validation warnings |
|
|
99
107
|
|
|
100
108
|
## Complete Workflow
|
|
101
109
|
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
gitService,
|
|
3
3
|
projectService,
|
|
4
4
|
validatePidFile
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QT6T5CAF.js";
|
|
6
6
|
import {
|
|
7
7
|
authService
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-XWCW6VSC.js";
|
|
9
9
|
|
|
10
10
|
// src/components/StatusDashboard.tsx
|
|
11
11
|
import { useState, useEffect } from "react";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
apiService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MEK4CIRY.js";
|
|
4
4
|
import {
|
|
5
5
|
gitService,
|
|
6
6
|
projectService
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QT6T5CAF.js";
|
|
8
8
|
import {
|
|
9
9
|
authService,
|
|
10
10
|
config,
|
|
11
11
|
logger
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-XWCW6VSC.js";
|
|
13
13
|
|
|
14
14
|
// src/utils/notify.ts
|
|
15
15
|
import notifier from "node-notifier";
|
|
@@ -353,9 +353,9 @@ var WebSocketServiceImpl = class {
|
|
|
353
353
|
return;
|
|
354
354
|
}
|
|
355
355
|
if (message.event === "commit.approved") {
|
|
356
|
-
const {
|
|
357
|
-
logger.info("websocket", `Commit approved: ${
|
|
358
|
-
this.commitApprovedHandlers.forEach((handler) => handler(
|
|
356
|
+
const { pendingCommit } = message.data;
|
|
357
|
+
logger.info("websocket", `Commit approved: ${pendingCommit.id}`);
|
|
358
|
+
this.commitApprovedHandlers.forEach((handler) => handler(pendingCommit, pendingCommit.project));
|
|
359
359
|
return;
|
|
360
360
|
}
|
|
361
361
|
if (message.event === "commit.pending") {
|
|
@@ -377,15 +377,15 @@ var WebSocketServiceImpl = class {
|
|
|
377
377
|
return;
|
|
378
378
|
}
|
|
379
379
|
if (message.event === "sync.requested") {
|
|
380
|
-
const {
|
|
381
|
-
logger.info("websocket", `Sync requested for project: ${
|
|
382
|
-
this.syncRequestedHandlers.forEach((handler) => handler(
|
|
380
|
+
const { project } = message.data;
|
|
381
|
+
logger.info("websocket", `Sync requested for project: ${project.id}`);
|
|
382
|
+
this.syncRequestedHandlers.forEach((handler) => handler(project.id));
|
|
383
383
|
return;
|
|
384
384
|
}
|
|
385
385
|
if (message.event === "agent.disconnected") {
|
|
386
|
-
const reason = message.data
|
|
387
|
-
logger.warn("websocket", `Agent disconnected by server: ${reason}`);
|
|
388
|
-
this.agentDisconnectedHandlers.forEach((handler) => handler(reason));
|
|
386
|
+
const { reason } = message.data;
|
|
387
|
+
logger.warn("websocket", `Agent disconnected by server: ${reason ?? "Server requested disconnect"}`);
|
|
388
|
+
this.agentDisconnectedHandlers.forEach((handler) => handler(reason ?? "Server requested disconnect"));
|
|
389
389
|
return;
|
|
390
390
|
}
|
|
391
391
|
logger.debug("websocket", `Unhandled event: ${message.event}`);
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
authService,
|
|
3
3
|
config,
|
|
4
4
|
logger
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-XWCW6VSC.js";
|
|
6
6
|
|
|
7
7
|
// src/utils/circuit-breaker.ts
|
|
8
8
|
var CircuitBreaker = class {
|
|
@@ -98,7 +98,7 @@ var CircuitBreaker = class {
|
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
// src/services/api.ts
|
|
101
|
-
var AGENT_VERSION = "1.2.
|
|
101
|
+
var AGENT_VERSION = "1.2.4";
|
|
102
102
|
var ApiServiceImpl = class {
|
|
103
103
|
sessionId = null;
|
|
104
104
|
circuitBreaker = new CircuitBreaker({
|
|
@@ -337,7 +337,8 @@ var ApiServiceImpl = class {
|
|
|
337
337
|
repo_path: data.repoPath,
|
|
338
338
|
remote_url: data.remoteUrl,
|
|
339
339
|
default_branch: data.defaultBranch,
|
|
340
|
-
current_branch: data.currentBranch
|
|
340
|
+
current_branch: data.currentBranch,
|
|
341
|
+
branches: data.branches
|
|
341
342
|
};
|
|
342
343
|
await this.request(`/api/agent/projects/${projectId}/sync`, {
|
|
343
344
|
method: "POST",
|
|
@@ -271,7 +271,7 @@ var AuthServiceImpl = class {
|
|
|
271
271
|
return null;
|
|
272
272
|
}
|
|
273
273
|
try {
|
|
274
|
-
const { apiService } = await import("./api-
|
|
274
|
+
const { apiService } = await import("./api-DWEOHMQO.js");
|
|
275
275
|
const user = await apiService.getCurrentUser();
|
|
276
276
|
logger.info("auth", `Token validated for user: ${user.email}`);
|
|
277
277
|
return user;
|
package/dist/daemon/runner.js
CHANGED
|
@@ -3,20 +3,20 @@ import {
|
|
|
3
3
|
commitQueue,
|
|
4
4
|
notify,
|
|
5
5
|
websocketService
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-G63H6RU4.js";
|
|
7
7
|
import {
|
|
8
8
|
apiService
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-MEK4CIRY.js";
|
|
10
10
|
import {
|
|
11
11
|
gitService,
|
|
12
12
|
projectService,
|
|
13
13
|
removePidFile,
|
|
14
14
|
writePidFile
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-QT6T5CAF.js";
|
|
16
16
|
import {
|
|
17
17
|
authService,
|
|
18
18
|
logger
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-XWCW6VSC.js";
|
|
20
20
|
|
|
21
21
|
// src/daemon/runner.ts
|
|
22
22
|
import "dotenv/config";
|
|
@@ -285,6 +285,19 @@ Priority: ${suggestion.priority}`,
|
|
|
285
285
|
setupSignalHandlers();
|
|
286
286
|
startHeartbeat();
|
|
287
287
|
fileWatcher.start();
|
|
288
|
+
const linkedProjects = projectService.getAllLinkedProjects();
|
|
289
|
+
const projectEntries = Object.entries(linkedProjects);
|
|
290
|
+
if (projectEntries.length > 0) {
|
|
291
|
+
logger.info("daemon", `Syncing ${projectEntries.length} linked project(s) on startup...`);
|
|
292
|
+
for (const [, linkedProject] of projectEntries) {
|
|
293
|
+
try {
|
|
294
|
+
await fileWatcher.syncProjectById(linkedProject.projectId);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
logger.error("daemon", `Failed to sync project ${linkedProject.projectId} on startup`, error);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
logger.success("daemon", "Initial project sync complete");
|
|
300
|
+
}
|
|
288
301
|
logger.success("daemon", "Daemon started successfully");
|
|
289
302
|
await new Promise(() => {
|
|
290
303
|
});
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
commitQueue,
|
|
4
4
|
websocketService
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-G63H6RU4.js";
|
|
6
6
|
import {
|
|
7
7
|
apiService
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MEK4CIRY.js";
|
|
9
9
|
import {
|
|
10
10
|
getPidFilePath,
|
|
11
11
|
gitService,
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
projectService,
|
|
15
15
|
spawnDetached,
|
|
16
16
|
validatePidFile
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-QT6T5CAF.js";
|
|
18
18
|
import {
|
|
19
19
|
authService,
|
|
20
20
|
config,
|
|
21
21
|
logger
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-XWCW6VSC.js";
|
|
23
23
|
|
|
24
24
|
// src/index.ts
|
|
25
25
|
import "dotenv/config";
|
|
@@ -620,7 +620,7 @@ function registerStatusCommand(program2) {
|
|
|
620
620
|
try {
|
|
621
621
|
const { render } = await import("ink");
|
|
622
622
|
const { createElement } = await import("react");
|
|
623
|
-
const { StatusDashboard } = await import("./StatusDashboard-
|
|
623
|
+
const { StatusDashboard } = await import("./StatusDashboard-3OVDAOMH.js");
|
|
624
624
|
render(createElement(StatusDashboard, { cwd }));
|
|
625
625
|
return;
|
|
626
626
|
} catch (error) {
|
|
@@ -1719,6 +1719,97 @@ Current version: ${currentVersion}`));
|
|
|
1719
1719
|
// src/commands/doctor.ts
|
|
1720
1720
|
import ora12 from "ora";
|
|
1721
1721
|
import chalk12 from "chalk";
|
|
1722
|
+
|
|
1723
|
+
// src/utils/api-errors.ts
|
|
1724
|
+
function formatApiError(error) {
|
|
1725
|
+
const errorMessage = error.message;
|
|
1726
|
+
if (errorMessage.includes("503") || errorMessage.includes("Service Unavailable")) {
|
|
1727
|
+
return {
|
|
1728
|
+
message: "Service temporarily unavailable",
|
|
1729
|
+
details: [
|
|
1730
|
+
"The Stint server is currently down for maintenance or experiencing issues.",
|
|
1731
|
+
"Please try again in a few minutes."
|
|
1732
|
+
]
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
if (errorMessage.includes("ECONNREFUSED") || errorMessage.includes("ENOTFOUND") || errorMessage.includes("ETIMEDOUT") || errorMessage.includes("fetch failed")) {
|
|
1736
|
+
return {
|
|
1737
|
+
message: "Unable to reach the server",
|
|
1738
|
+
details: [
|
|
1739
|
+
"Check your internet connection.",
|
|
1740
|
+
"Verify the API server is accessible."
|
|
1741
|
+
]
|
|
1742
|
+
};
|
|
1743
|
+
}
|
|
1744
|
+
if (errorMessage.includes("401")) {
|
|
1745
|
+
return {
|
|
1746
|
+
message: "Authentication expired or invalid",
|
|
1747
|
+
details: ['Run "stint login" to re-authenticate.']
|
|
1748
|
+
};
|
|
1749
|
+
}
|
|
1750
|
+
if (errorMessage.includes("403")) {
|
|
1751
|
+
return {
|
|
1752
|
+
message: "Access denied",
|
|
1753
|
+
details: [
|
|
1754
|
+
"You may not have permission for this action.",
|
|
1755
|
+
'Try logging in again with "stint login".'
|
|
1756
|
+
]
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
if (errorMessage.includes("404")) {
|
|
1760
|
+
return {
|
|
1761
|
+
message: "Resource not found",
|
|
1762
|
+
details: ["The requested resource does not exist."]
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
if (errorMessage.includes("429")) {
|
|
1766
|
+
return {
|
|
1767
|
+
message: "Too many requests",
|
|
1768
|
+
details: ["Please wait a moment before trying again."]
|
|
1769
|
+
};
|
|
1770
|
+
}
|
|
1771
|
+
if (errorMessage.includes("500")) {
|
|
1772
|
+
return {
|
|
1773
|
+
message: "Server error occurred",
|
|
1774
|
+
details: [
|
|
1775
|
+
"The server encountered an unexpected error.",
|
|
1776
|
+
"Please try again later or contact support if the issue persists."
|
|
1777
|
+
]
|
|
1778
|
+
};
|
|
1779
|
+
}
|
|
1780
|
+
if (errorMessage.includes("Circuit breaker is open")) {
|
|
1781
|
+
return {
|
|
1782
|
+
message: "Service temporarily unavailable",
|
|
1783
|
+
details: [
|
|
1784
|
+
"Multiple requests have failed recently.",
|
|
1785
|
+
"The system is in protection mode. Please wait a moment before retrying."
|
|
1786
|
+
]
|
|
1787
|
+
};
|
|
1788
|
+
}
|
|
1789
|
+
if (errorMessage.includes("No authentication token")) {
|
|
1790
|
+
return {
|
|
1791
|
+
message: "Not logged in",
|
|
1792
|
+
details: ['Run "stint login" to authenticate.']
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
const statusMatch = errorMessage.match(/API request failed: (\d{3})/);
|
|
1796
|
+
if (statusMatch) {
|
|
1797
|
+
return {
|
|
1798
|
+
message: `Request failed (HTTP ${statusMatch[1]})`,
|
|
1799
|
+
details: ["An unexpected error occurred. Please try again."]
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
return {
|
|
1803
|
+
message: "Connection error",
|
|
1804
|
+
details: ["An unexpected error occurred. Please try again."]
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
function isServiceUnavailable(error) {
|
|
1808
|
+
const msg = error.message;
|
|
1809
|
+
return msg.includes("503") || msg.includes("Service Unavailable") || msg.includes("ECONNREFUSED") || msg.includes("ENOTFOUND") || msg.includes("Circuit breaker");
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
// src/commands/doctor.ts
|
|
1722
1813
|
import { exec as exec3 } from "child_process";
|
|
1723
1814
|
import { promisify as promisify3 } from "util";
|
|
1724
1815
|
import process7 from "process";
|
|
@@ -1794,11 +1885,22 @@ function registerDoctorCommand(program2) {
|
|
|
1794
1885
|
success: true,
|
|
1795
1886
|
message: `Authenticated as ${user.email}`
|
|
1796
1887
|
};
|
|
1797
|
-
} catch {
|
|
1888
|
+
} catch (error) {
|
|
1889
|
+
if (isServiceUnavailable(error)) {
|
|
1890
|
+
const friendly = formatApiError(error);
|
|
1891
|
+
return {
|
|
1892
|
+
success: false,
|
|
1893
|
+
message: friendly.message,
|
|
1894
|
+
details: [
|
|
1895
|
+
...friendly.details,
|
|
1896
|
+
"Authentication check skipped due to connectivity issues."
|
|
1897
|
+
]
|
|
1898
|
+
};
|
|
1899
|
+
}
|
|
1798
1900
|
return {
|
|
1799
1901
|
success: false,
|
|
1800
|
-
message: "
|
|
1801
|
-
details: ['Run "stint login" to
|
|
1902
|
+
message: "Not authenticated",
|
|
1903
|
+
details: ['Run "stint login" to authenticate']
|
|
1802
1904
|
};
|
|
1803
1905
|
}
|
|
1804
1906
|
}
|
|
@@ -1813,10 +1915,11 @@ function registerDoctorCommand(program2) {
|
|
|
1813
1915
|
message: "API connection successful"
|
|
1814
1916
|
};
|
|
1815
1917
|
} catch (error) {
|
|
1918
|
+
const friendly = formatApiError(error);
|
|
1816
1919
|
return {
|
|
1817
1920
|
success: false,
|
|
1818
|
-
message:
|
|
1819
|
-
details:
|
|
1921
|
+
message: friendly.message,
|
|
1922
|
+
details: friendly.details
|
|
1820
1923
|
};
|
|
1821
1924
|
}
|
|
1822
1925
|
}
|
|
@@ -1840,10 +1943,11 @@ function registerDoctorCommand(program2) {
|
|
|
1840
1943
|
message: "WebSocket connection successful"
|
|
1841
1944
|
};
|
|
1842
1945
|
} catch (error) {
|
|
1946
|
+
const friendly = formatApiError(error);
|
|
1843
1947
|
return {
|
|
1844
1948
|
success: false,
|
|
1845
|
-
message:
|
|
1846
|
-
details:
|
|
1949
|
+
message: friendly.message,
|
|
1950
|
+
details: friendly.details
|
|
1847
1951
|
};
|
|
1848
1952
|
}
|
|
1849
1953
|
}
|
|
@@ -1890,7 +1994,7 @@ function registerDoctorCommand(program2) {
|
|
|
1890
1994
|
}
|
|
1891
1995
|
|
|
1892
1996
|
// src/index.ts
|
|
1893
|
-
var AGENT_VERSION = "1.2.
|
|
1997
|
+
var AGENT_VERSION = "1.2.4";
|
|
1894
1998
|
var program = new Command();
|
|
1895
1999
|
program.name("stint").description("Stint Agent - Local daemon for Stint Project Assistant").version(AGENT_VERSION, "-v, --version", "output the current version").addHelpText("after", `
|
|
1896
2000
|
${chalk13.bold("Examples:")}
|
package/package.json
CHANGED