@gowelle/stint-agent 1.2.3 → 1.2.5
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 +32 -4
- package/dist/{StatusDashboard-63AGKYJB.js → StatusDashboard-N6F7NTE6.js} +2 -2
- package/dist/api-CTKZUAEV.js +7 -0
- package/dist/{chunk-RLW3QCR7.js → chunk-7RFRGXTU.js} +1 -1
- package/dist/{chunk-J27QHXXT.js → chunk-M62KR3LR.js} +13 -2
- package/dist/{chunk-E5B6S5EK.js → chunk-MMZYYFJF.js} +17 -12
- package/dist/{chunk-4KNUG3GA.js → chunk-QSQGPVIU.js} +2 -2
- package/dist/daemon/runner.js +33 -4
- package/dist/index.js +17 -11
- package/package.json +1 -1
- package/dist/api-PEHB3UYL.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
|
|
|
@@ -117,6 +125,26 @@ stint status
|
|
|
117
125
|
# Now commits approved in the web app will execute automatically!
|
|
118
126
|
```
|
|
119
127
|
|
|
128
|
+
## Configuration
|
|
129
|
+
|
|
130
|
+
### Desktop Notifications
|
|
131
|
+
|
|
132
|
+
The daemon sends desktop notifications for important events (commit approved, new pending commits, project updates). Notifications are **enabled by default**.
|
|
133
|
+
|
|
134
|
+
**Disable notifications:**
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
stint config set notifications.enabled false
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Enable notifications:**
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
stint config set notifications.enabled true
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
> **Note:** Events are still logged even when notifications are disabled.
|
|
147
|
+
|
|
120
148
|
## Troubleshooting
|
|
121
149
|
|
|
122
150
|
For comprehensive troubleshooting help, see the **[Troubleshooting Guide](docs/TROUBLESHOOTING.md)**.
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
gitService,
|
|
3
3
|
projectService,
|
|
4
4
|
validatePidFile
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-7RFRGXTU.js";
|
|
6
6
|
import {
|
|
7
7
|
authService
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-M62KR3LR.js";
|
|
9
9
|
|
|
10
10
|
// src/components/StatusDashboard.tsx
|
|
11
11
|
import { useState, useEffect } from "react";
|
|
@@ -16,7 +16,10 @@ var DEFAULT_CONFIG = {
|
|
|
16
16
|
apiUrl: "https://stint.codes",
|
|
17
17
|
wsUrl: "wss://stint.codes/reverb",
|
|
18
18
|
reverbAppKey: "wtn6tu6lirfv6yflujk7",
|
|
19
|
-
projects: {}
|
|
19
|
+
projects: {},
|
|
20
|
+
notifications: {
|
|
21
|
+
enabled: true
|
|
22
|
+
}
|
|
20
23
|
};
|
|
21
24
|
var ConfigManager = class {
|
|
22
25
|
conf;
|
|
@@ -130,6 +133,14 @@ var ConfigManager = class {
|
|
|
130
133
|
setReverbAppKey(reverbAppKey) {
|
|
131
134
|
this.conf.set("reverbAppKey", reverbAppKey);
|
|
132
135
|
}
|
|
136
|
+
// Notification management
|
|
137
|
+
areNotificationsEnabled() {
|
|
138
|
+
const notifConfig = this.conf.get("notifications");
|
|
139
|
+
return notifConfig?.enabled ?? true;
|
|
140
|
+
}
|
|
141
|
+
setNotificationsEnabled(enabled) {
|
|
142
|
+
this.conf.set("notifications", { enabled });
|
|
143
|
+
}
|
|
133
144
|
};
|
|
134
145
|
var config = new ConfigManager();
|
|
135
146
|
|
|
@@ -271,7 +282,7 @@ var AuthServiceImpl = class {
|
|
|
271
282
|
return null;
|
|
272
283
|
}
|
|
273
284
|
try {
|
|
274
|
-
const { apiService } = await import("./api-
|
|
285
|
+
const { apiService } = await import("./api-CTKZUAEV.js");
|
|
275
286
|
const user = await apiService.getCurrentUser();
|
|
276
287
|
logger.info("auth", `Token validated for user: ${user.email}`);
|
|
277
288
|
return user;
|
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
2
|
apiService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QSQGPVIU.js";
|
|
4
4
|
import {
|
|
5
5
|
gitService,
|
|
6
6
|
projectService
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7RFRGXTU.js";
|
|
8
8
|
import {
|
|
9
9
|
authService,
|
|
10
10
|
config,
|
|
11
11
|
logger
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-M62KR3LR.js";
|
|
13
13
|
|
|
14
14
|
// src/utils/notify.ts
|
|
15
15
|
import notifier from "node-notifier";
|
|
16
16
|
function notify(options) {
|
|
17
|
+
if (!config.areNotificationsEnabled()) {
|
|
18
|
+
logger.debug("notify", "Notifications disabled, skipping notification");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
17
21
|
try {
|
|
18
22
|
notifier.notify({
|
|
19
23
|
title: options.title,
|
|
20
24
|
message: options.message,
|
|
21
25
|
open: options.open,
|
|
26
|
+
icon: options.icon,
|
|
22
27
|
sound: true,
|
|
23
28
|
wait: false,
|
|
24
29
|
appID: "Stint Agent"
|
|
@@ -353,9 +358,9 @@ var WebSocketServiceImpl = class {
|
|
|
353
358
|
return;
|
|
354
359
|
}
|
|
355
360
|
if (message.event === "commit.approved") {
|
|
356
|
-
const {
|
|
357
|
-
logger.info("websocket", `Commit approved: ${
|
|
358
|
-
this.commitApprovedHandlers.forEach((handler) => handler(
|
|
361
|
+
const { pendingCommit } = message.data;
|
|
362
|
+
logger.info("websocket", `Commit approved: ${pendingCommit.id}`);
|
|
363
|
+
this.commitApprovedHandlers.forEach((handler) => handler(pendingCommit, pendingCommit.project));
|
|
359
364
|
return;
|
|
360
365
|
}
|
|
361
366
|
if (message.event === "commit.pending") {
|
|
@@ -377,15 +382,15 @@ var WebSocketServiceImpl = class {
|
|
|
377
382
|
return;
|
|
378
383
|
}
|
|
379
384
|
if (message.event === "sync.requested") {
|
|
380
|
-
const {
|
|
381
|
-
logger.info("websocket", `Sync requested for project: ${
|
|
382
|
-
this.syncRequestedHandlers.forEach((handler) => handler(
|
|
385
|
+
const { project } = message.data;
|
|
386
|
+
logger.info("websocket", `Sync requested for project: ${project.id}`);
|
|
387
|
+
this.syncRequestedHandlers.forEach((handler) => handler(project.id));
|
|
383
388
|
return;
|
|
384
389
|
}
|
|
385
390
|
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));
|
|
391
|
+
const { reason } = message.data;
|
|
392
|
+
logger.warn("websocket", `Agent disconnected by server: ${reason ?? "Server requested disconnect"}`);
|
|
393
|
+
this.agentDisconnectedHandlers.forEach((handler) => handler(reason ?? "Server requested disconnect"));
|
|
389
394
|
return;
|
|
390
395
|
}
|
|
391
396
|
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-M62KR3LR.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.5";
|
|
102
102
|
var ApiServiceImpl = class {
|
|
103
103
|
sessionId = null;
|
|
104
104
|
circuitBreaker = new CircuitBreaker({
|
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-MMZYYFJF.js";
|
|
7
7
|
import {
|
|
8
8
|
apiService
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-QSQGPVIU.js";
|
|
10
10
|
import {
|
|
11
11
|
gitService,
|
|
12
12
|
projectService,
|
|
13
13
|
removePidFile,
|
|
14
14
|
writePidFile
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-7RFRGXTU.js";
|
|
16
16
|
import {
|
|
17
17
|
authService,
|
|
18
18
|
logger
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-M62KR3LR.js";
|
|
20
20
|
|
|
21
21
|
// src/daemon/runner.ts
|
|
22
22
|
import "dotenv/config";
|
|
@@ -250,10 +250,26 @@ async function startDaemon() {
|
|
|
250
250
|
websocketService.subscribeToUserChannel(user.id);
|
|
251
251
|
websocketService.onCommitApproved((commit, project) => {
|
|
252
252
|
logger.info("daemon", `Commit approved: ${commit.id} for project ${project.name}`);
|
|
253
|
+
notify({
|
|
254
|
+
title: "Commit Approved",
|
|
255
|
+
message: `${commit.message}
|
|
256
|
+
Project: ${project.name}`
|
|
257
|
+
});
|
|
253
258
|
commitQueue.addToQueue(commit, project);
|
|
254
259
|
});
|
|
260
|
+
websocketService.onCommitPending((commit) => {
|
|
261
|
+
logger.info("daemon", `Commit pending: ${commit.id}`);
|
|
262
|
+
notify({
|
|
263
|
+
title: "New Pending Commit",
|
|
264
|
+
message: commit.message
|
|
265
|
+
});
|
|
266
|
+
});
|
|
255
267
|
websocketService.onProjectUpdated((project) => {
|
|
256
268
|
logger.info("daemon", `Project updated: ${project.id} - ${project.name}`);
|
|
269
|
+
notify({
|
|
270
|
+
title: "Project Updated",
|
|
271
|
+
message: project.name
|
|
272
|
+
});
|
|
257
273
|
});
|
|
258
274
|
websocketService.onDisconnect(() => {
|
|
259
275
|
logger.warn("daemon", "WebSocket disconnected, will attempt to reconnect");
|
|
@@ -285,6 +301,19 @@ Priority: ${suggestion.priority}`,
|
|
|
285
301
|
setupSignalHandlers();
|
|
286
302
|
startHeartbeat();
|
|
287
303
|
fileWatcher.start();
|
|
304
|
+
const linkedProjects = projectService.getAllLinkedProjects();
|
|
305
|
+
const projectEntries = Object.entries(linkedProjects);
|
|
306
|
+
if (projectEntries.length > 0) {
|
|
307
|
+
logger.info("daemon", `Syncing ${projectEntries.length} linked project(s) on startup...`);
|
|
308
|
+
for (const [, linkedProject] of projectEntries) {
|
|
309
|
+
try {
|
|
310
|
+
await fileWatcher.syncProjectById(linkedProject.projectId);
|
|
311
|
+
} catch (error) {
|
|
312
|
+
logger.error("daemon", `Failed to sync project ${linkedProject.projectId} on startup`, error);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
logger.success("daemon", "Initial project sync complete");
|
|
316
|
+
}
|
|
288
317
|
logger.success("daemon", "Daemon started successfully");
|
|
289
318
|
await new Promise(() => {
|
|
290
319
|
});
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
commitQueue,
|
|
4
4
|
websocketService
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MMZYYFJF.js";
|
|
6
6
|
import {
|
|
7
7
|
apiService
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QSQGPVIU.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-7RFRGXTU.js";
|
|
18
18
|
import {
|
|
19
19
|
authService,
|
|
20
20
|
config,
|
|
21
21
|
logger
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-M62KR3LR.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-N6F7NTE6.js");
|
|
624
624
|
render(createElement(StatusDashboard, { cwd }));
|
|
625
625
|
return;
|
|
626
626
|
} catch (error) {
|
|
@@ -1281,11 +1281,17 @@ function registerCommitCommands(program2) {
|
|
|
1281
1281
|
}
|
|
1282
1282
|
const commit = matchingCommits[0];
|
|
1283
1283
|
let status = await gitService.getStatus(cwd);
|
|
1284
|
-
if (options.autoStage
|
|
1285
|
-
|
|
1286
|
-
|
|
1284
|
+
if (options.autoStage) {
|
|
1285
|
+
if (commit.files && commit.files.length > 0) {
|
|
1286
|
+
activeSpinner.text = `Staging ${commit.files.length} files...`;
|
|
1287
|
+
await gitService.stageFiles(cwd, commit.files);
|
|
1288
|
+
logger.info("commit", `Auto-staged files: ${commit.files.join(", ")}`);
|
|
1289
|
+
} else {
|
|
1290
|
+
activeSpinner.text = "Staging all changes...";
|
|
1291
|
+
await gitService.stageAll(cwd);
|
|
1292
|
+
logger.info("commit", "Auto-staged all changes");
|
|
1293
|
+
}
|
|
1287
1294
|
status = await gitService.getStatus(cwd);
|
|
1288
|
-
logger.info("commit", `Auto-staged files: ${commit.files.join(", ")}`);
|
|
1289
1295
|
}
|
|
1290
1296
|
if (status.staged.length === 0) {
|
|
1291
1297
|
activeSpinner.fail("No staged changes");
|
|
@@ -1294,7 +1300,7 @@ function registerCommitCommands(program2) {
|
|
|
1294
1300
|
console.log(chalk9.gray("Expected files: " + commit.files.join(", ")));
|
|
1295
1301
|
console.log(chalk9.gray("\nUse --auto-stage to automatically stage expected files."));
|
|
1296
1302
|
} else {
|
|
1297
|
-
console.log(chalk9.gray("
|
|
1303
|
+
console.log(chalk9.gray("Use --auto-stage to automatically stage all changes, or stage files manually:"));
|
|
1298
1304
|
console.log(chalk9.gray(" git add <files>\n"));
|
|
1299
1305
|
}
|
|
1300
1306
|
process6.exit(1);
|
|
@@ -1994,7 +2000,7 @@ function registerDoctorCommand(program2) {
|
|
|
1994
2000
|
}
|
|
1995
2001
|
|
|
1996
2002
|
// src/index.ts
|
|
1997
|
-
var AGENT_VERSION = "1.2.
|
|
2003
|
+
var AGENT_VERSION = "1.2.5";
|
|
1998
2004
|
var program = new Command();
|
|
1999
2005
|
program.name("stint").description("Stint Agent - Local daemon for Stint Project Assistant").version(AGENT_VERSION, "-v, --version", "output the current version").addHelpText("after", `
|
|
2000
2006
|
${chalk13.bold("Examples:")}
|
package/package.json
CHANGED