@gowelle/stint-agent 1.2.48 → 1.2.49

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-DO2UM4KG.js";
5
+ } from "./chunk-NNK7GJL4.js";
6
6
  import {
7
7
  authService
8
- } from "./chunk-FX5SUMJG.js";
8
+ } from "./chunk-3JSOITUS.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-NUYTAWHX.js";
4
+ import "./chunk-3JSOITUS.js";
5
+ export {
6
+ apiService
7
+ };
@@ -358,7 +358,7 @@ var AuthServiceImpl = class {
358
358
  return null;
359
359
  }
360
360
  try {
361
- const { apiService } = await import("./api-5NWCQKIO.js");
361
+ const { apiService } = await import("./api-XHW54OCY.js");
362
362
  const user = await apiService.getCurrentUser();
363
363
  logger.info("auth", `Token validated for user: ${user.email}`);
364
364
  return user;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  config,
3
3
  logger
4
- } from "./chunk-FX5SUMJG.js";
4
+ } from "./chunk-3JSOITUS.js";
5
5
 
6
6
  // src/services/git.ts
7
7
  import simpleGit from "simple-git";
@@ -2,7 +2,7 @@ import {
2
2
  authService,
3
3
  config,
4
4
  logger
5
- } from "./chunk-FX5SUMJG.js";
5
+ } from "./chunk-3JSOITUS.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.48";
103
+ var AGENT_VERSION = "1.2.49";
104
104
  var ApiServiceImpl = class {
105
105
  sessionId = null;
106
106
  circuitBreaker = new CircuitBreaker({
@@ -143,20 +143,24 @@ var ApiServiceImpl = class {
143
143
  * Make an HTTP request to the API with circuit breaker protection
144
144
  * @param endpoint - API endpoint path (e.g., '/api/user')
145
145
  * @param options - Fetch options (method, body, headers, etc.)
146
+ * @param timeoutMs - Request timeout in milliseconds (default: 30000)
146
147
  * @returns Parsed JSON response
147
- * @throws Error if request fails or circuit breaker is open
148
+ * @throws Error if request fails, times out, or circuit breaker is open
148
149
  */
149
- async request(endpoint, options = {}) {
150
+ async request(endpoint, options = {}, timeoutMs = 3e4) {
150
151
  const url = `${config.getApiUrl()}${endpoint}`;
151
152
  const headers = await this.getHeaders();
152
153
  return this.circuitBreaker.execute(async () => {
154
+ const controller = new AbortController();
155
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
153
156
  try {
154
157
  const response = await fetch(url, {
155
158
  ...options,
156
159
  headers: {
157
160
  ...headers,
158
161
  ...options.headers
159
- }
162
+ },
163
+ signal: controller.signal
160
164
  });
161
165
  if (!response.ok) {
162
166
  const errorText = await response.text();
@@ -166,8 +170,13 @@ var ApiServiceImpl = class {
166
170
  }
167
171
  return await response.json();
168
172
  } catch (error) {
173
+ if (error.name === "AbortError") {
174
+ throw new Error(`Request to ${endpoint} timed out after ${timeoutMs}ms`);
175
+ }
169
176
  logger.error("api", `Request to ${endpoint} failed`, error);
170
177
  throw error;
178
+ } finally {
179
+ clearTimeout(timeoutId);
171
180
  }
172
181
  });
173
182
  }
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  apiService
3
- } from "./chunk-GFOTV2EU.js";
3
+ } from "./chunk-NUYTAWHX.js";
4
4
  import {
5
5
  gitService,
6
6
  projectService
7
- } from "./chunk-DO2UM4KG.js";
7
+ } from "./chunk-NNK7GJL4.js";
8
8
  import {
9
9
  authService,
10
10
  config,
11
11
  logger
12
- } from "./chunk-FX5SUMJG.js";
12
+ } from "./chunk-3JSOITUS.js";
13
13
 
14
14
  // src/services/package-detector.ts
15
15
  import fs from "fs";
@@ -1429,7 +1429,7 @@ var WebSocketServiceImpl = class {
1429
1429
  "websocket",
1430
1430
  `Commit ${commit.id} marked as large, fetching full details...`
1431
1431
  );
1432
- const { apiService: apiService2 } = await import("./api-5NWCQKIO.js");
1432
+ const { apiService: apiService2 } = await import("./api-XHW54OCY.js");
1433
1433
  const fullCommit = await apiService2.getCommit(commit.id);
1434
1434
  commit = {
1435
1435
  ...commit,
@@ -4,20 +4,20 @@ import {
4
4
  notify,
5
5
  packageDetector,
6
6
  websocketService
7
- } from "../chunk-BXL4FWJP.js";
7
+ } from "../chunk-RBG4PQQH.js";
8
8
  import {
9
9
  apiService
10
- } from "../chunk-GFOTV2EU.js";
10
+ } from "../chunk-NUYTAWHX.js";
11
11
  import {
12
12
  gitService,
13
13
  projectService,
14
14
  removePidFile,
15
15
  writePidFile
16
- } from "../chunk-DO2UM4KG.js";
16
+ } from "../chunk-NNK7GJL4.js";
17
17
  import {
18
18
  authService,
19
19
  logger
20
- } from "../chunk-FX5SUMJG.js";
20
+ } from "../chunk-3JSOITUS.js";
21
21
 
