@gowelle/stint-agent 1.2.20 → 1.2.22

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 CHANGED
@@ -20,6 +20,7 @@ The official CLI agent for [Stint](https://stint.codes) — a lightweight daemon
20
20
  - 🚀 Multiple release channels (stable/beta/nightly)
21
21
  - 🔍 Built-in environment diagnostics
22
22
  - 📈 Resource usage monitoring
23
+ - 📁 File selection for commits (sync changed files to web app)
23
24
 
24
25
  For detailed feature documentation, see the **[Features Guide](docs/features.md)**.
25
26
 
@@ -105,32 +106,16 @@ stint daemon status
105
106
  | `--push` | Push changes to remote after committing |
106
107
  | `--force` | Skip file validation warnings |
107
108
 
108
- ### Updates
109
+ ### Commit Workflow Controls
109
110
 
110
- | Command | Description |
111
- | ---------------------------- | ---------------------------------------------- |
112
- | `stint update` | Update to latest stable version |
113
- | `stint update --check` | Check for updates without installing |
114
- | `stint update --channel beta`| Update to beta channel |
115
- | `stint update -y` | Skip confirmation prompt |
111
+ Stint supports advanced commit controls configured via the web dashboard:
116
112
 
117
- **Automatic Update Checks:**
113
+ 1. **Commit Templates**: Enforce message conventions (e.g., conventional commits).
114
+ 2. **Pre-commit Hooks**: Automatically run local commands (linting, tests) before the agent executes a commit.
115
+ * **Blocking**: Configure hooks to prevent commit on failure.
116
+ * **Timeouts**: Configurable timeout execution.
118
117
 
119
- The daemon automatically checks for updates once per day on startup. You'll receive a desktop notification when an update is available.
120
-
121
- **Disable automatic checks:**
122
- ```bash
123
- stint config set autoCheckUpdates false
124
- ```
125
-
126
- **Release Channels:**
127
- - `stable` - Production releases (default)
128
- - `beta` - Pre-release versions for testing
129
-
130
- To publish a beta version:
131
- ```bash
132
- npm publish --tag beta
133
- ```
118
+ Configure these securely in your Project Settings on [stint.codes](https://stint.codes).
134
119
 
135
120
  ## Complete Workflow
136
121
 
@@ -2,10 +2,10 @@ import {
2
2
  gitService,
3
3
  projectService,
4
4
  validatePidFile
5
- } from "./chunk-ABDHDLEJ.js";
5
+ } from "./chunk-TQHWJWBZ.js";
6
6
  import {
7
7
  authService
8
- } from "./chunk-GOS22L3R.js";
8
+ } from "./chunk-7H6J2KCA.js";
9
9
 
10
10
  // src/components/StatusDashboard.tsx
11
11
  import { useState, useEffect } from "react";
@@ -0,0 +1,7 @@
1
+ import {
2
+ apiService
3
+ } from "./chunk-KMYPMLEH.js";
4
+ import "./chunk-7H6J2KCA.js";
5
+ export {
6
+ apiService
7
+ };
@@ -45,9 +45,7 @@ var DEFAULT_CONFIG = {
45
45
  projects: {},
46
46
  notifications: {
47
47
  enabled: true
48
- },
49
- autoCheckUpdates: true,
50
- lastUpdateCheck: null
48
+ }
51
49
  };
