@gowelle/stint-agent 1.2.35 → 1.2.36

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/index.js CHANGED
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  commitQueue,
4
4
  websocketService
5
- } from "./chunk-MISINEGG.js";
5
+ } from "./chunk-BYBGWAQO.js";
6
6
  import {
7
7
  apiService
8
- } from "./chunk-H5GHDNXY.js";
8
+ } from "./chunk-VE7Z43P7.js";
9
9
  import {
10
10
  getPidFilePath,
11
11
  gitService,
@@ -14,14 +14,14 @@ import {
14
14
  projectService,
15
15
  spawnDetached,
16
16
  validatePidFile
17
- } from "./chunk-4655SBXG.js";
17
+ } from "./chunk-KHLFCZRY.js";
18
18
  import {
19
19
  __commonJS,
20
20
  __toESM,
21
21
  authService,
22
22
  config,
23
23
  logger
24
- } from "./chunk-RC7Z6GTK.js";
24
+ } from "./chunk-E3WNZ2CK.js";
25
25
 
26
26
  // node_modules/semver/internal/constants.js
27
27
  var require_constants = __commonJS({
@@ -1983,7 +1983,10 @@ function startCallbackServer(expectedState, timeoutMs = 5 * 60 * 1e3) {
1983
1983
  server.on("request", (req, res) => {
1984
1984
  res.setHeader("Access-Control-Allow-Origin", "*");
1985
1985
  res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
1986
- res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-XSRF-TOKEN, X-Requested-With, X-Inertia, X-Inertia-Version");
1986
+ res.setHeader(
1987
+ "Access-Control-Allow-Headers",
1988
+ "Content-Type, Authorization, X-XSRF-TOKEN, X-Requested-With, X-Inertia, X-Inertia-Version"
1989
+ );
1987
1990
  res.setHeader("Access-Control-Expose-Headers", "X-Inertia-Location");
1988
1991
  res.setHeader("Access-Control-Allow-Private-Network", "true");
1989
1992
  if (req.method === "OPTIONS") {
@@ -2006,11 +2009,13 @@ function startCallbackServer(expectedState, timeoutMs = 5 * 60 * 1e3) {
2006
2009
  const errorDescription = url.searchParams.get("error_description") || error;
2007
2010
  if (isJsonRequest) {
2008
2011
  res.writeHead(400, { "Content-Type": "application/json" });
2009
- res.end(JSON.stringify({
2010
- status: "error",
2011
- error,
2012
- message: errorDescription
2013
- }));
2012
+ res.end(
2013
+ JSON.stringify({
2014
+ status: "error",
2015
+ error,
2016
+ message: errorDescription
2017
+ })
2018
+ );
2014
2019
  } else {
2015
2020
  const escapedError = escapeHtml(errorDescription);
2016
2021
  res.writeHead(400, { "Content-Type": "text/html" });
@@ -2031,11 +2036,13 @@ function startCallbackServer(expectedState, timeoutMs = 5 * 60 * 1e3) {
2031
2036
  if (state !== expectedState) {
2032
2037
  if (isJsonRequest) {
2033
2038
  res.writeHead(400, { "Content-Type": "application/json" });
2034
- res.end(JSON.stringify({
2035
- status: "error",
2036
- error: "invalid_state",
2037
- message: "State parameter mismatch"
2038
- }));
2039
+ res.end(
2040
+ JSON.stringify({
2041
+ status: "error",
2042
+ error: "invalid_state",
2043
+ message: "State parameter mismatch"
2044
+ })
2045
+ );
2039
2046
  } else {
2040
2047
  res.writeHead(400, { "Content-Type": "text/html" });
2041
2048
  res.end(`
@@ -2055,11 +2062,13 @@ function startCallbackServer(expectedState, timeoutMs = 5 * 60 * 1e3) {
2055
2062
  if (!token) {
2056
2063
  if (isJsonRequest) {
2057
2064
  res.writeHead(400, { "Content-Type": "application/json" });
2058
- res.end(JSON.stringify({
2059
- status: "error",
2060
- error: "missing_token",
2061
- message: "No token provided"
2062
- }));
2065
+ res.end(
2066
+ JSON.stringify({
2067
+ status: "error",
2068
+ error: "missing_token",
2069
+ message: "No token provided"
2070
+ })
2071
+ );
2063
2072
  } else {
2064
2073
  res.writeHead(400, { "Content-Type": "text/html" });
2065
2074
  res.end(`
@@ -2081,14 +2090,16 @@ function startCallbackServer(expectedState, timeoutMs = 5 * 60 * 1e3) {
2081
2090
  res.end();
2082
2091
  } else if (isJsonRequest) {
2083
2092
  res.writeHead(200, { "Content-Type": "application/json" });
2084
- res.end(JSON.stringify({
2085
- status: "success",
2086
- message: "Authentication successful",
2087
- user: "Authenticated",
2088
- next: next || void 0
2089
- }));
2093
+ res.end(
2094
+ JSON.stringify({
2095
+ status: "success",
2096
+ message: "Authentication successful",
2097
+ user: "Authenticated",
2098
+ next: next || void 0
2099
+ })
2100
+ );
2090
2101
  } else if (next) {
2091
- res.writeHead(302, { "Location": next });
2102
+ res.writeHead(302, { Location: next });
2092
2103
  res.end();
2093
2104
  } else {
2094
2105
  res.writeHead(200, { "Content-Type": "text/html" });
@@ -2176,10 +2187,12 @@ function startCallbackServer(expectedState, timeoutMs = 5 * 60 * 1e3) {
2176
2187
  const isJsonRequest = req.headers.accept?.includes("application/json");
2177
2188
  if (isJsonRequest) {
2178
2189
  res.writeHead(500, { "Content-Type": "application/json" });
2179
- res.end(JSON.stringify({
2180
- status: "error",
2181
- message: "Internal server error processing callback"
2182
- }));
2190
+ res.end(
2191
+ JSON.stringify({
2192
+ status: "error",
2193
+ message: "Internal server error processing callback"
2194
+ })
2195
+ );
2183
2196
  } else {
2184
2197
  res.writeHead(500, { "Content-Type": "text/html" });
2185
2198
  res.end(`
@@ -2239,7 +2252,11 @@ function startCallbackServer(expectedState, timeoutMs = 5 * 60 * 1e3) {
2239
2252
  const port = address.port;
2240
2253
  timeout = setTimeout(() => {
2241
2254
  server.close();
2242
- callbackReject(new Error("Authentication timeout: No callback received within 5 minutes"));
2255
+ callbackReject(
2256
+ new Error(
2257
+ "Authentication timeout: No callback received within 5 minutes"
2258
+ )
2259
+ );
2243
2260
  }, timeoutMs);
2244
2261
  callbackPromise.then(() => clearTimeout(timeout)).catch(() => clearTimeout(timeout)).finally(() => {
2245
2262
  setTimeout(() => {
@@ -2267,11 +2284,17 @@ function registerLoginCommand(program2) {
2267
2284
  authUrl.searchParams.set("state", state);
2268
2285
  authUrl.searchParams.set("machine_id", machineId);
2269
2286
  authUrl.searchParams.set("machine_name", machineName);
2270
- authUrl.searchParams.set("redirect_uri", `http://localhost:${port}/auth/callback`);
2287
+ authUrl.searchParams.set(
2288
+ "redirect_uri",
2289
+ `http://localhost:${port}/auth/callback`
2290
+ );
2271
2291
  spinner.text = "Opening browser for authentication...";
2272
2292
  await open(authUrl.toString());
2273
2293
  spinner.text = "Waiting for authentication...";
2274
- logger.info("login", `Login initiated, callback server listening on port ${port}`);
2294
+ logger.info(
2295
+ "login",
2296
+ `Login initiated, callback server listening on port ${port}`
2297
+ );
2275
2298
  const token = await callbackPromise;
2276
2299
  spinner.text = "Completing authentication...";
2277
2300
  await completeLogin(token);
@@ -2297,8 +2320,12 @@ async function completeLogin(token) {
2297
2320
  spinner.succeed("Authentication successful!");
2298
2321
  console.log(chalk.green(`
2299
2322
  \u2713 Logged in as ${chalk.bold(user.email)}`));
2300
- console.log(chalk.gray(`Machine: ${authService.getMachineName()} (${authService.getMachineId()})
2301
- `));
2323
+ console.log(
2324
+ chalk.gray(
2325
+ `Machine: ${authService.getMachineName()} (${authService.getMachineId()})
2326
+ `
2327
+ )
2328
+ );
2302
2329
  logger.success("login", `Logged in as ${user.email}`);
2303
2330
  } catch (error) {
2304
2331
  spinner.fail("Authentication failed");
@@ -2321,11 +2348,18 @@ function registerLogoutCommand(program2) {
2321
2348
  try {
2322
2349
  await apiService.disconnect();
2323
2350
  } catch {
2324
- logger.warn("logout", "Failed to disconnect session, continuing with logout");
2351
+ logger.warn(
2352
+ "logout",
2353
+ "Failed to disconnect session, continuing with logout"
2354
+ );
2325
2355
  }
2326
2356
  await authService.clearToken();
2327
2357
  spinner.succeed("Logged out successfully");
2328
- console.log(chalk2.gray("\nYour credentials have been removed from this machine.\n"));
2358
+ console.log(
2359
+ chalk2.gray(
2360
+ "\nYour credentials have been removed from this machine.\n"
2361
+ )
2362
+ );
2329
2363
  logger.success("logout", "User logged out");
2330
2364
  } catch (error) {
2331
2365
  spinner.fail("Logout failed");
@@ -2360,30 +2394,40 @@ function registerWhoamiCommand(program2) {
2360
2394
  const user = await authService.validateToken();
2361
2395
  if (!user) {
2362
2396
  if (options.json) {
2363
- console.log(JSON.stringify({ authenticated: false, error: "Token invalid" }));
2397
+ console.log(
2398
+ JSON.stringify({ authenticated: false, error: "Token invalid" })
2399
+ );
2364
2400
  await authService.clearToken();
2365
2401
  return;
2366
2402
  }
2367
2403
  if (spinner) spinner.fail("Authentication invalid");
2368
- console.log(chalk3.red("\n\u2716 Your authentication token is invalid or expired."));
2404
+ console.log(
2405
+ chalk3.red("\n\u2716 Your authentication token is invalid or expired.")
2406
+ );
2369
2407
  console.log(chalk3.gray('Run "stint login" to re-authenticate.\n'));
2370
2408
  await authService.clearToken();
2371
2409
  return;
2372
2410
  }
2373
2411
  if (options.json) {
2374
2412
  logger.disableConsole();
2375
- console.log(JSON.stringify({
2376
- authenticated: true,
2377
- user: {
2378
- name: user.name,
2379
- email: user.email,
2380
- id: user.id
2381
- },
2382
- machine: {
2383
- name: authService.getMachineName(),
2384
- id: authService.getMachineId()
2385
- }
2386
- }, null, 2));
2413
+ console.log(
2414
+ JSON.stringify(
2415
+ {
2416
+ authenticated: true,
2417
+ user: {
2418
+ name: user.name,
2419
+ email: user.email,
2420
+ id: user.id
2421
+ },
2422
+ machine: {
2423
+ name: authService.getMachineName(),
2424
+ id: authService.getMachineId()
2425
+ }
2426
+ },
2427
+ null,
2428
+ 2
2429
+ )
2430
+ );
2387
2431
  return;
2388
2432
  }
2389
2433
  if (spinner) spinner.succeed("Authenticated");
@@ -2394,10 +2438,15 @@ function registerWhoamiCommand(program2) {
2394
2438
  console.log(`${chalk3.bold("User ID:")} ${user.id}`);
2395
2439
  console.log(chalk3.blue("\n\u{1F4BB} Machine Information:"));
2396
2440
  console.log(chalk3.gray("\u2500".repeat(50)));
2397
- console.log(`${chalk3.bold("Name:")} ${authService.getMachineName()}`);
2441
+ console.log(
2442
+ `${chalk3.bold("Name:")} ${authService.getMachineName()}`
2443
+ );
2398
2444
  console.log(`${chalk3.bold("ID:")} ${authService.getMachineId()}`);
2399
2445
  console.log();
2400
- logger.info("whoami", `User: ${user.email}, Machine: ${authService.getMachineName()}`);
2446
+ logger.info(
2447
+ "whoami",
2448
+ `User: ${user.email}, Machine: ${authService.getMachineName()}`
2449
+ );
2401
2450
  } catch (error) {
2402
2451
  if (spinner) spinner.fail("Failed to retrieve information");
2403
2452
  logger.error("whoami", "Command failed", error);
@@ -2426,9 +2475,17 @@ function registerLinkCommand(program2) {
2426
2475
  const existingLink = await projectService.getLinkedProject(cwd);
2427
2476
  if (existingLink) {
2428
2477
  spinner.warn("Directory already linked");
2429
- console.log(chalk4.yellow(`
2430
- \u26A0 This directory is already linked to project ${existingLink.projectId}`));
2431
- console.log(chalk4.gray('Run "stint unlink" first if you want to link to a different project.\n'));
2478
+ console.log(
2479
+ chalk4.yellow(
2480
+ `
2481
+ \u26A0 This directory is already linked to project ${existingLink.projectId}`
2482
+ )
2483
+ );
2484
+ console.log(
2485
+ chalk4.gray(
2486
+ 'Run "stint unlink" first if you want to link to a different project.\n'
2487
+ )
2488
+ );
2432
2489
  return;
2433
2490
  }
2434
2491
  spinner.text = "Verifying git repository...";
@@ -2436,15 +2493,21 @@ function registerLinkCommand(program2) {
2436
2493
  if (!isRepo) {
2437
2494
  spinner.fail("Not a git repository");
2438
2495
  console.log(chalk4.red("\n\u2716 This directory is not a git repository."));
2439
- console.log(chalk4.gray("Please run this command in a git repository.\n"));
2496
+ console.log(
2497
+ chalk4.gray("Please run this command in a git repository.\n")
2498
+ );
2440
2499
  process2.exit(1);
2441
2500
  }
2442
2501
  spinner.text = "Fetching projects...";
2443
2502
  const projects = await apiService.getLinkedProjects();
2444
2503
  if (projects.length === 0) {
2445
2504
  spinner.info("No projects available");
2446
- console.log(chalk4.yellow("\n\u26A0 No projects found in your Stint account."));
2447
- console.log(chalk4.gray("Create a project at https://stint.codes first.\n"));
2505
+ console.log(
2506
+ chalk4.yellow("\n\u26A0 No projects found in your Stint account.")
2507
+ );
2508
+ console.log(
2509
+ chalk4.gray("Create a project at https://stint.codes first.\n")
2510
+ );
2448
2511
  return;
2449
2512
  }
2450
2513
  spinner.succeed("Ready to link");
@@ -2481,7 +2544,10 @@ function registerLinkCommand(program2) {
2481
2544
  try {
2482
2545
  repoInfo = await gitService.getRepoInfo(cwd);
2483
2546
  } catch (e) {
2484
- logger.warn("link", `Failed to get repo info for creation metadata: ${e.message}`);
2547
+ logger.warn(
2548
+ "link",
2549
+ `Failed to get repo info for creation metadata: ${e.message}`
2550
+ );
2485
2551
  }
2486
2552
  }
2487
2553
  const newProject = await apiService.createProject({
@@ -2502,8 +2568,12 @@ function registerLinkCommand(program2) {
2502
2568
  const linkSpinner = ora4("Linking project...").start();
2503
2569
  await projectService.linkProject(cwd, selectedProjectId);
2504
2570
  linkSpinner.succeed("Project linked successfully!");
2505
- console.log(chalk4.green(`
2506
- \u2713 Linked to ${chalk4.bold(selectedProject?.name || selectedProjectId)}`));
2571
+ console.log(
2572
+ chalk4.green(
2573
+ `
2574
+ \u2713 Linked to ${chalk4.bold(selectedProject?.name || selectedProjectId)}`
2575
+ )
2576
+ );
2507
2577
  console.log(chalk4.gray(`Directory: ${cwd}`));
2508
2578
  console.log(chalk4.gray(`Project ID: ${selectedProjectId}
2509
2579
  `));
@@ -2532,14 +2602,18 @@ function registerUnlinkCommand(program2) {
2532
2602
  const linkedProject = await projectService.getLinkedProject(cwd);
2533
2603
  if (!linkedProject) {
2534
2604
  spinner.info("Not linked");
2535
- console.log(chalk5.yellow("\n\u26A0 This directory is not linked to any project.\n"));
2605
+ console.log(
2606
+ chalk5.yellow("\n\u26A0 This directory is not linked to any project.\n")
2607
+ );
2536
2608
  return;
2537
2609
  }
2538
2610
  spinner.stop();
2539
2611
  console.log(chalk5.blue("\n\u{1F4CB} Current Link:"));
2540
2612
  console.log(chalk5.gray("\u2500".repeat(50)));
2541
2613
  console.log(`${chalk5.bold("Project ID:")} ${linkedProject.projectId}`);
2542
- console.log(`${chalk5.bold("Linked At:")} ${new Date(linkedProject.linkedAt).toLocaleString()}`);
2614
+ console.log(
2615
+ `${chalk5.bold("Linked At:")} ${new Date(linkedProject.linkedAt).toLocaleString()}`
2616
+ );
2543
2617
  console.log();
2544
2618
  if (!options.force) {
2545
2619
  const shouldUnlink = await confirm({
@@ -2583,11 +2657,13 @@ function registerStatusCommand(program2) {
2583
2657
  try {
2584
2658
  const { render } = await import("ink");
2585
2659
  const { createElement } = await import("react");
2586
- const { StatusDashboard } = await import("./StatusDashboard-N3HF2TD3.js");
2660
+ const { StatusDashboard } = await import("./StatusDashboard-VOOOQA7A.js");
2587
2661
  render(createElement(StatusDashboard, { cwd }));
2588
2662
  return;
2589
2663
  } catch (error) {
2590
- console.error(chalk6.red(`Failed to start dashboard: ${error.message}`));
2664
+ console.error(
2665
+ chalk6.red(`Failed to start dashboard: ${error.message}`)
2666
+ );
2591
2667
  process4.exit(1);
2592
2668
  }
2593
2669
  }
@@ -2641,7 +2717,13 @@ function registerStatusCommand(program2) {
2641
2717
  daemon: {
2642
2718
  running: valid && !!pid,
2643
2719
  pid: pid || null,
2644
- logFile: path2.join(os.homedir(), ".config", "stint", "logs", "daemon.log")
2720
+ logFile: path2.join(
2721
+ os.homedir(),
2722
+ ".config",
2723
+ "stint",
2724
+ "logs",
2725
+ "daemon.log"
2726
+ )
2645
2727
  }
2646
2728
  };
2647
2729
  console.log(JSON.stringify(statusOutput, null, 2));
@@ -2651,34 +2733,67 @@ function registerStatusCommand(program2) {
2651
2733
  console.log(chalk6.blue("\n\u{1F4E6} Project Status:"));
2652
2734
  console.log(chalk6.gray("\u2500".repeat(50)));
2653
2735
  if (linkedProject) {
2654
- console.log(`${chalk6.bold("Status:")} ${chalk6.green("\u2713 Linked")}`);
2655
- console.log(`${chalk6.bold("Project ID:")} ${linkedProject.projectId}`);
2656
- console.log(`${chalk6.bold("Linked At:")} ${new Date(linkedProject.linkedAt).toLocaleString()}`);
2736
+ console.log(
2737
+ `${chalk6.bold("Status:")} ${chalk6.green("\u2713 Linked")}`
2738
+ );
2739
+ console.log(
2740
+ `${chalk6.bold("Project ID:")} ${linkedProject.projectId}`
2741
+ );
2742
+ console.log(
2743
+ `${chalk6.bold("Linked At:")} ${new Date(linkedProject.linkedAt).toLocaleString()}`
2744
+ );
2657
2745
  } else {
2658
- console.log(`${chalk6.bold("Status:")} ${chalk6.yellow("Not linked")}`);
2659
- console.log(chalk6.gray('Run "stint link" to link this directory to a project.'));
2746
+ console.log(
2747
+ `${chalk6.bold("Status:")} ${chalk6.yellow("Not linked")}`
2748
+ );
2749
+ console.log(
2750
+ chalk6.gray('Run "stint link" to link this directory to a project.')
2751
+ );
2660
2752
  }
2661
2753
  console.log(chalk6.blue("\n\u{1F4C2} Git Repository:"));
2662
2754
  console.log(chalk6.gray("\u2500".repeat(50)));
2663
2755
  if (isRepo) {
2664
2756
  try {
2665
2757
  if (repoInfo) {
2666
- console.log(`${chalk6.bold("Branch:")} ${chalk6.cyan(repoInfo.currentBranch)}`);
2667
- console.log(`${chalk6.bold("Remote:")} ${repoInfo.remoteUrl || chalk6.gray("None")}`);
2668
- console.log(`${chalk6.bold("Last Commit:")} ${repoInfo.lastCommitSha.substring(0, 7)} - ${repoInfo.lastCommitMessage}`);
2669
- console.log(`${chalk6.bold("Commit Date:")} ${new Date(repoInfo.lastCommitDate).toLocaleString()}`);
2758
+ console.log(
2759
+ `${chalk6.bold("Branch:")} ${chalk6.cyan(repoInfo.currentBranch)}`
2760
+ );
2761
+ console.log(
2762
+ `${chalk6.bold("Remote:")} ${repoInfo.remoteUrl || chalk6.gray("None")}`
2763
+ );
2764
+ console.log(
2765
+ `${chalk6.bold("Last Commit:")} ${repoInfo.lastCommitSha.substring(0, 7)} - ${repoInfo.lastCommitMessage}`
2766
+ );
2767
+ console.log(
2768
+ `${chalk6.bold("Commit Date:")} ${new Date(repoInfo.lastCommitDate).toLocaleString()}`
2769
+ );
2670
2770
  const { staged, unstaged, untracked, ahead, behind } = repoInfo.status;
2671
2771
  const totalChanges = staged.length + unstaged.length + untracked.length;
2672
2772
  if (totalChanges > 0) {
2673
- console.log(`${chalk6.bold("Changes:")} ${chalk6.yellow(`${totalChanges} file(s)`)}`);
2674
- if (staged.length > 0) console.log(` ${chalk6.green("Staged:")} ${staged.length}`);
2675
- if (unstaged.length > 0) console.log(` ${chalk6.yellow("Unstaged:")} ${unstaged.length}`);
2676
- if (untracked.length > 0) console.log(` ${chalk6.gray("Untracked:")} ${untracked.length}`);
2773
+ console.log(
2774
+ `${chalk6.bold("Changes:")} ${chalk6.yellow(`${totalChanges} file(s)`)}`
2775
+ );
2776
+ if (staged.length > 0)
2777
+ console.log(
2778
+ ` ${chalk6.green("Staged:")} ${staged.length}`
2779
+ );
2780
+ if (unstaged.length > 0)
2781
+ console.log(
2782
+ ` ${chalk6.yellow("Unstaged:")} ${unstaged.length}`
2783
+ );
2784
+ if (untracked.length > 0)
2785
+ console.log(
2786
+ ` ${chalk6.gray("Untracked:")} ${untracked.length}`
2787
+ );
2677
2788
  } else {
2678
- console.log(`${chalk6.bold("Changes:")} ${chalk6.green("Clean working tree")}`);
2789
+ console.log(
2790
+ `${chalk6.bold("Changes:")} ${chalk6.green("Clean working tree")}`
2791
+ );
2679
2792
  }
2680
2793
  if (ahead > 0 || behind > 0) {
2681
- console.log(`${chalk6.bold("Sync Status:")} ${ahead > 0 ? chalk6.yellow(`\u2191${ahead}`) : ""} ${behind > 0 ? chalk6.yellow(`\u2193${behind}`) : ""}`);
2794
+ console.log(
2795
+ `${chalk6.bold("Sync Status:")} ${ahead > 0 ? chalk6.yellow(`\u2191${ahead}`) : ""} ${behind > 0 ? chalk6.yellow(`\u2193${behind}`) : ""}`
2796
+ );
2682
2797
  }
2683
2798
  } else {
2684
2799
  console.log(chalk6.red("Error reading repository information"));
@@ -2692,22 +2807,40 @@ function registerStatusCommand(program2) {
2692
2807
  console.log(chalk6.blue("\n\u{1F510} Authentication:"));
2693
2808
  console.log(chalk6.gray("\u2500".repeat(50)));
2694
2809
  if (user) {
2695
- console.log(`${chalk6.bold("Status:")} ${chalk6.green("\u2713 Authenticated")}`);
2696
- console.log(`${chalk6.bold("User:")} ${user.name} (${user.email})`);
2697
- console.log(`${chalk6.bold("Machine:")} ${authService.getMachineName()}`);
2810
+ console.log(
2811
+ `${chalk6.bold("Status:")} ${chalk6.green("\u2713 Authenticated")}`
2812
+ );
2813
+ console.log(
2814
+ `${chalk6.bold("User:")} ${user.name} (${user.email})`
2815
+ );
2816
+ console.log(
2817
+ `${chalk6.bold("Machine:")} ${authService.getMachineName()}`
2818
+ );
2698
2819
  } else {
2699
- console.log(`${chalk6.bold("Status:")} ${chalk6.yellow("Not logged in")}`);
2820
+ console.log(
2821
+ `${chalk6.bold("Status:")} ${chalk6.yellow("Not logged in")}`
2822
+ );
2700
2823
  console.log(chalk6.gray('Run "stint login" to authenticate.'));
2701
2824
  }
2702
2825
  console.log(chalk6.blue("\n\u2699\uFE0F Daemon:"));
2703
2826
  console.log(chalk6.gray("\u2500".repeat(50)));
2704
2827
  if (valid && pid) {
2705
- console.log(`${chalk6.bold("Status:")} ${chalk6.green("\u2713 Running")}`);
2828
+ console.log(
2829
+ `${chalk6.bold("Status:")} ${chalk6.green("\u2713 Running")}`
2830
+ );
2706
2831
  console.log(`${chalk6.bold("PID:")} ${pid}`);
2707
- console.log(`${chalk6.bold("Logs:")} ${path2.join(os.homedir(), ".config", "stint", "logs", "daemon.log")}`);
2832
+ console.log(
2833
+ `${chalk6.bold("Logs:")} ${path2.join(os.homedir(), ".config", "stint", "logs", "daemon.log")}`
2834
+ );
2708
2835
  } else {
2709
- console.log(`${chalk6.bold("Status:")} ${chalk6.yellow("Not running")}`);
2710
- console.log(chalk6.gray('Run "stint daemon start" to start the background agent.'));
2836
+ console.log(
2837
+ `${chalk6.bold("Status:")} ${chalk6.yellow("Not running")}`
2838
+ );
2839
+ console.log(
2840
+ chalk6.gray(
2841
+ 'Run "stint daemon start" to start the background agent.'
2842
+ )
2843
+ );
2711
2844
  }
2712
2845
  console.log();
2713
2846
  logger.info("status", "Status command executed");
@@ -2734,8 +2867,12 @@ function registerSyncCommand(program2) {
2734
2867
  const linkedProject = await projectService.getLinkedProject(cwd);
2735
2868
  if (!linkedProject) {
2736
2869
  spinner.fail("Not linked");
2737
- console.log(chalk7.yellow("\n\u26A0 This directory is not linked to any project."));
2738
- console.log(chalk7.gray('Run "stint link" first to link this directory.\n'));
2870
+ console.log(
2871
+ chalk7.yellow("\n\u26A0 This directory is not linked to any project.")
2872
+ );
2873
+ console.log(
2874
+ chalk7.gray('Run "stint link" first to link this directory.\n')
2875
+ );
2739
2876
  process5.exit(1);
2740
2877
  }
2741
2878
  spinner.text = "Analyzing repository...";
@@ -2749,7 +2886,11 @@ function registerSyncCommand(program2) {
2749
2886
  spinner.text = "Preparing sync payload...";
2750
2887
  const syncSpinner = ora7("Connecting to server...").start();
2751
2888
  try {
2752
- await apiService.syncProject(linkedProject.projectId, repoInfo, changedFiles);
2889
+ await apiService.syncProject(
2890
+ linkedProject.projectId,
2891
+ repoInfo,
2892
+ changedFiles
2893
+ );
2753
2894
  syncSpinner.succeed("Server sync completed");
2754
2895
  } catch (error) {
2755
2896
  syncSpinner.fail("Server sync failed");
@@ -2757,14 +2898,25 @@ function registerSyncCommand(program2) {
2757
2898
  }
2758
2899
  console.log(chalk7.green("\n\u2713 Repository sync completed"));
2759
2900
  console.log(chalk7.gray("\u2500".repeat(50)));
2760
- console.log(`${chalk7.bold("Files:")} ${totalFiles} total (${status.staged.length} staged, ${status.unstaged.length} modified, ${status.untracked.length} untracked)`);
2761
- console.log(`${chalk7.bold("Changed:")} ${changedFiles.length} files synced for commit selection`);
2901
+ console.log(
2902
+ `${chalk7.bold("Files:")} ${totalFiles} total (${status.staged.length} staged, ${status.unstaged.length} modified, ${status.untracked.length} untracked)`
2903
+ );
2904
+ console.log(
2905
+ `${chalk7.bold("Changed:")} ${changedFiles.length} files synced for commit selection`
2906
+ );
2762
2907
  console.log(`${chalk7.bold("Project ID:")} ${linkedProject.projectId}`);
2763
2908
  console.log(`${chalk7.bold("Branch:")} ${repoInfo.currentBranch}`);
2764
- console.log(`${chalk7.bold("Commit:")} ${repoInfo.lastCommitSha.substring(0, 7)} - ${repoInfo.lastCommitMessage}`);
2765
- console.log(`${chalk7.bold("Remote:")} ${repoInfo.remoteUrl || chalk7.gray("None")}`);
2909
+ console.log(
2910
+ `${chalk7.bold("Commit:")} ${repoInfo.lastCommitSha.substring(0, 7)} - ${repoInfo.lastCommitMessage}`
2911
+ );
2912
+ console.log(
2913
+ `${chalk7.bold("Remote:")} ${repoInfo.remoteUrl || chalk7.gray("None")}`
2914
+ );
2766
2915
  console.log();
2767
- logger.success("sync", `Synced ${cwd} to project ${linkedProject.projectId}`);
2916
+ logger.success(
2917
+ "sync",
2918
+ `Synced ${cwd} to project ${linkedProject.projectId}`
2919
+ );
2768
2920
  } catch (error) {
2769
2921
  spinner.fail("Sync failed");
2770
2922
  logger.error("sync", "Sync command failed", error);
@@ -2827,7 +2979,9 @@ function getLinuxStats(pid) {
2827
2979
  };
2828
2980
  }
2829
2981
  function getMacStats(pid) {
2830
- const psOutput = execSync(`ps -p ${pid} -o %cpu,%mem,etime,thcount`).toString();
2982
+ const psOutput = execSync(
2983
+ `ps -p ${pid} -o %cpu,%mem,etime,thcount`
2984
+ ).toString();
2831
2985
  const [cpu, mem, etime, threads] = psOutput.split("\n")[1].trim().split(/\s+/);
2832
2986
  const uptimeSeconds = parseElapsedTime(etime);
2833
2987
  const totalMem = os2.totalmem() / (1024 * 1024);
@@ -2942,16 +3096,20 @@ function registerDaemonCommands(program2) {
2942
3096
  const { valid, pid } = validatePidFile();
2943
3097
  if (valid && pid) {
2944
3098
  spinner.info("Daemon already running");
2945
- console.log(chalk8.yellow(`
3099
+ console.log(
3100
+ chalk8.yellow(`
2946
3101
  \u26A0 Daemon is already running (PID: ${pid})
2947
- `));
3102
+ `)
3103
+ );
2948
3104
  return;
2949
3105
  }
2950
3106
  spinner.text = "Validating authentication...";
2951
3107
  const user = await authService.validateToken();
2952
3108
  if (!user) {
2953
3109
  spinner.fail("Not authenticated");
2954
- console.log(chalk8.red("\n\u2716 You must be logged in to start the daemon."));
3110
+ console.log(
3111
+ chalk8.red("\n\u2716 You must be logged in to start the daemon.")
3112
+ );
2955
3113
  console.log(chalk8.gray('Run "stint login" first.\n'));
2956
3114
  process.exit(1);
2957
3115
  }
@@ -2969,8 +3127,12 @@ function registerDaemonCommands(program2) {
2969
3127
  console.log(chalk8.green(`
2970
3128
  \u2713 Daemon is running in the background`));
2971
3129
  console.log(chalk8.gray(`PID: ${daemonPid}`));
2972
- console.log(chalk8.gray(`Logs: ${path3.join(os3.homedir(), ".config", "stint", "logs", "daemon.log")}
2973
- `));
3130
+ console.log(
3131
+ chalk8.gray(
3132
+ `Logs: ${path3.join(os3.homedir(), ".config", "stint", "logs", "daemon.log")}
3133
+ `
3134
+ )
3135
+ );
2974
3136
  logger.success("daemon", `Daemon started with PID ${daemonPid}`);
2975
3137
  } catch (error) {
2976
3138
  spinner.fail("Failed to start daemon");
@@ -3027,10 +3189,14 @@ function registerDaemonCommands(program2) {
3027
3189
  console.log(chalk8.blue("\n\u2699\uFE0F Daemon Status:"));
3028
3190
  console.log(chalk8.gray("\u2500".repeat(50)));
3029
3191
  if (valid && pid) {
3030
- console.log(`${chalk8.bold("Status:")} ${chalk8.green("\u2713 Running")}`);
3192
+ console.log(
3193
+ `${chalk8.bold("Status:")} ${chalk8.green("\u2713 Running")}`
3194
+ );
3031
3195
  console.log(`${chalk8.bold("PID:")} ${pid}`);
3032
3196
  console.log(`${chalk8.bold("PID File:")} ${getPidFilePath()}`);
3033
- console.log(`${chalk8.bold("Logs:")} ${path3.join(os3.homedir(), ".config", "stint", "logs", "daemon.log")}`);
3197
+ console.log(
3198
+ `${chalk8.bold("Logs:")} ${path3.join(os3.homedir(), ".config", "stint", "logs", "daemon.log")}`
3199
+ );
3034
3200
  const stats = await getProcessStats(pid);
3035
3201
  if (stats) {
3036
3202
  console.log(chalk8.blue("\n\u{1F4CA} Resource Usage:"));
@@ -3038,38 +3204,66 @@ function registerDaemonCommands(program2) {
3038
3204
  console.log(`${chalk8.bold("CPU:")} ${stats.cpuPercent}%`);
3039
3205
  console.log(`${chalk8.bold("Memory:")} ${stats.memoryMB} MB`);
3040
3206
  console.log(`${chalk8.bold("Threads:")} ${stats.threads}`);
3041
- console.log(`${chalk8.bold("Uptime:")} ${formatUptime(stats.uptime)}`);
3207
+ console.log(
3208
+ `${chalk8.bold("Uptime:")} ${formatUptime(stats.uptime)}`
3209
+ );
3042
3210
  }
3043
- const statusPath = path3.join(os3.homedir(), ".config", "stint", "daemon.status.json");
3211
+ const statusPath = path3.join(
3212
+ os3.homedir(),
3213
+ ".config",
3214
+ "stint",
3215
+ "daemon.status.json"
3216
+ );
3044
3217
  if (fs.existsSync(statusPath)) {
3045
3218
  try {
3046
- const statusData = JSON.parse(fs.readFileSync(statusPath, "utf8"));
3219
+ const statusData = JSON.parse(
3220
+ fs.readFileSync(statusPath, "utf8")
3221
+ );
3047
3222
  console.log(chalk8.blue("\n\u{1F4E1} WebSocket Status:"));
3048
3223
  console.log(chalk8.gray("\u2500".repeat(50)));
3049
3224
  if (statusData.websocket?.connected) {
3050
- console.log(`${chalk8.bold("Connected:")} ${chalk8.green("\u2713 Yes")}`);
3225
+ console.log(
3226
+ `${chalk8.bold("Connected:")} ${chalk8.green("\u2713 Yes")}`
3227
+ );
3051
3228
  if (statusData.websocket.channel) {
3052
- console.log(`${chalk8.bold("Channel:")} ${statusData.websocket.channel}`);
3229
+ console.log(
3230
+ `${chalk8.bold("Channel:")} ${statusData.websocket.channel}`
3231
+ );
3053
3232
  }
3054
3233
  } else {
3055
- console.log(`${chalk8.bold("Connected:")} ${chalk8.yellow("\u2717 No")}`);
3234
+ console.log(
3235
+ `${chalk8.bold("Connected:")} ${chalk8.yellow("\u2717 No")}`
3236
+ );
3056
3237
  }
3057
3238
  if (statusData.websocket?.lastEvent) {
3058
- console.log(`${chalk8.bold("Last Event:")} ${statusData.websocket.lastEvent}`);
3239
+ console.log(
3240
+ `${chalk8.bold("Last Event:")} ${statusData.websocket.lastEvent}`
3241
+ );
3059
3242
  if (statusData.websocket.lastEventTime) {
3060
- const ago = Math.floor((Date.now() - new Date(statusData.websocket.lastEventTime).getTime()) / 1e3);
3061
- console.log(`${chalk8.bold("Event Time:")} ${formatUptime(ago)} ago`);
3243
+ const ago = Math.floor(
3244
+ (Date.now() - new Date(statusData.websocket.lastEventTime).getTime()) / 1e3
3245
+ );
3246
+ console.log(
3247
+ `${chalk8.bold("Event Time:")} ${formatUptime(ago)} ago`
3248
+ );
3062
3249
  }
3063
3250
  }
3064
3251
  } catch {
3065
3252
  }
3066
3253
  }
3067
3254
  } else {
3068
- console.log(`${chalk8.bold("Status:")} ${chalk8.yellow("Not running")}`);
3069
- console.log(chalk8.gray('Run "stint daemon start" to start the daemon.'));
3255
+ console.log(
3256
+ `${chalk8.bold("Status:")} ${chalk8.yellow("Not running")}`
3257
+ );
3258
+ console.log(
3259
+ chalk8.gray('Run "stint daemon start" to start the daemon.')
3260
+ );
3070
3261
  }
3071
3262
  console.log();
3072
- logger.info("daemon", `Status check: ${valid ? "running" : "not running"}`);
3263
+ logger.info(
3264
+ "daemon",
3265
+ `Status check: ${valid ? "running" : "not running"}`
3266
+ );
3073
3267
  } catch (error) {
3074
3268
  spinner.fail("Failed to check status");
3075
3269
  logger.error("daemon", "Status command failed", error);
@@ -3114,19 +3308,38 @@ function registerDaemonCommands(program2) {
3114
3308
  throw new Error("Daemon failed to start");
3115
3309
  }
3116
3310
  startSpinner.succeed("Daemon started");
3117
- console.log(chalk8.green(`
3311
+ console.log(
3312
+ chalk8.green(
3313
+ `
3118
3314
  \u2713 Daemon restarted successfully (PID: ${daemonPid})
3119
- `));
3315
+ `
3316
+ )
3317
+ );
3120
3318
  logger.success("daemon", `Daemon restarted with PID ${daemonPid}`);
3121
3319
  } catch (error) {
3122
3320
  startSpinner.fail("Failed to start daemon");
3123
3321
  throw error;
3124
3322
  }
3125
3323
  });
3126
- daemon.command("logs").description("View and filter daemon logs").option("-l, --level <level>", "Filter by log level (INFO, WARN, ERROR, DEBUG)").option("-c, --category <category>", "Filter by log category").option("-s, --since <date>", 'Show logs since date/time (ISO format or relative time like "1h", "2d")').option("-u, --until <date>", 'Show logs until date/time (ISO format or relative time like "1h", "2d")').option("--search <text>", "Search for specific text in log messages").option("-f, --follow", "Follow log output in real time").option("-n, --lines <number>", "Number of lines to show", "50").action(async (command) => {
3324
+ daemon.command("logs").description("View and filter daemon logs").option(
3325
+ "-l, --level <level>",
3326
+ "Filter by log level (INFO, WARN, ERROR, DEBUG)"
3327
+ ).option("-c, --category <category>", "Filter by log category").option(
3328
+ "-s, --since <date>",
3329
+ 'Show logs since date/time (ISO format or relative time like "1h", "2d")'
3330
+ ).option(
3331
+ "-u, --until <date>",
3332
+ 'Show logs until date/time (ISO format or relative time like "1h", "2d")'
3333
+ ).option("--search <text>", "Search for specific text in log messages").option("-f, --follow", "Follow log output in real time").option("-n, --lines <number>", "Number of lines to show", "50").action(async (command) => {
3127
3334
  const spinner = ora8("Loading logs...").start();
3128
3335
  try {
3129
- const logPath = path3.join(os3.homedir(), ".config", "stint", "logs", "agent.log");
3336
+ const logPath = path3.join(
3337
+ os3.homedir(),
3338
+ ".config",
3339
+ "stint",
3340
+ "logs",
3341
+ "agent.log"
3342
+ );
3130
3343
  if (!fs.existsSync(logPath)) {
3131
3344
  spinner.fail("No logs found");
3132
3345
  return;
@@ -3252,16 +3465,27 @@ function registerCommitCommands(program2) {
3252
3465
  const linkedProject = await projectService.getLinkedProject(cwd);
3253
3466
  if (!linkedProject) {
3254
3467
  if (options.json) {
3255
- console.error(JSON.stringify({ error: "Not linked to a project", code: "NOT_LINKED" }));
3468
+ console.error(
3469
+ JSON.stringify({
3470
+ error: "Not linked to a project",
3471
+ code: "NOT_LINKED"
3472
+ })
3473
+ );
3256
3474
  process6.exit(1);
3257
3475
  }
3258
3476
  if (spinner) spinner.fail("Not linked");
3259
- console.log(chalk9.yellow("\n\u26A0 This directory is not linked to any project."));
3260
- console.log(chalk9.gray('Run "stint link" first to link this directory.\n'));
3477
+ console.log(
3478
+ chalk9.yellow("\n\u26A0 This directory is not linked to any project.")
3479
+ );
3480
+ console.log(
3481
+ chalk9.gray('Run "stint link" first to link this directory.\n')
3482
+ );
3261
3483
  process6.exit(1);
3262
3484
  }
3263
3485
  if (spinner) spinner.text = "Fetching pending commits...";
3264
- const commits = await apiService.getPendingCommits(linkedProject.projectId);
3486
+ const commits = await apiService.getPendingCommits(
3487
+ linkedProject.projectId
3488
+ );
3265
3489
  if (options.json) {
3266
3490
  logger.disableConsole();
3267
3491
  console.log(JSON.stringify(commits, null, 2));
@@ -3280,170 +3504,227 @@ function registerCommitCommands(program2) {
3280
3504
  const shortId = commit.id.substring(0, 7);
3281
3505
  const date = new Date(commit.createdAt);
3282
3506
  const timeAgo = getTimeAgo(date);
3283
- console.log(` ${chalk9.cyan(shortId)} ${commit.message.padEnd(40)} ${chalk9.gray(timeAgo)}`);
3507
+ console.log(
3508
+ ` ${chalk9.cyan(shortId)} ${commit.message.padEnd(40)} ${chalk9.gray(timeAgo)}`
3509
+ );
3284
3510
  if (commit.files && commit.files.length > 0) {
3285
- console.log(chalk9.gray(` Files: ${commit.files.join(", ")}`));
3511
+ console.log(
3512
+ chalk9.gray(` Files: ${commit.files.join(", ")}`)
3513
+ );
3286
3514
  }
3287
3515
  });
3288
- console.log(chalk9.gray('\nRun "stint commit <id>" to execute a specific commit.\n'));
3516
+ console.log(
3517
+ chalk9.gray(
3518
+ '\nRun "stint commit <id>" to execute a specific commit.\n'
3519
+ )
3520
+ );
3289
3521
  logger.info("commits", `Listed ${commits.length} pending commits`);
3290
3522
  } catch (error) {
3291
3523
  if (spinner) spinner.fail("Failed to fetch commits");
3292
- else if (options.json) console.error(JSON.stringify({ error: error.message }));
3524
+ else if (options.json)
3525
+ console.error(JSON.stringify({ error: error.message }));
3293
3526
  logger.error("commits", "Failed to fetch commits", error);
3294
- if (!options.json) console.error(chalk9.red(`
3527
+ if (!options.json)
3528
+ console.error(chalk9.red(`
3295
3529
  \u2716 Error: ${error.message}
3296
3530
  `));
3297
3531
  process6.exit(1);
3298
3532
  }
3299
3533
  });
3300
- 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) => {
3301
- let activeSpinner = null;
3302
- try {
3303
- activeSpinner = ora9("Checking repository status...").start();
3304
- const cwd = process6.cwd();
3305
- const linkedProject = await projectService.getLinkedProject(cwd);
3306
- if (!linkedProject) {
3307
- activeSpinner.fail("Not linked");
3308
- console.log(chalk9.yellow("\n\u26A0 This directory is not linked to any project."));
3309
- console.log(chalk9.gray('Run "stint link" first to link this directory.\n'));
3310
- process6.exit(1);
3311
- }
3312
- activeSpinner.text = "Fetching commit details...";
3313
- const commits = await apiService.getPendingCommits(linkedProject.projectId);
3314
- const matchingCommits = commits.filter((c) => c.id.startsWith(id));
3315
- if (matchingCommits.length === 0) {
3316
- activeSpinner.fail("Commit not found");
3317
- console.log(chalk9.red(`
3534
+ program2.command("commit <id>").description("Execute a specific pending commit").option(
3535
+ "--auto-stage",
3536
+ "Automatically stage files specified in the pending commit"
3537
+ ).option("--push", "Push changes to remote after committing").option("--force", "Skip file validation warnings").action(
3538
+ async (id, options) => {
3539
+ let activeSpinner = null;
3540
+ try {
3541
+ activeSpinner = ora9("Checking repository status...").start();
3542
+ const cwd = process6.cwd();
3543
+ const linkedProject = await projectService.getLinkedProject(cwd);
3544
+ if (!linkedProject) {
3545
+ activeSpinner.fail("Not linked");
3546
+ console.log(
3547
+ chalk9.yellow("\n\u26A0 This directory is not linked to any project.")
3548
+ );
3549
+ console.log(
3550
+ chalk9.gray('Run "stint link" first to link this directory.\n')
3551
+ );
3552
+ process6.exit(1);
3553
+ }
3554
+ activeSpinner.text = "Fetching commit details...";
3555
+ const commits = await apiService.getPendingCommits(
3556
+ linkedProject.projectId
3557
+ );
3558
+ const matchingCommits = commits.filter((c) => c.id.startsWith(id));
3559
+ if (matchingCommits.length === 0) {
3560
+ activeSpinner.fail("Commit not found");
3561
+ console.log(
3562
+ chalk9.red(`
3318
3563
  \u2716 Commit ${id} not found in pending commits.
3319
- `));
3320
- console.log(chalk9.gray('Run "stint commits" to see available commits.\n'));
3321
- process6.exit(1);
3322
- }
3323
- if (matchingCommits.length > 1) {
3324
- activeSpinner.fail("Ambiguous commit ID");
3325
- console.log(chalk9.yellow(`
3564
+ `)
3565
+ );
3566
+ console.log(
3567
+ chalk9.gray('Run "stint commits" to see available commits.\n')
3568
+ );
3569
+ process6.exit(1);
3570
+ }
3571
+ if (matchingCommits.length > 1) {
3572
+ activeSpinner.fail("Ambiguous commit ID");
3573
+ console.log(chalk9.yellow(`
3326
3574
  \u26A0 Multiple commits match "${id}":
3327
3575
  `));
3328
- matchingCommits.forEach((c) => {
3329
- const shortId = c.id.substring(0, 12);
3330
- console.log(` ${chalk9.cyan(shortId)} ${c.message}`);
3331
- });
3332
- console.log(chalk9.gray("\nPlease use a longer ID to be more specific.\n"));
3333
- process6.exit(1);
3334
- }
3335
- const commit = matchingCommits[0];
3336
- let status = await gitService.getStatus(cwd);
3337
- if (options.autoStage) {
3338
- if (commit.files && commit.files.length > 0) {
3339
- activeSpinner.text = `Staging ${commit.files.length} files...`;
3340
- await gitService.stageFiles(cwd, commit.files);
3341
- logger.info("commit", `Auto-staged files: ${commit.files.join(", ")}`);
3342
- } else {
3343
- activeSpinner.text = "Staging all changes...";
3344
- await gitService.stageAll(cwd);
3345
- logger.info("commit", "Auto-staged all changes");
3346
- }
3347
- status = await gitService.getStatus(cwd);
3348
- }
3349
- if (status.staged.length === 0) {
3350
- activeSpinner.fail("No staged changes");
3351
- console.log(chalk9.yellow("\n\u26A0 No staged changes detected."));
3352
- if (commit.files && commit.files.length > 0) {
3353
- console.log(chalk9.gray("Expected files: " + commit.files.join(", ")));
3354
- console.log(chalk9.gray("\nUse --auto-stage to automatically stage expected files."));
3355
- } else {
3356
- console.log(chalk9.gray("Use --auto-stage to automatically stage all changes, or stage files manually:"));
3357
- console.log(chalk9.gray(" git add <files>\n"));
3576
+ matchingCommits.forEach((c) => {
3577
+ const shortId = c.id.substring(0, 12);
3578
+ console.log(` ${chalk9.cyan(shortId)} ${c.message}`);
3579
+ });
3580
+ console.log(
3581
+ chalk9.gray("\nPlease use a longer ID to be more specific.\n")
3582
+ );
3583
+ process6.exit(1);
3358
3584
  }
3359
- process6.exit(1);
3360
- }
3361
- if (commit.files && commit.files.length > 0 && !options.force && !options.autoStage) {
3362
- const stagedSet = new Set(status.staged);
3363
- const expectedSet = new Set(commit.files);
3364
- const missing = commit.files.filter((f) => !stagedSet.has(f));
3365
- const extra = status.staged.filter((f) => !expectedSet.has(f));
3366
- if (missing.length > 0 || extra.length > 0) {
3367
- activeSpinner.stop();
3368
- console.log(chalk9.yellow("\n\u26A0 Staged files do not match expected files:\n"));
3369
- if (missing.length > 0) {
3370
- console.log(chalk9.red(" Missing (expected but not staged):"));
3371
- missing.forEach((f) => console.log(chalk9.red(` - ${f}`)));
3585
+ const commit = matchingCommits[0];
3586
+ let status = await gitService.getStatus(cwd);
3587
+ if (options.autoStage) {
3588
+ if (commit.files && commit.files.length > 0) {
3589
+ activeSpinner.text = `Staging ${commit.files.length} files...`;
3590
+ await gitService.stageFiles(cwd, commit.files);
3591
+ logger.info(
3592
+ "commit",
3593
+ `Auto-staged files: ${commit.files.join(", ")}`
3594
+ );
3595
+ } else {
3596
+ activeSpinner.text = "Staging all changes...";
3597
+ await gitService.stageAll(cwd);
3598
+ logger.info("commit", "Auto-staged all changes");
3372
3599
  }
3373
- if (extra.length > 0) {
3374
- console.log(chalk9.yellow("\n Extra (staged but not expected):"));
3375
- extra.forEach((f) => console.log(chalk9.yellow(` + ${f}`)));
3600
+ status = await gitService.getStatus(cwd);
3601
+ }
3602
+ if (status.staged.length === 0) {
3603
+ activeSpinner.fail("No staged changes");
3604
+ console.log(chalk9.yellow("\n\u26A0 No staged changes detected."));
3605
+ if (commit.files && commit.files.length > 0) {
3606
+ console.log(
3607
+ chalk9.gray("Expected files: " + commit.files.join(", "))
3608
+ );
3609
+ console.log(
3610
+ chalk9.gray(
3611
+ "\nUse --auto-stage to automatically stage expected files."
3612
+ )
3613
+ );
3614
+ } else {
3615
+ console.log(
3616
+ chalk9.gray(
3617
+ "Use --auto-stage to automatically stage all changes, or stage files manually:"
3618
+ )
3619
+ );
3620
+ console.log(chalk9.gray(" git add <files>\n"));
3376
3621
  }
3377
- console.log();
3378
- const proceed = await confirm2({
3379
- message: "Do you want to proceed anyway?",
3380
- default: false
3381
- });
3382
- if (!proceed) {
3383
- console.log(chalk9.gray("\nCommit cancelled. Use --auto-stage to stage expected files.\n"));
3384
- return;
3622
+ process6.exit(1);
3623
+ }
3624
+ if (commit.files && commit.files.length > 0 && !options.force && !options.autoStage) {
3625
+ const stagedSet = new Set(status.staged);
3626
+ const expectedSet = new Set(commit.files);
3627
+ const missing = commit.files.filter((f) => !stagedSet.has(f));
3628
+ const extra = status.staged.filter((f) => !expectedSet.has(f));
3629
+ if (missing.length > 0 || extra.length > 0) {
3630
+ activeSpinner.stop();
3631
+ console.log(
3632
+ chalk9.yellow("\n\u26A0 Staged files do not match expected files:\n")
3633
+ );
3634
+ if (missing.length > 0) {
3635
+ console.log(chalk9.red(" Missing (expected but not staged):"));
3636
+ missing.forEach((f) => console.log(chalk9.red(` - ${f}`)));
3637
+ }
3638
+ if (extra.length > 0) {
3639
+ console.log(
3640
+ chalk9.yellow("\n Extra (staged but not expected):")
3641
+ );
3642
+ extra.forEach((f) => console.log(chalk9.yellow(` + ${f}`)));
3643
+ }
3644
+ console.log();
3645
+ const proceed = await confirm2({
3646
+ message: "Do you want to proceed anyway?",
3647
+ default: false
3648
+ });
3649
+ if (!proceed) {
3650
+ console.log(
3651
+ chalk9.gray(
3652
+ "\nCommit cancelled. Use --auto-stage to stage expected files.\n"
3653
+ )
3654
+ );
3655
+ return;
3656
+ }
3657
+ activeSpinner = ora9("Continuing...").start();
3385
3658
  }
3386
- activeSpinner = ora9("Continuing...").start();
3387
3659
  }
3388
- }
3389
- activeSpinner.stop();
3390
- console.log(chalk9.blue("\n\u{1F4CB} Staged changes to commit:"));
3391
- console.log(chalk9.gray("\u2500".repeat(40)));
3392
- status.staged.forEach((file) => {
3393
- console.log(chalk9.green(` + ${file}`));
3394
- });
3395
- console.log();
3396
- console.log(`${chalk9.bold("Message:")} ${commit.message}`);
3397
- if (options.push) {
3398
- console.log(`${chalk9.bold("Push:")} ${chalk9.cyan("Yes (will push after commit)")}`);
3399
- }
3400
- console.log();
3401
- const confirmed = await confirm2({
3402
- message: "Are you sure you want to commit these changes?",
3403
- default: true
3404
- });
3405
- if (!confirmed) {
3406
- console.log(chalk9.yellow("\nCommit cancelled.\n"));
3407
- return;
3408
- }
3409
- activeSpinner = ora9("Preparing commit...").start();
3410
- const project = {
3411
- id: linkedProject.projectId,
3412
- name: "Current Project",
3413
- createdAt: "",
3414
- updatedAt: ""
3415
- };
3416
- const sha = await commitQueue.executeCommit(commit, project, (stage) => {
3417
- if (activeSpinner) activeSpinner.text = stage;
3418
- }, { push: options.push ?? false });
3419
- activeSpinner.succeed("Commit executed successfully!");
3420
- console.log(chalk9.green("\n\u2713 Commit executed"));
3421
- console.log(chalk9.gray("\u2500".repeat(50)));
3422
- console.log(`${chalk9.bold("Commit ID:")} ${commit.id}`);
3423
- console.log(`${chalk9.bold("Message:")} ${commit.message}`);
3424
- console.log(`${chalk9.bold("SHA:")} ${sha}`);
3425
- console.log(`${chalk9.bold("Files:")} ${status.staged.length} files committed`);
3426
- if (options.push) {
3427
- console.log(`${chalk9.bold("Pushed:")} ${chalk9.green("Yes")}`);
3428
- }
3429
- console.log();
3430
- if (status.staged.length > 0) {
3431
- console.log(chalk9.gray("Committed files:"));
3660
+ activeSpinner.stop();
3661
+ console.log(chalk9.blue("\n\u{1F4CB} Staged changes to commit:"));
3662
+ console.log(chalk9.gray("\u2500".repeat(40)));
3432
3663
  status.staged.forEach((file) => {
3433
3664
  console.log(chalk9.green(` + ${file}`));
3434
3665
  });
3435
3666
  console.log();
3436
- }
3437
- logger.success("commit", `Executed commit ${commit.id} -> ${sha}`);
3438
- } catch (error) {
3439
- activeSpinner?.fail("Commit execution failed");
3440
- logger.error("commit", "Failed to execute commit", error);
3441
- console.error(chalk9.red(`
3667
+ console.log(`${chalk9.bold("Message:")} ${commit.message}`);
3668
+ if (options.push) {
3669
+ console.log(
3670
+ `${chalk9.bold("Push:")} ${chalk9.cyan("Yes (will push after commit)")}`
3671
+ );
3672
+ }
3673
+ console.log();
3674
+ const confirmed = await confirm2({
3675
+ message: "Are you sure you want to commit these changes?",
3676
+ default: true
3677
+ });
3678
+ if (!confirmed) {
3679
+ console.log(chalk9.yellow("\nCommit cancelled.\n"));
3680
+ return;
3681
+ }
3682
+ activeSpinner = ora9("Preparing commit...").start();
3683
+ const project = {
3684
+ id: linkedProject.projectId,
3685
+ name: "Current Project",
3686
+ createdAt: "",
3687
+ updatedAt: ""
3688
+ };
3689
+ const sha = await commitQueue.executeCommit(
3690
+ commit,
3691
+ project,
3692
+ (stage) => {
3693
+ if (activeSpinner) activeSpinner.text = stage;
3694
+ },
3695
+ { push: options.push ?? false }
3696
+ );
3697
+ activeSpinner.succeed("Commit executed successfully!");
3698
+ console.log(chalk9.green("\n\u2713 Commit executed"));
3699
+ console.log(chalk9.gray("\u2500".repeat(50)));
3700
+ console.log(`${chalk9.bold("Commit ID:")} ${commit.id}`);
3701
+ console.log(`${chalk9.bold("Message:")} ${commit.message}`);
3702
+ console.log(`${chalk9.bold("SHA:")} ${sha}`);
3703
+ console.log(
3704
+ `${chalk9.bold("Files:")} ${status.staged.length} files committed`
3705
+ );
3706
+ if (options.push) {
3707
+ console.log(`${chalk9.bold("Pushed:")} ${chalk9.green("Yes")}`);
3708
+ }
3709
+ console.log();
3710
+ if (status.staged.length > 0) {
3711
+ console.log(chalk9.gray("Committed files:"));
3712
+ status.staged.forEach((file) => {
3713
+ console.log(chalk9.green(` + ${file}`));
3714
+ });
3715
+ console.log();
3716
+ }
3717
+ logger.success("commit", `Executed commit ${commit.id} -> ${sha}`);
3718
+ } catch (error) {
3719
+ activeSpinner?.fail("Commit execution failed");
3720
+ logger.error("commit", "Failed to execute commit", error);
3721
+ console.error(chalk9.red(`
3442
3722
  \u2716 Error: ${error.message}
3443
3723
  `));
3444
- process6.exit(1);
3724
+ process6.exit(1);
3725
+ }
3445
3726
  }
3446
- });
3727
+ );
3447
3728
  }
3448
3729
  function getTimeAgo(date) {
3449
3730
  const now = /* @__PURE__ */ new Date();
@@ -3475,10 +3756,14 @@ async function installWindows() {
3475
3756
  const command = getDaemonCommand();
3476
3757
  const escapedCommand = command.replace(/"/g, '\\"');
3477
3758
  try {
3478
- await execAsync(`schtasks /Create /SC ONLOGON /TN "${WINDOWS_TASK_NAME}" /TR "${escapedCommand}" /F`);
3759
+ await execAsync(
3760
+ `schtasks /Create /SC ONLOGON /TN "${WINDOWS_TASK_NAME}" /TR "${escapedCommand}" /F`
3761
+ );
3479
3762
  } catch (error) {
3480
3763
  if (error.message.includes("Access is denied")) {
3481
- throw new Error("Access denied. Please run this command as Administrator (Right-click Terminal > Run as administrator).");
3764
+ throw new Error(
3765
+ "Access denied. Please run this command as Administrator (Right-click Terminal > Run as administrator)."
3766
+ );
3482
3767
  }
3483
3768
  throw error;
3484
3769
  }
@@ -3488,8 +3773,20 @@ async function uninstallWindows() {
3488
3773
  }
3489
3774
  function getMacPlistContent() {
3490
3775
  const scriptPath = process.argv[1];
3491
- const logPath = path4.join(os4.homedir(), ".config", "stint", "logs", "launchd.log");
3492
- const errorPath = path4.join(os4.homedir(), ".config", "stint", "logs", "launchd.error.log");
3776
+ const logPath = path4.join(
3777
+ os4.homedir(),
3778
+ ".config",
3779
+ "stint",
3780
+ "logs",
3781
+ "launchd.log"
3782
+ );
3783
+ const errorPath = path4.join(
3784
+ os4.homedir(),
3785
+ ".config",
3786
+ "stint",
3787
+ "logs",
3788
+ "launchd.error.log"
3789
+ );
3493
3790
  const logDir = path4.dirname(logPath);
3494
3791
  if (!fs2.existsSync(logDir)) {
3495
3792
  fs2.mkdirSync(logDir, { recursive: true });
@@ -3595,7 +3892,11 @@ function registerInstallCommand(program2) {
3595
3892
  const user = await authService.validateToken();
3596
3893
  if (!user) {
3597
3894
  spinner.fail("Not authenticated");
3598
- console.log(chalk10.red("\n\u2716 You must be logged in to install the background agent on startup."));
3895
+ console.log(
3896
+ chalk10.red(
3897
+ "\n\u2716 You must be logged in to install the background agent on startup."
3898
+ )
3899
+ );
3599
3900
  console.log(chalk10.gray('Run "stint login" first.\n'));
3600
3901
  process.exit(1);
3601
3902
  }
@@ -3611,14 +3912,24 @@ function registerInstallCommand(program2) {
3611
3912
  throw new Error(`Unsupported platform: ${platform}`);
3612
3913
  }
3613
3914
  spinner.succeed("Installed successfully!");
3614
- console.log(chalk10.green(`
3615
- \u2713 Stint agent configured to start on login`));
3915
+ console.log(
3916
+ chalk10.green(`
3917
+ \u2713 Stint agent configured to start on login`)
3918
+ );
3616
3919
  if (platform === "win32") {
3617
- console.log(chalk10.gray(`Registered Task Scheduler task: ${WINDOWS_TASK_NAME}`));
3920
+ console.log(
3921
+ chalk10.gray(`Registered Task Scheduler task: ${WINDOWS_TASK_NAME}`)
3922
+ );
3618
3923
  } else if (platform === "darwin") {
3619
- console.log(chalk10.gray(`Created LaunchAgent: ~/Library/LaunchAgents/${MAC_PLIST_NAME}`));
3924
+ console.log(
3925
+ chalk10.gray(
3926
+ `Created LaunchAgent: ~/Library/LaunchAgents/${MAC_PLIST_NAME}`
3927
+ )
3928
+ );
3620
3929
  } else if (platform === "linux") {
3621
- console.log(chalk10.gray(`Created systemd user service: ${SYSTEMD_SERVICE_NAME}`));
3930
+ console.log(
3931
+ chalk10.gray(`Created systemd user service: ${SYSTEMD_SERVICE_NAME}`)
3932
+ );
3622
3933
  }
3623
3934
  console.log();
3624
3935
  logger.success("install", `Agent installed on startup for ${platform}`);
@@ -3648,7 +3959,10 @@ function registerUninstallCommand(program2) {
3648
3959
  }
3649
3960
  spinner.succeed("Uninstalled successfully");
3650
3961
  console.log(chalk10.gray("\nStint agent removed from system startup.\n"));
3651
- logger.success("install", `Agent uninstalled from startup for ${platform}`);
3962
+ logger.success(
3963
+ "install",
3964
+ `Agent uninstalled from startup for ${platform}`
3965
+ );
3652
3966
  } catch (error) {
3653
3967
  spinner.fail("Uninstall failed");
3654
3968
  logger.error("install", "Uninstall command failed", error);
@@ -3671,7 +3985,12 @@ import path5 from "path";
3671
3985
  import os5 from "os";
3672
3986
  import { fileURLToPath as fileURLToPath2 } from "url";
3673
3987
  var CACHE_TTL = 60 * 60 * 1e3;
3674
- var CACHE_FILE = path5.join(os5.homedir(), ".config", "stint", "version-cache.json");
3988
+ var CACHE_FILE = path5.join(
3989
+ os5.homedir(),
3990
+ ".config",
3991
+ "stint",
3992
+ "version-cache.json"
3993
+ );
3675
3994
  var PACKAGE_NAME = "@gowelle/stint-agent";
3676
3995
  var VersionService = class {
3677
3996
  currentVersion;
@@ -3702,7 +4021,10 @@ var VersionService = class {
3702
4021
  throw new Error(`Invalid current version: ${this.currentVersion}`);
3703
4022
  }
3704
4023
  const hasUpdate = import_semver.default.gt(latestVersion, this.currentVersion);
3705
- logger.info("version", `Current: ${this.currentVersion}, Latest (${channel}): ${latestVersion}, Update available: ${hasUpdate}`);
4024
+ logger.info(
4025
+ "version",
4026
+ `Current: ${this.currentVersion}, Latest (${channel}): ${latestVersion}, Update available: ${hasUpdate}`
4027
+ );
3706
4028
  return {
3707
4029
  current: this.currentVersion,
3708
4030
  latest: latestVersion,
@@ -3736,7 +4058,9 @@ var VersionService = class {
3736
4058
  logger.debug("version", "Fetching fresh registry data");
3737
4059
  const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`);
3738
4060
  if (!response.ok) {
3739
- throw new Error(`Failed to fetch registry data: ${response.status} ${response.statusText}`);
4061
+ throw new Error(
4062
+ `Failed to fetch registry data: ${response.status} ${response.statusText}`
4063
+ );
3740
4064
  }
3741
4065
  const data = await response.json();
3742
4066
  this.saveCache(data);
@@ -3884,7 +4208,10 @@ var UpdateService = class {
3884
4208
  attempts++;
3885
4209
  }
3886
4210
  if (isProcessRunning(pid)) {
3887
- logger.warn("update", "Daemon did not stop gracefully, forcing shutdown");
4211
+ logger.warn(
4212
+ "update",
4213
+ "Daemon did not stop gracefully, forcing shutdown"
4214
+ );
3888
4215
  killProcess(pid, "SIGKILL");
3889
4216
  await new Promise((resolve) => setTimeout(resolve, 500));
3890
4217
  }
@@ -3906,7 +4233,9 @@ var UpdateService = class {
3906
4233
  } catch (error) {
3907
4234
  logger.error("update", "Failed to restart daemon", error);
3908
4235
  console.log(chalk11.yellow("\n\u26A0 Failed to restart daemon automatically."));
3909
- console.log(chalk11.gray('Run "stint daemon start" to start it manually.\n'));
4236
+ console.log(
4237
+ chalk11.gray('Run "stint daemon start" to start it manually.\n')
4238
+ );
3910
4239
  }
3911
4240
  }
3912
4241
  };
@@ -3924,16 +4253,26 @@ function registerUpdateCommand(program2) {
3924
4253
  console.log(chalk12.blue("\n\u{1F4E6} Version Information:"));
3925
4254
  console.log(chalk12.gray("\u2500".repeat(50)));
3926
4255
  console.log(`${chalk12.bold("Current:")} ${versionInfo.current}`);
3927
- console.log(`${chalk12.bold("Latest:")} ${versionInfo.latest} (${channel})`);
4256
+ console.log(
4257
+ `${chalk12.bold("Latest:")} ${versionInfo.latest} (${channel})`
4258
+ );
3928
4259
  console.log();
3929
4260
  if (!versionInfo.hasUpdate) {
3930
- console.log(chalk12.green("\u2713 You are already on the latest version!\n"));
4261
+ console.log(
4262
+ chalk12.green("\u2713 You are already on the latest version!\n")
4263
+ );
3931
4264
  return;
3932
4265
  }
3933
- console.log(chalk12.yellow(`\u26A0 Update available: ${versionInfo.current} \u2192 ${versionInfo.latest}
3934
- `));
4266
+ console.log(
4267
+ chalk12.yellow(
4268
+ `\u26A0 Update available: ${versionInfo.current} \u2192 ${versionInfo.latest}
4269
+ `
4270
+ )
4271
+ );
3935
4272
  if (options.check) {
3936
- console.log(chalk12.gray('Run "stint update" to install the latest version.\n'));
4273
+ console.log(
4274
+ chalk12.gray('Run "stint update" to install the latest version.\n')
4275
+ );
3937
4276
  return;
3938
4277
  }
3939
4278
  if (!options.yes) {
@@ -3951,9 +4290,11 @@ function registerUpdateCommand(program2) {
3951
4290
  console.log();
3952
4291
  const result = await updateService.performUpdate(channel);
3953
4292
  if (result.success) {
3954
- console.log(chalk12.green(`
4293
+ console.log(
4294
+ chalk12.green(`
3955
4295
  \u2713 Successfully updated to ${versionInfo.latest}!
3956
- `));
4296
+ `)
4297
+ );
3957
4298
  logger.success("update", `Updated to ${versionInfo.latest}`);
3958
4299
  } else {
3959
4300
  console.log(chalk12.red(`
@@ -4100,8 +4441,12 @@ function registerDoctorCommand(program2) {
4100
4441
  name: "Git Configuration",
4101
4442
  check: async () => {
4102
4443
  try {
4103
- const { stdout: userName } = await execAsync2("git config --global user.name");
4104
- const { stdout: userEmail } = await execAsync2("git config --global user.email");
4444
+ const { stdout: userName } = await execAsync2(
4445
+ "git config --global user.name"
4446
+ );
4447
+ const { stdout: userEmail } = await execAsync2(
4448
+ "git config --global user.email"
4449
+ );
4105
4450
  if (!userName.trim() || !userEmail.trim()) {
4106
4451
  return {
4107
4452
  success: false,
@@ -4214,10 +4559,14 @@ function registerDoctorCommand(program2) {
4214
4559
  try {
4215
4560
  const result = await check.check();
4216
4561
  if (result.success) {
4217
- console.log(`${chalk13.green("\u2713")} ${chalk13.bold(check.name)}: ${result.message}`);
4562
+ console.log(
4563
+ `${chalk13.green("\u2713")} ${chalk13.bold(check.name)}: ${result.message}`
4564
+ );
4218
4565
  } else {
4219
4566
  hasErrors = true;
4220
- console.log(`${chalk13.red("\u2716")} ${chalk13.bold(check.name)}: ${result.message}`);
4567
+ console.log(
4568
+ `${chalk13.red("\u2716")} ${chalk13.bold(check.name)}: ${result.message}`
4569
+ );
4221
4570
  if (result.details) {
4222
4571
  result.details.forEach((detail) => {
4223
4572
  console.log(chalk13.gray(` ${detail}`));
@@ -4226,16 +4575,24 @@ function registerDoctorCommand(program2) {
4226
4575
  }
4227
4576
  } catch (error) {
4228
4577
  hasErrors = true;
4229
- console.log(`${chalk13.red("\u2716")} ${chalk13.bold(check.name)}: Check failed - ${error.message}`);
4578
+ console.log(
4579
+ `${chalk13.red("\u2716")} ${chalk13.bold(check.name)}: Check failed - ${error.message}`
4580
+ );
4230
4581
  }
4231
4582
  }
4232
4583
  spinner.stop();
4233
4584
  console.log();
4234
4585
  if (hasErrors) {
4235
- console.log(chalk13.yellow("Some checks failed. Please address the issues above."));
4586
+ console.log(
4587
+ chalk13.yellow(
4588
+ "Some checks failed. Please address the issues above."
4589
+ )
4590
+ );
4236
4591
  process7.exit(1);
4237
4592
  } else {
4238
- console.log(chalk13.green("All checks passed! Your environment is healthy."));
4593
+ console.log(
4594
+ chalk13.green("All checks passed! Your environment is healthy.")
4595
+ );
4239
4596
  }
4240
4597
  } catch (error) {
4241
4598
  spinner.fail("Diagnostics failed");
@@ -4256,7 +4613,10 @@ var ALLOWED_KEYS = [
4256
4613
  "apiUrl",
4257
4614
  "wsUrl",
4258
4615
  "reverbAppKey",
4259
- "notifications.enabled"
4616
+ "notifications.enabled",
4617
+ "notifications.commits",
4618
+ "notifications.sync",
4619
+ "notifications.suggestions"
4260
4620
  ];
4261
4621
  var SENSITIVE_KEYS = ["token"];
4262
4622
  function isAllowedKey(key) {
@@ -4311,11 +4671,16 @@ function registerConfigCommand(program2) {
4311
4671
  if (isSensitiveKey(key)) {
4312
4672
  console.log(chalk14.yellow(`
4313
4673
  \u26A0 Cannot read sensitive key "${key}"`));
4314
- console.log(chalk14.gray('Use "stint whoami" to check authentication status.\n'));
4674
+ console.log(
4675
+ chalk14.gray('Use "stint whoami" to check authentication status.\n')
4676
+ );
4315
4677
  return;
4316
4678
  }
4317
4679
  const allConfig = config.getAll();
4318
- const value = getNestedValue(allConfig, key);
4680
+ const value = getNestedValue(
4681
+ allConfig,
4682
+ key
4683
+ );
4319
4684
  if (value === void 0) {
4320
4685
  console.log(chalk14.yellow(`
4321
4686
  \u26A0 Key "${key}" is not set.
@@ -4362,13 +4727,21 @@ ${chalk14.bold(key)}: ${formatValue(value)}
4362
4727
  const allConfig = config.getAll();
4363
4728
  setNestedValue(allConfig, key, parsedValue);
4364
4729
  const topKey = key.split(".")[0];
4365
- config.set(topKey, allConfig[topKey]);
4730
+ config.set(
4731
+ topKey,
4732
+ allConfig[topKey]
4733
+ );
4366
4734
  } else {
4367
- config.set(key, parsedValue);
4735
+ config.set(
4736
+ key,
4737
+ parsedValue
4738
+ );
4368
4739
  }
4369
- console.log(chalk14.green(`
4740
+ console.log(
4741
+ chalk14.green(`
4370
4742
  \u2713 Set ${key} = ${formatValue(parsedValue)}
4371
- `));
4743
+ `)
4744
+ );
4372
4745
  logger.success("config", `Set config key: ${key} = ${value}`);
4373
4746
  } catch (error) {
4374
4747
  logger.error("config", "Failed to set config", error);
@@ -4383,14 +4756,23 @@ ${chalk14.bold(key)}: ${formatValue(value)}
4383
4756
  console.log(chalk14.bold("\n\u{1F4CB} Configuration:\n"));
4384
4757
  console.log(chalk14.gray("\u2500".repeat(50)));
4385
4758
  for (const key of ALLOWED_KEYS) {
4386
- const value = getNestedValue(allConfig, key);
4759
+ const value = getNestedValue(
4760
+ allConfig,
4761
+ key
4762
+ );
4387
4763
  console.log(`${chalk14.cyan(key.padEnd(25))} ${formatValue(value)}`);
4388
4764
  }
4389
4765
  console.log(chalk14.gray("\u2500".repeat(50)));
4390
- console.log(`${chalk14.cyan("token".padEnd(25))} ${chalk14.yellow("[REDACTED]")}`);
4766
+ console.log(
4767
+ `${chalk14.cyan("token".padEnd(25))} ${chalk14.yellow("[REDACTED]")}`
4768
+ );
4391
4769
  console.log(chalk14.gray("\u2500".repeat(50)));
4392
- console.log(`${chalk14.gray("machineId".padEnd(25))} ${chalk14.gray(allConfig.machineId)}`);
4393
- console.log(`${chalk14.gray("machineName".padEnd(25))} ${chalk14.gray(allConfig.machineName)}`);
4770
+ console.log(
4771
+ `${chalk14.gray("machineId".padEnd(25))} ${chalk14.gray(allConfig.machineId)}`
4772
+ );
4773
+ console.log(
4774
+ `${chalk14.gray("machineName".padEnd(25))} ${chalk14.gray(allConfig.machineName)}`
4775
+ );
4394
4776
  console.log();
4395
4777
  logger.debug("config", "Listed config");
4396
4778
  } catch (error) {
@@ -4402,16 +4784,22 @@ ${chalk14.bold(key)}: ${formatValue(value)}
4402
4784
  });
4403
4785
  configCmd.command("path").description("Show the configuration file path").action(() => {
4404
4786
  const configPath = getConfigPath();
4405
- console.log(`
4787
+ console.log(
4788
+ `
4406
4789
  ${chalk14.bold("Config file:")} ${chalk14.cyan(configPath)}
4407
- `);
4790
+ `
4791
+ );
4408
4792
  logger.debug("config", `Config path: ${configPath}`);
4409
4793
  });
4410
4794
  configCmd.command("reset").description("Reset configuration to defaults (keeps token)").option("--force", "Skip confirmation prompt").action(async (options) => {
4411
4795
  try {
4412
4796
  if (!options.force) {
4413
- console.log(chalk14.yellow("\n\u26A0 This will reset all configuration to defaults."));
4414
- console.log(chalk14.gray("Your authentication token will be preserved.\n"));
4797
+ console.log(
4798
+ chalk14.yellow("\n\u26A0 This will reset all configuration to defaults.")
4799
+ );
4800
+ console.log(
4801
+ chalk14.gray("Your authentication token will be preserved.\n")
4802
+ );
4415
4803
  const readline = await import("readline");
4416
4804
  const rl = readline.createInterface({
4417
4805
  input: process.stdin,
@@ -4428,12 +4816,19 @@ ${chalk14.bold("Config file:")} ${chalk14.cyan(configPath)}
4428
4816
  }
4429
4817
  const token = config.getToken();
4430
4818
  for (const key of ALLOWED_KEYS) {
4431
- if (key === "notifications.enabled") {
4432
- config.set("notifications", { enabled: true });
4819
+ if (key.startsWith("notifications.")) {
4820
+ config.set("notifications", {
4821
+ enabled: true,
4822
+ commits: true,
4823
+ sync: false,
4824
+ suggestions: true
4825
+ });
4433
4826
  } else {
4434
4827
  if (key === "apiUrl") config.set("apiUrl", "https://stint.codes");
4435
- if (key === "wsUrl") config.set("wsUrl", "wss://stint.codes/reverb");
4436
- if (key === "reverbAppKey") config.set("reverbAppKey", "wtn6tu6lirfv6yflujk7");
4828
+ if (key === "wsUrl")
4829
+ config.set("wsUrl", "wss://stint.codes/reverb");
4830
+ if (key === "reverbAppKey")
4831
+ config.set("reverbAppKey", "wtn6tu6lirfv6yflujk7");
4437
4832
  }
4438
4833
  }
4439
4834
  if (token) {
@@ -4451,9 +4846,11 @@ ${chalk14.bold("Config file:")} ${chalk14.cyan(configPath)}
4451
4846
  }
4452
4847
 
4453
4848
  // src/index.ts
4454
- var AGENT_VERSION = "1.2.35";
4849
+ var AGENT_VERSION = "1.2.36";
4455
4850
  var program = new Command();
4456
- program.name("stint").description("Stint Agent - Local daemon for Stint Project Assistant").version(AGENT_VERSION, "-v, --version", "output the current version").addHelpText("after", `
4851
+ program.name("stint").description("Stint Agent - Local daemon for Stint Project Assistant").version(AGENT_VERSION, "-v, --version", "output the current version").addHelpText(
4852
+ "after",
4853
+ `
4457
4854
  ${chalk15.bold("Examples:")}
4458
4855
  ${chalk15.cyan("$")} stint login ${chalk15.gray("# Authenticate with Stint")}
4459
4856
  ${chalk15.cyan("$")} stint install ${chalk15.gray("# Install agent to run on startup")}
@@ -4464,7 +4861,8 @@ ${chalk15.bold("Examples:")}
4464
4861
 
4465
4862
  ${chalk15.bold("Documentation:")}
4466
4863
  For more information, visit: ${chalk15.blue("https://stint.codes/docs")}
4467
- `);
4864
+ `
4865
+ );
4468
4866
  registerLoginCommand(program);
4469
4867
  registerLogoutCommand(program);
4470
4868
  registerWhoamiCommand(program);