22
22
  // src/daemon/runner.ts
23
23
  import "dotenv/config";
package/dist/index.js CHANGED
@@ -3,10 +3,10 @@ import {
3
3
  commitQueue,
4
4
  packageDetector,
5
5
  websocketService
6
- } from "./chunk-BXL4FWJP.js";
6
+ } from "./chunk-RBG4PQQH.js";
7
7
  import {
8
8
  apiService
9
- } from "./chunk-GFOTV2EU.js";
9
+ } from "./chunk-NUYTAWHX.js";
10
10
  import {
11
11
  getPidFilePath,
12
12
  gitService,
@@ -15,14 +15,14 @@ import {
15
15
  projectService,
16
16
  spawnDetached,
17
17
  validatePidFile
18
- } from "./chunk-DO2UM4KG.js";
18
+ } from "./chunk-NNK7GJL4.js";
19
19
  import {
20
20
  __commonJS,
21
21
  __toESM,
22
22
  authService,
23
23
  config,
24
24
  logger
25
- } from "./chunk-FX5SUMJG.js";
25
+ } from "./chunk-3JSOITUS.js";
26
26
 
27
27
  // node_modules/semver/internal/constants.js
28
28
  var require_constants = __commonJS({
@@ -1956,8 +1956,8 @@ var require_semver2 = __commonJS({
1956
1956
 
1957
1957
  // src/index.ts
1958
1958
  import "dotenv/config";
1959
- import { Command as Command2 } from "commander";
1960
- import chalk16 from "chalk";
1959
+ import { Command as Command3 } from "commander";
1960
+ import chalk17 from "chalk";
1961
1961
 
1962
1962
  // src/commands/login.ts
1963
1963
  import open from "open";
@@ -2658,7 +2658,7 @@ function registerStatusCommand(program2) {
2658
2658
  try {
2659
2659
  const { render } = await import("ink");
2660
2660
  const { createElement } = await import("react");
2661
- const { StatusDashboard } = await import("./StatusDashboard-EEY7KFZW.js");
2661
+ const { StatusDashboard } = await import("./StatusDashboard-SV67LHN2.js");
2662
2662
  render(createElement(StatusDashboard, { cwd }));
2663
2663
  return;
2664
2664
  } catch (error) {
@@ -2892,8 +2892,7 @@ function registerSyncCommand(program2) {
2892
2892
  );
2893
2893
  spinner.text = "Scanning file tree...";
2894
2894
  const fileTree = await gitService.getFileTree(cwd);
2895
- spinner.text = "Preparing sync payload...";
2896
- const syncSpinner = ora7("Connecting to server...").start();
2895
+ spinner.text = "Syncing with server...";
2897
2896
  try {
2898
2897
  await apiService.syncProject(
2899
2898
  linkedProject.projectId,
@@ -2902,9 +2901,9 @@ function registerSyncCommand(program2) {
2902
2901
  packageInfo,
2903
2902
  fileTree
2904
2903
  );
2905
- syncSpinner.succeed("Server sync completed");
2904
+ spinner.succeed("Sync completed");
2906
2905
  } catch (error) {
2907
- syncSpinner.fail("Server sync failed");
2906
+ spinner.fail("Server sync failed");
2908
2907
  throw error;
2909
2908
  }
2910
2909
  console.log(chalk7.green("\n\u2713 Repository sync completed"));
@@ -4945,22 +4944,134 @@ Tasks for project ${chalk15.cyan(linkedProject.projectId)}`
4945
4944
  }
4946
4945
  });
4947
4946
 
4947
+ // src/commands/projects.ts
4948
+ import { Command as Command2 } from "commander";
4949
+ import chalk16 from "chalk";
4950
+ import ora15 from "ora";
4951
+ var projectsCommand = new Command2("projects").description("List all linked projects").option("-r, --remote", "Fetch additional project details from server").action(async (options) => {
4952
+ try {
4953
+ const linkedProjects = projectService.getAllLinkedProjects();
4954
+ const entries = Object.entries(linkedProjects);
4955
+ if (entries.length === 0) {
4956
+ console.log(chalk16.gray("No projects linked."));
4957
+ console.log(
4958
+ chalk16.gray(
4959
+ "Run 'stint link' in a git repository to link it to a project."
4960
+ )
4961
+ );
4962
+ return;
4963
+ }
4964
+ console.log(chalk16.bold(`
4965
+ \u{1F4C2} Linked Projects (${entries.length})
4966
+ `));
4967
+ if (options.remote) {
4968
+ const spinner = ora15("Fetching project details from server...").start();
4969
+ const token = await authService.getToken();
4970
+ if (!token) {
4971
+ spinner.fail("Not authenticated");
4972
+ console.log(
4973
+ chalk16.yellow("Run 'stint login' to authenticate first.")
4974
+ );
4975
+ return;
4976
+ }
4977
+ try {
4978
+ const remoteProjects = await apiService.getLinkedProjects();
4979
+ spinner.stop();
4980
+ const remoteMap = new Map(
4981
+ remoteProjects.map((p) => [p.id, p])
4982
+ );
4983
+ entries.forEach(([path7, linked]) => {
4984
+ const remote = remoteMap.get(linked.projectId);
4985
+ if (remote) {
4986
+ console.log(
4987
+ `${chalk16.green("\u25CF")} ${chalk16.white.bold(remote.name)} ${chalk16.gray(`(${remote.id})`)}`
4988
+ );
4989
+ if (remote.description) {
4990
+ console.log(` ${chalk16.gray(remote.description)}`);
4991
+ }
4992
+ console.log(
4993
+ ` ${chalk16.gray("Path:")} ${chalk16.cyan(path7)}`
4994
+ );
4995
+ if (remote.default_branch) {
4996
+ console.log(
4997
+ ` ${chalk16.gray("Branch:")} ${chalk16.blue(remote.default_branch)}`
4998
+ );
4999
+ }
5000
+ console.log(
5001
+ ` ${chalk16.gray("Linked:")} ${chalk16.gray(new Date(linked.linkedAt).toLocaleDateString())}`
5002
+ );
5003
+ } else {
5004
+ console.log(
5005
+ `${chalk16.yellow("\u25CB")} ${chalk16.gray("Unknown Project")} ${chalk16.gray(`(${linked.projectId})`)}`
5006
+ );
5007
+ console.log(
5008
+ ` ${chalk16.gray("Path:")} ${chalk16.cyan(path7)}`
5009
+ );
5010
+ console.log(
5011
+ ` ${chalk16.gray("Linked:")} ${chalk16.gray(new Date(linked.linkedAt).toLocaleDateString())}`
5012
+ );
5013
+ console.log(
5014
+ ` ${chalk16.yellow("\u26A0 Project not found on server. May have been deleted.")}`
5015
+ );
5016
+ }
5017
+ console.log("");
5018
+ });
5019
+ const synced = entries.filter(
5020
+ ([, l]) => remoteMap.has(l.projectId)
5021
+ ).length;
5022
+ console.log(
5023
+ chalk16.gray(
5024
+ `${synced}/${entries.length} projects synced with server`
5025
+ )
5026
+ );
5027
+ } catch (error) {
5028
+ spinner.fail("Failed to fetch remote projects");
5029
+ logger.error(
5030
+ "cli",
5031
+ "Failed to fetch remote projects",
5032
+ error
5033
+ );
5034
+ console.log(chalk16.yellow("\nShowing local data only:"));
5035
+ displayLocalProjects(entries);
5036
+ }
5037
+ } else {
5038
+ displayLocalProjects(entries);
5039
+ }
5040
+ } catch (error) {
5041
+ logger.error("cli", "Failed to list projects", error);
5042
+ process.exit(1);
5043
+ }
5044
+ });
5045
+ function displayLocalProjects(entries) {
5046
+ entries.forEach(([path7, linked]) => {
5047
+ console.log(
5048
+ `${chalk16.green("\u25CF")} ${chalk16.white.bold(linked.projectId)}`
5049
+ );
5050
+ console.log(` ${chalk16.gray("Path:")} ${chalk16.cyan(path7)}`);
5051
+ console.log(
5052
+ ` ${chalk16.gray("Linked:")} ${chalk16.gray(new Date(linked.linkedAt).toLocaleDateString())}`
5053
+ );
5054
+ console.log("");
5055
+ });
5056
+ console.log(chalk16.gray("Tip: Use 'stint projects --remote' for more details"));
5057
+ }
5058
+
4948
5059
  // src/index.ts
4949
- var AGENT_VERSION = "1.2.48";
4950
- var program = new Command2();
5060
+ var AGENT_VERSION = "1.2.49";
5061
+ var program = new Command3();
4951
5062
  program.name("stint").description("Stint Agent - Local daemon for Stint Project Assistant").version(AGENT_VERSION, "-v, --version", "output the current version").addHelpText(
4952
5063
  "after",
4953
5064
  `
4954
- ${chalk16.bold("Examples:")}
4955
- ${chalk16.cyan("$")} stint login ${chalk16.gray("# Authenticate with Stint")}
4956
- ${chalk16.cyan("$")} stint install ${chalk16.gray("# Install agent to run on startup")}
4957
- ${chalk16.cyan("$")} stint link ${chalk16.gray("# Link current directory to a project")}
4958
- ${chalk16.cyan("$")} stint daemon start ${chalk16.gray("# Start background daemon")}
4959
- ${chalk16.cyan("$")} stint status ${chalk16.gray("# Check status")}
4960
- ${chalk16.cyan("$")} stint commits ${chalk16.gray("# List pending commits")}
5065
+ ${chalk17.bold("Examples:")}
5066
+ ${chalk17.cyan("$")} stint login ${chalk17.gray("# Authenticate with Stint")}
5067
+ ${chalk17.cyan("$")} stint install ${chalk17.gray("# Install agent to run on startup")}
5068
+ ${chalk17.cyan("$")} stint link ${chalk17.gray("# Link current directory to a project")}
5069
+ ${chalk17.cyan("$")} stint daemon start ${chalk17.gray("# Start background daemon")}
5070
+ ${chalk17.cyan("$")} stint status ${chalk17.gray("# Check status")}
5071
+ ${chalk17.cyan("$")} stint commits ${chalk17.gray("# List pending commits")}
4961
5072
 
4962
- ${chalk16.bold("Documentation:")}
4963
- For more information, visit: ${chalk16.blue("https://stint.codes/docs")}
5073
+ ${chalk17.bold("Documentation:")}
5074
+ For more information, visit: ${chalk17.blue("https://stint.codes/docs")}
4964
5075
  `
4965
5076
  );
4966
5077
  registerLoginCommand(program);
@@ -4978,6 +5089,7 @@ registerUpdateCommand(program);
4978
5089
  registerDoctorCommand(program);
4979
5090
  registerConfigCommand(program);
4980
5091
  program.addCommand(tasksCommand);
5092
+ program.addCommand(projectsCommand);
4981
5093
  program.exitOverride();
4982
5094
  try {
4983
5095
  await program.parseAsync(process.argv);
@@ -4985,7 +5097,7 @@ try {
4985
5097
  const commanderError = error;
4986
5098
  if (commanderError.code !== "commander.help" && commanderError.code !== "commander.version" && commanderError.code !== "commander.helpDisplayed") {
4987
5099
  logger.error("cli", "Command execution failed", error);
4988
- console.error(chalk16.red(`
5100
+ console.error(chalk17.red(`
4989
5101
  \u2716 Error: ${error.message}
4990
5102
  `));
4991
5103
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gowelle/stint-agent",
3
- "version": "1.2.48",
3
+ "version": "1.2.49",
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-GFOTV2EU.js";
4
- import "./chunk-FX5SUMJG.js";
5
- export {
6
- apiService
7
- };