@gowelle/stint-agent 1.2.43 → 1.2.44

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.
@@ -2,10 +2,10 @@ import {
2
2
  gitService,
3
3
  projectService,
4
4
  validatePidFile
5
- } from "./chunk-IYPRVBYG.js";
5
+ } from "./chunk-4IAVYCEN.js";
6
6
  import {
7
7
  authService
8
- } from "./chunk-H7MANPCF.js";
8
+ } from "./chunk-X2Z4ILIY.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-UBU6PUVO.js";
4
+ import "./chunk-X2Z4ILIY.js";
5
+ export {
6
+ apiService
7
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  config,
3
3
  logger
4
- } from "./chunk-H7MANPCF.js";
4
+ } from "./chunk-X2Z4ILIY.js";
5
5
 
6
6
  // src/services/git.ts
7
7
  import simpleGit from "simple-git";
@@ -1,23 +1,241 @@
1
1
  import {
2
2
  apiService
3
- } from "./chunk-XWCVS4R6.js";
3
+ } from "./chunk-UBU6PUVO.js";
4
4
  import {
5
5
  gitService,
6
6
  projectService
7
- } from "./chunk-IYPRVBYG.js";
7
+ } from "./chunk-4IAVYCEN.js";
8
8
  import {
9
9
  authService,
10
10
  config,
11
11
  logger
12
- } from "./chunk-H7MANPCF.js";
12
+ } from "./chunk-X2Z4ILIY.js";
13
+
14
+ // src/services/package-detector.ts
15
+ import fs from "fs";
16
+ import path from "path";
17
+ var PackageDetectorService = class {
18
+ /**
19
+ * Detect all package types in a project directory
20
+ */
21
+ async detectAll(projectPath) {
22
+ const packages = [];
23
+ try {
24
+ const npmInfo = await this.detectNpm(projectPath);
25
+ if (npmInfo) packages.push(npmInfo);
26
+ const composerInfo = await this.detectComposer(projectPath);
27
+ if (composerInfo) packages.push(composerInfo);
28
+ const cargoInfo = await this.detectCargo(projectPath);
29
+ if (cargoInfo) packages.push(cargoInfo);
30
+ const pipInfo = await this.detectPip(projectPath);
31
+ if (pipInfo) packages.push(pipInfo);
32
+ const goInfo = await this.detectGo(projectPath);
33
+ if (goInfo) packages.push(goInfo);
34
+ const gemInfo = await this.detectGem(projectPath);
35
+ if (gemInfo) packages.push(gemInfo);
36
+ if (packages.length > 0) {
37
+ logger.info(
38
+ "package-detector",
39
+ `Detected ${packages.length} package type(s): ${packages.map((p) => p.type).join(", ")}`
40
+ );
41
+ }
42
+ return packages;
43
+ } catch (error) {
44
+ logger.error(
45
+ "package-detector",
46
+ "Error detecting packages",
47
+ error
48
+ );
49
+ return packages;
50
+ }
51
+ }
52
+ /**
53
+ * Detect npm package (package.json)
54
+ */
55
+ async detectNpm(projectPath) {
56
+ const manifestPath = path.join(projectPath, "package.json");
57
+ if (!fs.existsSync(manifestPath)) {
58
+ return null;
59
+ }
60
+ try {
61
+ const content = fs.readFileSync(manifestPath, "utf8");
62
+ const pkg = JSON.parse(content);
63
+ const scripts = pkg.scripts ? Object.keys(pkg.scripts) : [];
64
+ return {
65
+ type: "npm",
66
+ name: pkg.name || "unknown",
67
+ version: pkg.version || "0.0.0",
68
+ manifestPath,
69
+ scripts,
70
+ hasPublishConfig: !!pkg.publishConfig
71
+ };
72
+ } catch (error) {
73
+ logger.debug(
74
+ "package-detector",
75
+ `Failed to parse package.json: ${error.message}`
76
+ );
77
+ return null;
78
+ }
79
+ }
80
+ /**
81
+ * Detect composer package (composer.json)
82
+ */
83
+ async detectComposer(projectPath) {
84
+ const manifestPath = path.join(projectPath, "composer.json");
85
+ if (!fs.existsSync(manifestPath)) {
86
+ return null;
87
+ }
88
+ try {
89
+ const content = fs.readFileSync(manifestPath, "utf8");
90
+ const pkg = JSON.parse(content);
91
+ return {
92
+ type: "composer",
93
+ name: pkg.name || "unknown",
94
+ version: pkg.version || "0.0.0",
95
+ manifestPath
96
+ };
97
+ } catch (error) {
98
+ logger.debug(
99
+ "package-detector",
100
+ `Failed to parse composer.json: ${error.message}`
101
+ );
102
+ return null;
103
+ }
104
+ }
105
+ /**
106
+ * Detect cargo package (Cargo.toml)
107
+ */
108
+ async detectCargo(projectPath) {
109
+ const manifestPath = path.join(projectPath, "Cargo.toml");
110
+ if (!fs.existsSync(manifestPath)) {
111
+ return null;
112
+ }
113
+ try {
114
+ const content = fs.readFileSync(manifestPath, "utf8");
115
+ const nameMatch = content.match(/^\s*name\s*=\s*["']([^"']+)["']/m);
116
+ const versionMatch = content.match(/^\s*version\s*=\s*["']([^"']+)["']/m);
117
+ return {
118
+ type: "cargo",
119
+ name: nameMatch ? nameMatch[1] : "unknown",
120
+ version: versionMatch ? versionMatch[1] : "0.0.0",
121
+ manifestPath
122
+ };
123
+ } catch (error) {
124
+ logger.debug(
125
+ "package-detector",
126
+ `Failed to parse Cargo.toml: ${error.message}`
127
+ );
128
+ return null;
129
+ }
130
+ }
131
+ /**
132
+ * Detect pip package (pyproject.toml or setup.py)
133
+ */
134
+ async detectPip(projectPath) {
135
+ const pyprojectPath = path.join(projectPath, "pyproject.toml");
136
+ if (fs.existsSync(pyprojectPath)) {
137
+ try {
138
+ const content = fs.readFileSync(pyprojectPath, "utf8");
139
+ const nameMatch = content.match(
140
+ /\[project\][\s\S]*?name\s*=\s*["']([^"']+)["']/
141
+ );
142
+ const versionMatch = content.match(
143
+ /\[project\][\s\S]*?version\s*=\s*["']([^"']+)["']/
144
+ );
145
+ const poetryNameMatch = content.match(
146
+ /\[tool\.poetry\][\s\S]*?name\s*=\s*["']([^"']+)["']/
147
+ );
148
+ const poetryVersionMatch = content.match(
149
+ /\[tool\.poetry\][\s\S]*?version\s*=\s*["']([^"']+)["']/
150
+ );
151
+ return {
152
+ type: "pip",
153
+ name: nameMatch?.[1] || poetryNameMatch?.[1] || "unknown",
154
+ version: versionMatch?.[1] || poetryVersionMatch?.[1] || "0.0.0",
155
+ manifestPath: pyprojectPath
156
+ };
157
+ } catch (error) {
158
+ logger.debug(
159
+ "package-detector",
160
+ `Failed to parse pyproject.toml: ${error.message}`
161
+ );
162
+ }
163
+ }
164
+ const setupPyPath = path.join(projectPath, "setup.py");
165
+ if (fs.existsSync(setupPyPath)) {
166
+ return {
167
+ type: "pip",
168
+ name: "unknown",
169
+ version: "0.0.0",
170
+ manifestPath: setupPyPath
171
+ };
172
+ }
173
+ return null;
174
+ }
175
+ /**
176
+ * Detect go module (go.mod)
177
+ */
178
+ async detectGo(projectPath) {
179
+ const manifestPath = path.join(projectPath, "go.mod");
180
+ if (!fs.existsSync(manifestPath)) {
181
+ return null;
182
+ }
183
+ try {
184
+ const content = fs.readFileSync(manifestPath, "utf8");
185
+ const moduleMatch = content.match(/^module\s+(\S+)/m);
186
+ return {
187
+ type: "go",
188
+ name: moduleMatch ? moduleMatch[1] : "unknown",
189
+ version: "0.0.0",
190
+ // Go modules use git tags for versioning
191
+ manifestPath
192
+ };
193
+ } catch (error) {
194
+ logger.debug(
195
+ "package-detector",
196
+ `Failed to parse go.mod: ${error.message}`
197
+ );
198
+ return null;
199
+ }
200
+ }
201
+ /**
202
+ * Detect gem package (*.gemspec)
203
+ */
204
+ async detectGem(projectPath) {
205
+ try {
206
+ const files = fs.readdirSync(projectPath);
207
+ const gemspecFile = files.find((f) => f.endsWith(".gemspec"));
208
+ if (!gemspecFile) {
209
+ return null;
210
+ }
211
+ const manifestPath = path.join(projectPath, gemspecFile);
212
+ const content = fs.readFileSync(manifestPath, "utf8");
213
+ const nameMatch = content.match(/\.name\s*=\s*["']([^"']+)["']/);
214
+ const versionMatch = content.match(/\.version\s*=\s*["']([^"']+)["']/);
215
+ return {
216
+ type: "gem",
217
+ name: nameMatch ? nameMatch[1] : gemspecFile.replace(".gemspec", ""),
218
+ version: versionMatch ? versionMatch[1] : "0.0.0",
219
+ manifestPath
220
+ };
221
+ } catch (error) {
222
+ logger.debug(
223
+ "package-detector",
224
+ `Failed to detect gemspec: ${error.message}`
225
+ );
226
+ return null;
227
+ }
228
+ }
229
+ };
230
+ var packageDetector = new PackageDetectorService();
13
231
 