52
50
  var ConfigManager = class {
53
51
  conf;
@@ -310,7 +308,7 @@ var AuthServiceImpl = class {
310
308
  return null;
311
309
  }
312
310
  try {
313
- const { apiService } = await import("./api-RQW35VGT.js");
311
+ const { apiService } = await import("./api-U7WJAW3E.js");
314
312
  const user = await apiService.getCurrentUser();
315
313
  logger.info("auth", `Token validated for user: ${user.email}`);
316
314
  return user;
@@ -2,7 +2,7 @@ import {
2
2
  authService,
3
3
  config,
4
4
  logger
5
- } from "./chunk-GOS22L3R.js";
5
+ } from "./chunk-7H6J2KCA.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.20";
101
+ var AGENT_VERSION = "1.2.22";
102
102
  var ApiServiceImpl = class {
103
103
  sessionId = null;
104
104
  circuitBreaker = new CircuitBreaker({
@@ -330,8 +330,9 @@ var ApiServiceImpl = class {
330
330
  * Sync project repository information with the API
331
331
  * @param projectId - Project ID
332
332
  * @param data - Repository information (path, remote URL, branches)
333
+ * @param changedFiles - Optional array of changed files for commit file selection
333
334
  */
334
- async syncProject(projectId, data) {
335
+ async syncProject(projectId, data, changedFiles) {
335
336
  logger.info("api", `Syncing project ${projectId}`);
336
337
  await this.withRetry(async () => {
337
338
  const payload = {
@@ -341,11 +342,14 @@ var ApiServiceImpl = class {
341
342
  current_branch: data.currentBranch,
342
343
  branches: data.branches
343
344
  };
345
+ if (changedFiles && changedFiles.length > 0) {
346
+ payload.changed_files = changedFiles;
347
+ }
344
348
  await this.request(`/api/agent/projects/${projectId}/sync`, {
345
349
  method: "POST",
346
350
  body: JSON.stringify(payload)
347
351
  });
348
- logger.success("api", `Project ${projectId} synced`);
352
+ logger.success("api", `Project ${projectId} synced (${changedFiles?.length ?? 0} changed files)`);
349
353
  }, "Sync project");
350
354
  }
351
355
  /**
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  config,
3
3
  logger
4
- } from "./chunk-GOS22L3R.js";
4
+ } from "./chunk-7H6J2KCA.js";
5
5
 
6
6
  // src/services/git.ts
7
7
  import simpleGit from "simple-git";
@@ -150,6 +150,73 @@ var GitServiceImpl = class {
150
150
  throw new Error(`Failed to get git status: ${error.message}`);
151
151
  }
152
152
  }
153
+ /**
154
+ * Get detailed information about all changed files in the working directory
155
+ * Used for file selection during commit generation in the web app
156
+ * @param path - Repository path
157
+ * @returns Array of changed files with their status and staging state
158
+ */
159
+ async getChangedFiles(path3) {
160
+ try {
161
+ const git = this.getGit(path3);
162
+ const status = await git.status();
163
+ const changedFiles = [];
164
+ for (const file of status.staged) {
165
+ let fileStatus = "modified";
166
+ if (status.created.includes(file)) {
167
+ fileStatus = "added";
168
+ } else if (status.deleted.includes(file)) {
169
+ fileStatus = "deleted";
170
+ } else if (status.renamed.some((r) => r.to === file)) {
171
+ fileStatus = "renamed";
172
+ }
173
+ changedFiles.push({
174
+ path: file,
175
+ status: fileStatus,
176
+ staged: true
177
+ });
178
+ }
179
+ for (const file of status.modified) {
180
+ if (!status.staged.includes(file)) {
181
+ changedFiles.push({
182
+ path: file,
183
+ status: "modified",
184
+ staged: false
185
+ });
186
+ }
187
+ }
188
+ for (const file of status.deleted) {
189
+ if (!status.staged.includes(file)) {
190
+ changedFiles.push({
191
+ path: file,
192
+ status: "deleted",
193
+ staged: false
194
+ });
195
+ }
196
+ }
197
+ for (const file of status.not_added) {
198
+ changedFiles.push({
199
+ path: file,
200
+ status: "untracked",
201
+ staged: false
202
+ });
203
+ }
204
+ for (const renamed of status.renamed) {
205
+ if (!status.staged.includes(renamed.to)) {
206
+ changedFiles.push({
207
+ path: renamed.to,
208
+ status: "renamed",
209
+ staged: false
210
+ });
211
+ }
212
+ }
213
+ logger.info("git", `Found ${changedFiles.length} changed files in ${path3}`);
214
+ return changedFiles;
215
+ } catch (error) {
216
+ logger.error("git", `Failed to get changed files in ${path3}`, error);
217
+ throw new Error(`Failed to get changed files: ${error.message}`);
218
+ }
219
+ }
153
220
  /**
154
221
  * Push commits to remote repository
155
222
  * @param path - Repository path