@gowelle/stint-agent 1.2.0 → 1.2.2
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-7ZIGEOQ4.js → StatusDashboard-NTJAONDR.js} +2 -2
- package/dist/api-XYDQ3I2Y.js +7 -0
- package/dist/{chunk-RHMTZK2J.js → chunk-2QJPWC56.js} +1 -1
- package/dist/{chunk-FBQA4K5J.js → chunk-FY5S22C3.js} +21 -1
- package/dist/{chunk-W4JGOGR7.js → chunk-GG6LVSVC.js} +9 -6
- package/dist/{chunk-IJUJ6NEL.js → chunk-XLTOQPAD.js} +81 -12
- package/dist/daemon/runner.js +5 -26
- package/dist/index.js +88 -32
- package/package.json +1 -1
- package/dist/api-HLTR2LTF.js +0 -7
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
gitService,
|
|
3
3
|
projectService,
|
|
4
4
|
validatePidFile
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FY5S22C3.js";
|
|
6
6
|
import {
|
|
7
7
|
authService
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-2QJPWC56.js";
|
|
9
9
|
|
|
10
10
|
// src/components/StatusDashboard.tsx
|
|
11
11
|
import { useState, useEffect } from "react";
|
|
@@ -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-XYDQ3I2Y.js");
|
|
275
275
|
const user = await apiService.getCurrentUser();
|
|
276
276
|
logger.info("auth", `Token validated for user: ${user.email}`);
|
|
277
277
|
return user;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
config,
|
|
3
3
|
logger
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2QJPWC56.js";
|
|
5
5
|
|
|
6
6
|
// src/services/git.ts
|
|
7
7
|
import simpleGit from "simple-git";
|
|
@@ -150,6 +150,26 @@ var GitServiceImpl = class {
|
|
|
150
150
|
throw new Error(`Failed to get git status: ${error.message}`);
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Push commits to remote repository
|
|
155
|
+
* @param path - Repository path
|
|
156
|
+
* @param remote - Remote name (default: 'origin')
|
|
157
|
+
* @param branch - Branch name (optional, uses current branch if not specified)
|
|
158
|
+
*/
|
|
159
|
+
async push(path3, remote = "origin", branch) {
|
|
160
|
+
try {
|
|
161
|
+
const git = this.getGit(path3);
|
|
162
|
+
if (branch) {
|
|
163
|
+
await git.push(remote, branch);
|
|
164
|
+
} else {
|
|
165
|
+
await git.push(remote);
|
|
166
|
+
}
|
|
167
|
+
logger.success("git", `Pushed to ${remote} in ${path3}`);
|
|
168
|
+
} catch (error) {
|
|
169
|
+
logger.error("git", `Failed to push in ${path3}`, error);
|
|
170
|
+
throw new Error(`Failed to push: ${error.message}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
153
173
|
async getRepoRoot(path3) {
|
|
154
174
|
try {
|
|
155
175
|
const git = this.getGit(path3);
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
authService,
|
|
3
3
|
config,
|
|
4
4
|
logger
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2QJPWC56.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.2";
|
|
102
102
|
var ApiServiceImpl = class {
|
|
103
103
|
sessionId = null;
|
|
104
104
|
circuitBreaker = new CircuitBreaker({
|
|
@@ -275,16 +275,18 @@ var ApiServiceImpl = class {
|
|
|
275
275
|
* Mark a commit as successfully executed
|
|
276
276
|
* @param commitId - Commit ID
|
|
277
277
|
* @param sha - Git commit SHA
|
|
278
|
+
* @param pushed - Whether the commit was pushed to remote (default: true)
|
|
279
|
+
* @param pushError - Error message if push failed
|
|
278
280
|
* @returns Updated commit data
|
|
279
281
|
*/
|
|
280
|
-
async markCommitExecuted(commitId, sha) {
|
|
281
|
-
logger.info("api", `Marking commit ${commitId} as executed (SHA: ${sha})`);
|
|
282
|
+
async markCommitExecuted(commitId, sha, pushed = true, pushError) {
|
|
283
|
+
logger.info("api", `Marking commit ${commitId} as executed (SHA: ${sha}, pushed: ${pushed})`);
|
|
282
284
|
return this.withRetry(async () => {
|
|
283
285
|
const response = await this.request(
|
|
284
286
|
`/api/agent/commits/${commitId}/executed`,
|
|
285
287
|
{
|
|
286
288
|
method: "POST",
|
|
287
|
-
body: JSON.stringify({ sha })
|
|
289
|
+
body: JSON.stringify({ sha, pushed, push_error: pushError })
|
|
288
290
|
}
|
|
289
291
|
);
|
|
290
292
|
const data = response.data;
|
|
@@ -302,7 +304,8 @@ var ApiServiceImpl = class {
|
|
|
302
304
|
status: data.status,
|
|
303
305
|
createdAt,
|
|
304
306
|
executedAt,
|
|
305
|
-
error: data.error
|
|
307
|
+
error: data.error,
|
|
308
|
+
pushError: data.push_error || data.pushError
|
|
306
309
|
};
|
|
307
310
|
logger.success("api", `Commit ${commitId} marked as executed`);
|
|
308
311
|
return commit;
|
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
import {
|
|
2
2
|
apiService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GG6LVSVC.js";
|
|
4
4
|
import {
|
|
5
5
|
gitService,
|
|
6
6
|
projectService
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-FY5S22C3.js";
|
|
8
8
|
import {
|
|
9
9
|
authService,
|
|
10
10
|
config,
|
|
11
11
|
logger
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-2QJPWC56.js";
|
|
13
|
+
|
|
14
|
+
// src/utils/notify.ts
|
|
15
|
+
import notifier from "node-notifier";
|
|
16
|
+
function notify(options) {
|
|
17
|
+
try {
|
|
18
|
+
notifier.notify({
|
|
19
|
+
title: options.title,
|
|
20
|
+
message: options.message,
|
|
21
|
+
open: options.open,
|
|
22
|
+
sound: true,
|
|
23
|
+
wait: false,
|
|
24
|
+
appID: "Stint Agent"
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
}, (error) => {
|
|
27
|
+
if (error) {
|
|
28
|
+
logger.error("notify", "Failed to send notification", error);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
} catch (error) {
|
|
32
|
+
logger.error("notify", "Failed to send notification", error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
13
35
|
|
|
14
36
|
// src/daemon/queue.ts
|
|
15
37
|
var CommitQueueProcessor = class {
|
|
@@ -47,7 +69,7 @@ var CommitQueueProcessor = class {
|
|
|
47
69
|
/**
|
|
48
70
|
* Execute a single commit
|
|
49
71
|
*/
|
|
50
|
-
async executeCommit(commit, project, onProgress) {
|
|
72
|
+
async executeCommit(commit, project, onProgress, options) {
|
|
51
73
|
logger.info("queue", `Processing commit: ${commit.id} - ${commit.message}`);
|
|
52
74
|
try {
|
|
53
75
|
onProgress?.("Finding project directory...");
|
|
@@ -62,18 +84,59 @@ var CommitQueueProcessor = class {
|
|
|
62
84
|
throw new Error(`Directory ${projectPath} is not a git repository`);
|
|
63
85
|
}
|
|
64
86
|
onProgress?.("Checking repository status...");
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
let status = await gitService.getStatus(projectPath);
|
|
88
|
+
if (commit.files && commit.files.length > 0) {
|
|
89
|
+
onProgress?.(`Staging ${commit.files.length} specified files...`);
|
|
90
|
+
await gitService.stageFiles(projectPath, commit.files);
|
|
91
|
+
status = await gitService.getStatus(projectPath);
|
|
92
|
+
logger.info("queue", `Auto-staged files: ${commit.files.join(", ")}`);
|
|
93
|
+
} else if (status.staged.length === 0) {
|
|
94
|
+
const hasChanges = status.unstaged.length > 0 || status.untracked.length > 0;
|
|
95
|
+
if (hasChanges) {
|
|
96
|
+
onProgress?.("Staging all changes...");
|
|
97
|
+
await gitService.stageAll(projectPath);
|
|
98
|
+
status = await gitService.getStatus(projectPath);
|
|
99
|
+
logger.info("queue", `Auto-staged all changes`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (status.staged.length === 0) {
|
|
103
|
+
throw new Error("No changes to commit. The working directory is clean.");
|
|
69
104
|
}
|
|
70
105
|
logger.info("queue", `Committing ${status.staged.length} staged files.`);
|
|
71
106
|
onProgress?.("Creating commit...");
|
|
72
107
|
logger.info("queue", `Creating commit with message: "${commit.message}"`);
|
|
73
108
|
const sha = await gitService.commit(projectPath, commit.message);
|
|
74
109
|
logger.success("queue", `Commit created successfully: ${sha}`);
|
|
110
|
+
let pushed = false;
|
|
111
|
+
let pushError;
|
|
112
|
+
const shouldPush = options?.push !== false;
|
|
113
|
+
if (shouldPush) {
|
|
114
|
+
try {
|
|
115
|
+
onProgress?.("Pushing to remote...");
|
|
116
|
+
await gitService.push(projectPath);
|
|
117
|
+
pushed = true;
|
|
118
|
+
logger.success("queue", `Pushed commit ${sha} to remote`);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
pushError = error.message;
|
|
121
|
+
const isConflict = pushError.includes("rejected") || pushError.includes("non-fast-forward") || pushError.includes("failed to push") || pushError.includes("Updates were rejected");
|
|
122
|
+
if (isConflict) {
|
|
123
|
+
logger.warn("queue", `Push failed due to remote conflict: ${pushError}`);
|
|
124
|
+
notify({
|
|
125
|
+
title: "\u26A0\uFE0F Push Failed - Manual Action Required",
|
|
126
|
+
message: `Commit "${commit.message}" created but push failed.
|
|
127
|
+
Run "git pull --rebase && git push" to resolve.`
|
|
128
|
+
});
|
|
129
|
+
} else {
|
|
130
|
+
logger.error("queue", `Push failed: ${pushError}`);
|
|
131
|
+
notify({
|
|
132
|
+
title: "\u274C Push Failed",
|
|
133
|
+
message: `Commit created but push failed: ${pushError}`
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
75
138
|
onProgress?.("Reporting to server...");
|
|
76
|
-
await this.reportSuccess(commit.id, sha);
|
|
139
|
+
await this.reportSuccess(commit.id, sha, pushed, pushError);
|
|
77
140
|
return sha;
|
|
78
141
|
} catch (error) {
|
|
79
142
|
const errorMessage = error.message;
|
|
@@ -84,11 +147,16 @@ var CommitQueueProcessor = class {
|
|
|
84
147
|
}
|
|
85
148
|
/**
|
|
86
149
|
* Report successful execution to API
|
|
150
|
+
* @param commitId - Commit ID
|
|
151
|
+
* @param sha - Git commit SHA
|
|
152
|
+
* @param pushed - Whether the commit was pushed to remote
|
|
153
|
+
* @param pushError - Error message if push failed
|
|
87
154
|
*/
|
|
88
|
-
async reportSuccess(commitId, sha) {
|
|
155
|
+
async reportSuccess(commitId, sha, pushed = true, pushError) {
|
|
89
156
|
try {
|
|
90
|
-
await apiService.markCommitExecuted(commitId, sha);
|
|
91
|
-
|
|
157
|
+
await apiService.markCommitExecuted(commitId, sha, pushed, pushError);
|
|
158
|
+
const status = pushed ? "executed" : "committed (push failed)";
|
|
159
|
+
logger.success("queue", `Reported commit ${status} to API: ${commitId} -> ${sha}`);
|
|
92
160
|
} catch (error) {
|
|
93
161
|
logger.error("queue", "Failed to report commit success to API", error);
|
|
94
162
|
}
|
|
@@ -364,6 +432,7 @@ var WebSocketServiceImpl = class {
|
|
|
364
432
|
var websocketService = new WebSocketServiceImpl();
|
|
365
433
|
|
|
366
434
|
export {
|
|
435
|
+
notify,
|
|
367
436
|
commitQueue,
|
|
368
437
|
websocketService
|
|
369
438
|
};
|
package/dist/daemon/runner.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
commitQueue,
|
|
4
|
+
notify,
|
|
4
5
|
websocketService
|
|
5
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-XLTOQPAD.js";
|
|
6
7
|
import {
|
|
7
8
|
apiService
|
|
8
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-GG6LVSVC.js";
|
|
9
10
|
import {
|
|
10
11
|
gitService,
|
|
11
12
|
projectService,
|
|
12
13
|
removePidFile,
|
|
13
14
|
writePidFile
|
|
14
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-FY5S22C3.js";
|
|
15
16
|
import {
|
|
16
17
|
authService,
|
|
17
18
|
logger
|
|
18
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-2QJPWC56.js";
|
|
19
20
|
|
|
20
21
|
// src/daemon/runner.ts
|
|
21
22
|
import "dotenv/config";
|
|
@@ -223,28 +224,6 @@ var FileWatcher = class {
|
|
|
223
224
|
}
|
|
224
225
|
};
|
|
225
226
|
|
|
226
|
-
// src/utils/notify.ts
|
|
227
|
-
import notifier from "node-notifier";
|
|
228
|
-
function notify(options) {
|
|
229
|
-
try {
|
|
230
|
-
notifier.notify({
|
|
231
|
-
title: options.title,
|
|
232
|
-
message: options.message,
|
|
233
|
-
open: options.open,
|
|
234
|
-
sound: true,
|
|
235
|
-
wait: false,
|
|
236
|
-
appID: "Stint Agent"
|
|
237
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
238
|
-
}, (error) => {
|
|
239
|
-
if (error) {
|
|
240
|
-
logger.error("notify", "Failed to send notification", error);
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
} catch (error) {
|
|
244
|
-
logger.error("notify", "Failed to send notification", error);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
227
|
// src/daemon/index.ts
|
|
249
228
|
var heartbeatInterval = null;
|
|
250
229
|
var isShuttingDown = false;
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
commitQueue,
|
|
4
4
|
websocketService
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-XLTOQPAD.js";
|
|
6
6
|
import {
|
|
7
7
|
apiService
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-GG6LVSVC.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-FY5S22C3.js";
|
|
18
18
|
import {
|
|
19
19
|
authService,
|
|
20
20
|
config,
|
|
21
21
|
logger
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-2QJPWC56.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-NTJAONDR.js");
|
|
624
624
|
render(createElement(StatusDashboard, { cwd }));
|
|
625
625
|
return;
|
|
626
626
|
} catch (error) {
|
|
@@ -1244,37 +1244,90 @@ function registerCommitCommands(program2) {
|
|
|
1244
1244
|
process6.exit(1);
|
|
1245
1245
|
}
|
|
1246
1246
|
});
|
|
1247
|
-
program2.command("commit <id>").description("Execute a specific pending commit").action(async (id) => {
|
|
1248
|
-
|
|
1247
|
+
program2.command("commit <id>").description("Execute a specific pending commit").option("--auto-stage", "Automatically stage files specified in the pending commit").option("--push", "Push changes to remote after committing").option("--force", "Skip file validation warnings").action(async (id, options) => {
|
|
1248
|
+
let activeSpinner = null;
|
|
1249
1249
|
try {
|
|
1250
|
+
activeSpinner = ora9("Checking repository status...").start();
|
|
1250
1251
|
const cwd = process6.cwd();
|
|
1251
1252
|
const linkedProject = await projectService.getLinkedProject(cwd);
|
|
1252
1253
|
if (!linkedProject) {
|
|
1253
|
-
|
|
1254
|
+
activeSpinner.fail("Not linked");
|
|
1254
1255
|
console.log(chalk9.yellow("\n\u26A0 This directory is not linked to any project."));
|
|
1255
1256
|
console.log(chalk9.gray('Run "stint link" first to link this directory.\n'));
|
|
1256
1257
|
process6.exit(1);
|
|
1257
1258
|
}
|
|
1258
|
-
|
|
1259
|
-
if (status.staged.length === 0) {
|
|
1260
|
-
spinner.fail("No staged changes");
|
|
1261
|
-
console.log(chalk9.yellow("\n\u26A0 No staged changes detected."));
|
|
1262
|
-
console.log(chalk9.gray("Please stage the files you want to commit first."));
|
|
1263
|
-
console.log(chalk9.gray(" git add <files>\n"));
|
|
1264
|
-
process6.exit(1);
|
|
1265
|
-
}
|
|
1266
|
-
spinner.text = "Fetching commit details...";
|
|
1259
|
+
activeSpinner.text = "Fetching commit details...";
|
|
1267
1260
|
const commits = await apiService.getPendingCommits(linkedProject.projectId);
|
|
1268
|
-
const
|
|
1269
|
-
if (
|
|
1270
|
-
|
|
1261
|
+
const matchingCommits = commits.filter((c) => c.id.startsWith(id));
|
|
1262
|
+
if (matchingCommits.length === 0) {
|
|
1263
|
+
activeSpinner.fail("Commit not found");
|
|
1271
1264
|
console.log(chalk9.red(`
|
|
1272
1265
|
\u2716 Commit ${id} not found in pending commits.
|
|
1273
1266
|
`));
|
|
1274
1267
|
console.log(chalk9.gray('Run "stint commits" to see available commits.\n'));
|
|
1275
1268
|
process6.exit(1);
|
|
1276
1269
|
}
|
|
1277
|
-
|
|
1270
|
+
if (matchingCommits.length > 1) {
|
|
1271
|
+
activeSpinner.fail("Ambiguous commit ID");
|
|
1272
|
+
console.log(chalk9.yellow(`
|
|
1273
|
+
\u26A0 Multiple commits match "${id}":
|
|
1274
|
+
`));
|
|
1275
|
+
matchingCommits.forEach((c) => {
|
|
1276
|
+
const shortId = c.id.substring(0, 12);
|
|
1277
|
+
console.log(` ${chalk9.cyan(shortId)} ${c.message}`);
|
|
1278
|
+
});
|
|
1279
|
+
console.log(chalk9.gray("\nPlease use a longer ID to be more specific.\n"));
|
|
1280
|
+
process6.exit(1);
|
|
1281
|
+
}
|
|
1282
|
+
const commit = matchingCommits[0];
|
|
1283
|
+
let status = await gitService.getStatus(cwd);
|
|
1284
|
+
if (options.autoStage && commit.files && commit.files.length > 0) {
|
|
1285
|
+
activeSpinner.text = `Staging ${commit.files.length} files...`;
|
|
1286
|
+
await gitService.stageFiles(cwd, commit.files);
|
|
1287
|
+
status = await gitService.getStatus(cwd);
|
|
1288
|
+
logger.info("commit", `Auto-staged files: ${commit.files.join(", ")}`);
|
|
1289
|
+
}
|
|
1290
|
+
if (status.staged.length === 0) {
|
|
1291
|
+
activeSpinner.fail("No staged changes");
|
|
1292
|
+
console.log(chalk9.yellow("\n\u26A0 No staged changes detected."));
|
|
1293
|
+
if (commit.files && commit.files.length > 0) {
|
|
1294
|
+
console.log(chalk9.gray("Expected files: " + commit.files.join(", ")));
|
|
1295
|
+
console.log(chalk9.gray("\nUse --auto-stage to automatically stage expected files."));
|
|
1296
|
+
} else {
|
|
1297
|
+
console.log(chalk9.gray("Please stage the files you want to commit first."));
|
|
1298
|
+
console.log(chalk9.gray(" git add <files>\n"));
|
|
1299
|
+
}
|
|
1300
|
+
process6.exit(1);
|
|
1301
|
+
}
|
|
1302
|
+
if (commit.files && commit.files.length > 0 && !options.force && !options.autoStage) {
|
|
1303
|
+
const stagedSet = new Set(status.staged);
|
|
1304
|
+
const expectedSet = new Set(commit.files);
|
|
1305
|
+
const missing = commit.files.filter((f) => !stagedSet.has(f));
|
|
1306
|
+
const extra = status.staged.filter((f) => !expectedSet.has(f));
|
|
1307
|
+
if (missing.length > 0 || extra.length > 0) {
|
|
1308
|
+
activeSpinner.stop();
|
|
1309
|
+
console.log(chalk9.yellow("\n\u26A0 Staged files do not match expected files:\n"));
|
|
1310
|
+
if (missing.length > 0) {
|
|
1311
|
+
console.log(chalk9.red(" Missing (expected but not staged):"));
|
|
1312
|
+
missing.forEach((f) => console.log(chalk9.red(` - ${f}`)));
|
|
1313
|
+
}
|
|
1314
|
+
if (extra.length > 0) {
|
|
1315
|
+
console.log(chalk9.yellow("\n Extra (staged but not expected):"));
|
|
1316
|
+
extra.forEach((f) => console.log(chalk9.yellow(` + ${f}`)));
|
|
1317
|
+
}
|
|
1318
|
+
console.log();
|
|
1319
|
+
const proceed = await confirm2({
|
|
1320
|
+
message: "Do you want to proceed anyway?",
|
|
1321
|
+
default: false
|
|
1322
|
+
});
|
|
1323
|
+
if (!proceed) {
|
|
1324
|
+
console.log(chalk9.gray("\nCommit cancelled. Use --auto-stage to stage expected files.\n"));
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
activeSpinner = ora9("Continuing...").start();
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
activeSpinner.stop();
|
|
1278
1331
|
console.log(chalk9.blue("\n\u{1F4CB} Staged changes to commit:"));
|
|
1279
1332
|
console.log(chalk9.gray("\u2500".repeat(40)));
|
|
1280
1333
|
status.staged.forEach((file) => {
|
|
@@ -1282,6 +1335,9 @@ function registerCommitCommands(program2) {
|
|
|
1282
1335
|
});
|
|
1283
1336
|
console.log();
|
|
1284
1337
|
console.log(`${chalk9.bold("Message:")} ${commit.message}`);
|
|
1338
|
+
if (options.push) {
|
|
1339
|
+
console.log(`${chalk9.bold("Push:")} ${chalk9.cyan("Yes (will push after commit)")}`);
|
|
1340
|
+
}
|
|
1285
1341
|
console.log();
|
|
1286
1342
|
const confirmed = await confirm2({
|
|
1287
1343
|
message: "Are you sure you want to commit these changes?",
|
|
@@ -1291,24 +1347,26 @@ function registerCommitCommands(program2) {
|
|
|
1291
1347
|
console.log(chalk9.yellow("\nCommit cancelled.\n"));
|
|
1292
1348
|
return;
|
|
1293
1349
|
}
|
|
1294
|
-
|
|
1350
|
+
activeSpinner = ora9("Preparing commit...").start();
|
|
1295
1351
|
const project = {
|
|
1296
1352
|
id: linkedProject.projectId,
|
|
1297
1353
|
name: "Current Project",
|
|
1298
|
-
// We don't have the name, but it's not critical
|
|
1299
1354
|
createdAt: "",
|
|
1300
1355
|
updatedAt: ""
|
|
1301
1356
|
};
|
|
1302
1357
|
const sha = await commitQueue.executeCommit(commit, project, (stage) => {
|
|
1303
|
-
|
|
1304
|
-
});
|
|
1305
|
-
|
|
1358
|
+
if (activeSpinner) activeSpinner.text = stage;
|
|
1359
|
+
}, { push: options.push ?? false });
|
|
1360
|
+
activeSpinner.succeed("Commit executed successfully!");
|
|
1306
1361
|
console.log(chalk9.green("\n\u2713 Commit executed"));
|
|
1307
1362
|
console.log(chalk9.gray("\u2500".repeat(50)));
|
|
1308
1363
|
console.log(`${chalk9.bold("Commit ID:")} ${commit.id}`);
|
|
1309
1364
|
console.log(`${chalk9.bold("Message:")} ${commit.message}`);
|
|
1310
1365
|
console.log(`${chalk9.bold("SHA:")} ${sha}`);
|
|
1311
1366
|
console.log(`${chalk9.bold("Files:")} ${status.staged.length} files committed`);
|
|
1367
|
+
if (options.push) {
|
|
1368
|
+
console.log(`${chalk9.bold("Pushed:")} ${chalk9.green("Yes")}`);
|
|
1369
|
+
}
|
|
1312
1370
|
console.log();
|
|
1313
1371
|
if (status.staged.length > 0) {
|
|
1314
1372
|
console.log(chalk9.gray("Committed files:"));
|
|
@@ -1319,9 +1377,7 @@ function registerCommitCommands(program2) {
|
|
|
1319
1377
|
}
|
|
1320
1378
|
logger.success("commit", `Executed commit ${commit.id} -> ${sha}`);
|
|
1321
1379
|
} catch (error) {
|
|
1322
|
-
|
|
1323
|
-
ora9().fail("Commit execution failed");
|
|
1324
|
-
}
|
|
1380
|
+
activeSpinner?.fail("Commit execution failed");
|
|
1325
1381
|
logger.error("commit", "Failed to execute commit", error);
|
|
1326
1382
|
console.error(chalk9.red(`
|
|
1327
1383
|
\u2716 Error: ${error.message}
|
|
@@ -1595,12 +1651,12 @@ async function getLatestVersionForChannel(channel) {
|
|
|
1595
1651
|
return channelVersions[0];
|
|
1596
1652
|
}
|
|
1597
1653
|
function registerUpdateCommand(program2) {
|
|
1598
|
-
program2.command("update").description("Update stint agent to the latest version").option("-c, --channel <channel>", "Release channel (stable, beta, nightly)").action(async (
|
|
1654
|
+
program2.command("update").description("Update stint agent to the latest version").option("-c, --channel <channel>", "Release channel (stable, beta, nightly)").action(async (options) => {
|
|
1599
1655
|
const spinner = ora11("Checking for updates...").start();
|
|
1600
1656
|
try {
|
|
1601
1657
|
const currentVersion = program2.version();
|
|
1602
1658
|
const config2 = getChannelConfig();
|
|
1603
|
-
const channel = (
|
|
1659
|
+
const channel = (options.channel || config2.defaultChannel).toLowerCase();
|
|
1604
1660
|
if (!config2.channels[channel]) {
|
|
1605
1661
|
spinner.fail(`Invalid channel: ${channel}`);
|
|
1606
1662
|
console.log(chalk11.gray("\nAvailable channels:"));
|
|
@@ -1834,7 +1890,7 @@ function registerDoctorCommand(program2) {
|
|
|
1834
1890
|
}
|
|
1835
1891
|
|
|
1836
1892
|
// src/index.ts
|
|
1837
|
-
var AGENT_VERSION = "1.2.
|
|
1893
|
+
var AGENT_VERSION = "1.2.2";
|
|
1838
1894
|
var program = new Command();
|
|
1839
1895
|
program.name("stint").description("Stint Agent - Local daemon for Stint Project Assistant").version(AGENT_VERSION, "-v, --version", "output the current version").addHelpText("after", `
|
|
1840
1896
|
${chalk13.bold("Examples:")}
|
package/package.json
CHANGED