14
232
  // src/utils/notify.ts
15
233
  import notifier from "node-notifier";
16
- import path from "path";
234
+ import path2 from "path";
17
235
  import { fileURLToPath } from "url";
18
236
  var __filename = fileURLToPath(import.meta.url);
19
- var __dirname = path.dirname(__filename);
20
- var DEFAULT_ICON = path.resolve(__dirname, "../assets/logo.png");
237
+ var __dirname = path2.dirname(__filename);
238
+ var DEFAULT_ICON = path2.resolve(__dirname, "../assets/logo.png");
21
239
  function notify(options) {
22
240
  if (!config.areNotificationsEnabled()) {
23
241
  logger.debug("notify", "Notifications disabled, skipping notification");
@@ -587,9 +805,9 @@ Run "git pull --rebase" to resolve.`,
587
805
  */
588
806
  findProjectPath(projectId) {
589
807
  const allProjects = projectService.getAllLinkedProjects();
590
- for (const [path3, linkedProject] of Object.entries(allProjects)) {
808
+ for (const [path4, linkedProject] of Object.entries(allProjects)) {
591
809
  if (linkedProject.projectId === projectId) {
592
- return path3;
810
+ return path4;
593
811
  }
594
812
  }
595
813
  return null;
@@ -612,10 +830,10 @@ var commitQueue = new CommitQueueProcessor();
612
830
  // src/services/websocket.ts
613
831
  import Echo from "laravel-echo";
614
832
  import Pusher from "pusher-js";
615
- import fs from "fs";
833
+ import fs2 from "fs";
616
834
  import os from "os";
617
- import path2 from "path";
618
- var STATUS_FILE_PATH = path2.join(
835
+ import path3 from "path";
836
+ var STATUS_FILE_PATH = path3.join(
619
837
  os.homedir(),
620
838
  ".config",
621
839
  "stint",
@@ -623,19 +841,19 @@ var STATUS_FILE_PATH = path2.join(
623
841
  );
624
842
  function writeStatus(update) {
625
843
  try {
626
- const dir = path2.dirname(STATUS_FILE_PATH);
627
- if (!fs.existsSync(dir)) {
628
- fs.mkdirSync(dir, { recursive: true });
844
+ const dir = path3.dirname(STATUS_FILE_PATH);
845
+ if (!fs2.existsSync(dir)) {
846
+ fs2.mkdirSync(dir, { recursive: true });
629
847
  }
630
848
  let status = { websocket: { connected: false } };
631
- if (fs.existsSync(STATUS_FILE_PATH)) {
849
+ if (fs2.existsSync(STATUS_FILE_PATH)) {
632
850
  try {
633
- status = JSON.parse(fs.readFileSync(STATUS_FILE_PATH, "utf8"));
851
+ status = JSON.parse(fs2.readFileSync(STATUS_FILE_PATH, "utf8"));
634
852
  } catch {
635
853
  }
636
854
  }
637
855
  status.websocket = { ...status.websocket, ...update };
638
- fs.writeFileSync(STATUS_FILE_PATH, JSON.stringify(status, null, 2));
856
+ fs2.writeFileSync(STATUS_FILE_PATH, JSON.stringify(status, null, 2));
639
857
  } catch {
640
858
  }
641
859
  }
@@ -941,7 +1159,7 @@ var WebSocketServiceImpl = class {
941
1159
  "websocket",
942
1160
  `Commit ${commit.id} marked as large, fetching full details...`
943
1161
  );
944
- const { apiService: apiService2 } = await import("./api-7EO4NO7A.js");
1162
+ const { apiService: apiService2 } = await import("./api-A5W4VYEH.js");
945
1163
  const fullCommit = await apiService2.getCommit(commit.id);
946
1164
  commit = {
947
1165
  ...commit,
@@ -1147,6 +1365,7 @@ var WebSocketServiceImpl = class {
1147
1365
  var websocketService = new WebSocketServiceImpl();
1148
1366
 
1149
1367
  export {
1368
+ packageDetector,
1150
1369
  notify,
1151
1370
  commitQueue,
1152
1371
  websocketService
@@ -2,7 +2,7 @@ import {
2
2
  authService,
3
3
  config,
4
4
  logger
5
- } from "./chunk-H7MANPCF.js";
5
+ } from "./chunk-X2Z4ILIY.js";
6
6
 
7
7
  // src/utils/circuit-breaker.ts
8
8
  var CircuitBreaker = class {
@@ -100,7 +100,7 @@ var CircuitBreaker = class {
100
100
  };
101
101
 
102
102
  // src/services/api.ts
103
- var AGENT_VERSION = "1.2.43";
103
+ var AGENT_VERSION = "1.2.44";
104
104
  var ApiServiceImpl = class {
105
105
  sessionId = null;
106
106
  circuitBreaker = new CircuitBreaker({
@@ -411,8 +411,9 @@ var ApiServiceImpl = class {
411
411
  * @param projectId - Project ID
412
412
  * @param data - Repository information (path, remote URL, branches)
413
413
  * @param changedFiles - Optional array of changed files for commit file selection
414
+ * @param packageInfo - Optional array of detected package types
414
415
  */
415
- async syncProject(projectId, data, changedFiles) {
416
+ async syncProject(projectId, data, changedFiles, packageInfo) {
416
417
  logger.info("api", `Syncing project ${projectId}`);
417
418
  return this.withRetry(async () => {
418
419
  const payload = {
@@ -425,13 +426,17 @@ var ApiServiceImpl = class {
425
426
  if (changedFiles && changedFiles.length > 0) {
426
427
  payload.changed_files = changedFiles;
427
428
  }
429
+ if (packageInfo && packageInfo.length > 0) {
430
+ payload.package_info = packageInfo;
431
+ }
428
432
  const response = await this.request(`/api/agent/projects/${projectId}/sync`, {
429
433
  method: "POST",
430
434
  body: JSON.stringify(payload)
431
435
  });
436
+ const packageTypes = packageInfo?.map((p) => p.type).join(", ") || "none";
432
437
  logger.success(
433
438
  "api",
434
- `Project ${projectId} synced (${changedFiles?.length ?? 0} changed files)`
439
+ `Project ${projectId} synced (${changedFiles?.length ?? 0} files, packages: ${packageTypes})`
435
440
  );
436
441
  return {
437
442
  auto_sync: response.auto_sync
@@ -346,7 +346,7 @@ var AuthServiceImpl = class {
346
346
  return null;
347
347
  }
348
348
  try {
349
- const { apiService } = await import("./api-7EO4NO7A.js");
349
+ const { apiService } = await import("./api-A5W4VYEH.js");
350
350
  const user = await apiService.getCurrentUser();
351
351
  logger.info("auth", `Token validated for user: ${user.email}`);
352
352
  return user;
@@ -2,21 +2,22 @@
2
2
  import {
3
3
  commitQueue,
4
4
  notify,
5
+ packageDetector,
5
6
  websocketService
6
- } from "../chunk-KGDXQOLB.js";
7
+ } from "../chunk-7B4YYEBR.js";
7
8
  import {
8
9
  apiService
9
- } from "../chunk-XWCVS4R6.js";
10
+ } from "../chunk-UBU6PUVO.js";
10
11
  import {
11
12
  gitService,
12
13
  projectService,
13
14
  removePidFile,
14
15
  writePidFile
15
- } from "../chunk-IYPRVBYG.js";
16
+ } from "../chunk-4IAVYCEN.js";
16
17
  import {
17
18
  authService,
18
19
  logger
19
- } from "../chunk-H7MANPCF.js";
20
+ } from "../chunk-X2Z4ILIY.js";
20
21
 
21
22
  // src/daemon/runner.ts
22
23
  import "dotenv/config";
@@ -190,10 +191,12 @@ var FileWatcher = class {
190
191
  }
191
192
  const repoInfo = await gitService.getRepoInfo(projectPath);
192
193
  const changedFiles = await gitService.getChangedFiles(projectPath);
194
+ const packageInfo = await packageDetector.detectAll(projectPath);
193
195
  const response = await apiService.syncProject(
194
196
  projectId,
195
197
  repoInfo,
196
- changedFiles
198
+ changedFiles,
199
+ packageInfo
197
200
  );
198
201
  if (response.auto_sync) {
199
202
  this.updateProjectSettings(projectId, response.auto_sync);
package/dist/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  commitQueue,
4
+ packageDetector,
4
5
  websocketService
5
- } from "./chunk-KGDXQOLB.js";
6
+ } from "./chunk-7B4YYEBR.js";
6
7
  import {
7
8
  apiService
8
- } from "./chunk-XWCVS4R6.js";
9
+ } from "./chunk-UBU6PUVO.js";
9
10
  import {
10
11
  getPidFilePath,
11
12
  gitService,
@@ -14,14 +15,14 @@ import {
14
15
  projectService,
15
16
  spawnDetached,
16
17
  validatePidFile
17
- } from "./chunk-IYPRVBYG.js";
18
+ } from "./chunk-4IAVYCEN.js";
18
19
  import {
19
20
  __commonJS,
20
21
  __toESM,
21
22
  authService,
22
23
  config,
23
24
  logger
24
- } from "./chunk-H7MANPCF.js";
25
+ } from "./chunk-X2Z4ILIY.js";
25
26
 
26
27
  // node_modules/semver/internal/constants.js
27
28
  var require_constants = __commonJS({
@@ -2657,7 +2658,7 @@ function registerStatusCommand(program2) {
2657
2658
  try {
2658
2659
  const { render } = await import("ink");
2659
2660
  const { createElement } = await import("react");
2660
- const { StatusDashboard } = await import("./StatusDashboard-QOFG2BEM.js");
2661
+ const { StatusDashboard } = await import("./StatusDashboard-LG4VC32Y.js");
2661
2662
  render(createElement(StatusDashboard, { cwd }));
2662
2663
  return;
2663
2664
  } catch (error) {
@@ -2883,13 +2884,16 @@ function registerSyncCommand(program2) {
2883
2884
  const repoInfo = await gitService.getRepoInfo(cwd);
2884
2885
  spinner.text = "Getting changed files...";
2885
2886
  const changedFiles = await gitService.getChangedFiles(cwd);
2887
+ spinner.text = "Detecting package types...";
2888
+ const packageInfo = await packageDetector.detectAll(cwd);
2886
2889
  spinner.text = "Preparing sync payload...";
2887
2890
  const syncSpinner = ora7("Connecting to server...").start();
2888
2891
  try {
2889
2892
  await apiService.syncProject(
2890
2893
  linkedProject.projectId,
2891
2894
  repoInfo,
2892
- changedFiles
2895
+ changedFiles,
2896
+ packageInfo
2893
2897
  );
2894
2898
  syncSpinner.succeed("Server sync completed");
2895
2899
  } catch (error) {
@@ -2904,6 +2908,10 @@ function registerSyncCommand(program2) {
2904
2908
  console.log(
2905
2909
  `${chalk7.bold("Changed:")} ${changedFiles.length} files synced for commit selection`
2906
2910
  );
2911
+ if (packageInfo.length > 0) {
2912
+ const pkgTypes = packageInfo.map((p) => `${p.type} (${p.name}@${p.version})`).join(", ");
2913
+ console.log(`${chalk7.bold("Packages:")} ${pkgTypes}`);
2914
+ }
2907
2915
  console.log(`${chalk7.bold("Project ID:")} ${linkedProject.projectId}`);
2908
2916
  console.log(`${chalk7.bold("Branch:")} ${repoInfo.currentBranch}`);
2909
2917
  console.log(
@@ -4928,7 +4936,7 @@ Tasks for project ${chalk15.cyan(linkedProject.projectId)}`
4928
4936
  });
4929
4937
 
4930
4938
  // src/index.ts
4931
- var AGENT_VERSION = "1.2.43";
4939
+ var AGENT_VERSION = "1.2.44";
4932
4940
  var program = new Command2();
4933
4941
  program.name("stint").description("Stint Agent - Local daemon for Stint Project Assistant").version(AGENT_VERSION, "-v, --version", "output the current version").addHelpText(
4934
4942
  "after",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gowelle/stint-agent",
3
- "version": "1.2.43",
3
+ "version": "1.2.44",
4
4
  "description": "Local agent for Stint - Project Assistant",
5
5
  "author": "Gowelle John <gowelle.john@icloud.com>",
6
6
  "license": "MIT",
@@ -1,7 +0,0 @@
1
- import {
2
- apiService
3
- } from "./chunk-XWCVS4R6.js";
4
- import "./chunk-H7MANPCF.js";
5
- export {
6
- apiService
7
- };