devark-cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
- 52a46eee13d20a05fc798ac3e30f00685cf9475e3a56a48ede86461cd5d56ee1 index.js
2
- 6e948721c1e5bb7dd3e746c0e1e7a972cbd491b6f0135718178b22563ca56de9 index.js.map
1
+ df64dc39f16af067e894ac8145ecc1cd692b008f0863974d06e7424ae803f123 index.js
2
+ 2207035473e531a8eee7f5ffb2b3928f94c4768b0c6993cf31e09a60b7a26e28 index.js.map
3
3
  137b0f6da8ab3a82dd96e536c9de1c0162f51d5450895af16e935906975671a8 report-template.html
package/dist/index.js CHANGED
@@ -2481,7 +2481,7 @@ var require_package = __commonJS({
2481
2481
  "package.json"(exports2, module2) {
2482
2482
  module2.exports = {
2483
2483
  name: "devark-cli",
2484
- version: "0.1.0",
2484
+ version: "0.1.2",
2485
2485
  description: "DevArk - Developer Productivity CLI",
2486
2486
  bin: {
2487
2487
  devark: "./bin/devark.js"
@@ -3060,6 +3060,25 @@ var init_api_client = __esm({
3060
3060
  }
3061
3061
  return response.data;
3062
3062
  }
3063
+ /**
3064
+ * Get the timestamp of the user's most recent session for incremental sync.
3065
+ * @returns Last session timestamp (ISO string) and ID, or null if no sessions exist
3066
+ */
3067
+ async getLastSessionDate() {
3068
+ var _a;
3069
+ try {
3070
+ const response = await this.client.get("/api/sessions/last");
3071
+ return {
3072
+ lastSessionTimestamp: response.data.lastSessionTimestamp || null,
3073
+ lastSessionId: response.data.lastSessionId || null
3074
+ };
3075
+ } catch (error) {
3076
+ if (((_a = error.response) == null ? void 0 : _a.status) === 404) {
3077
+ return { lastSessionTimestamp: null, lastSessionId: null };
3078
+ }
3079
+ throw error;
3080
+ }
3081
+ }
3063
3082
  getBaseUrl() {
3064
3083
  return this.client.defaults.baseURL || "http://localhost:3000";
3065
3084
  }
@@ -4010,10 +4029,14 @@ var init_send_orchestrator = __esm({
4010
4029
  return this.readSelectedSessions(options.selectedSessions);
4011
4030
  }
4012
4031
  if (options.all) {
4013
- const sessions2 = await readClaudeSessions({ since: void 0 });
4032
+ const serverSince = await this.getServerLastSessionDate();
4033
+ if (serverSince) {
4034
+ logger.debug(`Using server timestamp for incremental sync: ${serverSince.toISOString()}`);
4035
+ }
4036
+ const sessions2 = await readClaudeSessions({ since: serverSince });
4014
4037
  return sessions2;
4015
4038
  }
4016
- const sinceDate = this.determineSinceDate(options);
4039
+ const sinceDate = await this.determineSinceDateWithServerFallback(options);
4017
4040
  if (options.claudeProjectDir && options.claudeProjectDir.trim() !== "") {
4018
4041
  return this.loadProjectSessions(options.claudeProjectDir, sinceDate);
4019
4042
  }
@@ -4036,6 +4059,34 @@ var init_send_orchestrator = __esm({
4036
4059
  }
4037
4060
  return void 0;
4038
4061
  }
4062
+ /**
4063
+ * Get the server's last session timestamp for incremental sync.
4064
+ * Returns undefined on error to allow fallback to local sync state.
4065
+ */
4066
+ async getServerLastSessionDate() {
4067
+ try {
4068
+ const result = await apiClient.getLastSessionDate();
4069
+ if (result.lastSessionTimestamp) {
4070
+ return new Date(result.lastSessionTimestamp);
4071
+ }
4072
+ return void 0;
4073
+ } catch (error) {
4074
+ logger.warn(`Failed to get server last session date, falling back to local sync: ${error instanceof Error ? error.message : "Unknown error"}`);
4075
+ return void 0;
4076
+ }
4077
+ }
4078
+ /**
4079
+ * Determine since date with server-side incremental sync fallback.
4080
+ * First tries server timestamp, then falls back to local sync state.
4081
+ */
4082
+ async determineSinceDateWithServerFallback(options) {
4083
+ const serverSince = await this.getServerLastSessionDate();
4084
+ if (serverSince) {
4085
+ logger.debug(`Using server timestamp for incremental sync: ${serverSince.toISOString()}`);
4086
+ return serverSince;
4087
+ }
4088
+ return this.determineSinceDate(options);
4089
+ }
4039
4090
  async loadProjectSessions(claudeProjectDir, sinceDate) {
4040
4091
  const dirName = parseProjectName(claudeProjectDir);
4041
4092
  const project = await analyzeProject(claudeProjectDir, dirName);
@@ -11422,6 +11473,20 @@ var manual_sync_menu_exports = {};
11422
11473
  __export(manual_sync_menu_exports, {
11423
11474
  showManualSyncMenu: () => showManualSyncMenu
11424
11475
  });
11476
+ async function getServerLastSessionDate() {
11477
+ try {
11478
+ if (!await isAuthenticated()) {
11479
+ return void 0;
11480
+ }
11481
+ const result = await apiClient.getLastSessionDate();
11482
+ if (result.lastSessionTimestamp) {
11483
+ return new Date(result.lastSessionTimestamp);
11484
+ }
11485
+ return void 0;
11486
+ } catch {
11487
+ return void 0;
11488
+ }
11489
+ }
11425
11490
  async function showManualSyncMenu() {
11426
11491
  console.log("");
11427
11492
  console.log(colors.primary("Manual sync to cloud"));
@@ -11562,22 +11627,39 @@ async function showManualSyncMenu() {
11562
11627
  }
11563
11628
  }
11564
11629
  case "all": {
11565
- const projects = await discoverProjects();
11566
- const totalSessions = projects.reduce((sum, p) => sum + p.sessions, 0);
11567
- console.log("");
11568
- console.log(colors.info(`This will sync ${totalSessions} sessions from ${projects.length} projects.`));
11569
- const { confirm } = await import_inquirer14.default.prompt([
11570
- {
11571
- type: "confirm",
11572
- name: "confirm",
11573
- message: "Continue with syncing all projects?",
11574
- default: true
11630
+ const spinner = createSpinner("Calculating sessions to sync...").start();
11631
+ try {
11632
+ const serverSince = await getServerLastSessionDate();
11633
+ const sessions = await readClaudeSessions({ since: serverSince });
11634
+ const validSessions = sessions.filter((s) => s.duration >= 240);
11635
+ const projectPaths = new Set(validSessions.map((s) => {
11636
+ var _a;
11637
+ return (_a = s.sourceFile) == null ? void 0 : _a.claudeProjectPath;
11638
+ }).filter(Boolean));
11639
+ spinner.stop();
11640
+ console.log("");
11641
+ if (serverSince) {
11642
+ console.log(colors.info(`This will sync ${validSessions.length} new sessions from ${projectPaths.size} projects`));
11643
+ console.log(colors.subdued(`(Sessions since ${serverSince.toLocaleDateString()})`));
11644
+ } else {
11645
+ console.log(colors.info(`This will sync ${validSessions.length} sessions from ${projectPaths.size} projects.`));
11575
11646
  }
11576
- ]);
11577
- if (!confirm) {
11647
+ const { confirm } = await import_inquirer14.default.prompt([
11648
+ {
11649
+ type: "confirm",
11650
+ name: "confirm",
11651
+ message: `Continue with syncing ${validSessions.length} sessions?`,
11652
+ default: true
11653
+ }
11654
+ ]);
11655
+ if (!confirm) {
11656
+ return { type: "cancel" };
11657
+ }
11658
+ return { type: "all" };
11659
+ } catch (error) {
11660
+ spinner.fail(colors.error("Failed to calculate sessions"));
11578
11661
  return { type: "cancel" };
11579
11662
  }
11580
- return { type: "all" };
11581
11663
  }
11582
11664
  default:
11583
11665
  return { type: "cancel" };
@@ -11595,6 +11677,8 @@ var init_manual_sync_menu = __esm({
11595
11677
  init_claude();
11596
11678
  init_project_display();
11597
11679
  init_ui();
11680
+ init_api_client();
11681
+ init_token();
11598
11682
  }
11599
11683
  });
11600
11684
 
@@ -15608,7 +15692,7 @@ function createSection(title, content, options) {
15608
15692
  lines.push(color(chars.bl + chars.h.repeat(width - 2) + chars.br));
15609
15693
  return lines.join("\n");
15610
15694
  }
15611
- function createCloudStatusSection(status2) {
15695
+ function createCloudStatusSection(status2, serverLastSessionDate) {
15612
15696
  const content = [];
15613
15697
  const connectionIcon = status2.connected ? icons.success : icons.error;
15614
15698
  const connectionColor = status2.connected ? colors.success : colors.error;
@@ -15636,12 +15720,13 @@ function createCloudStatusSection(status2) {
15636
15720
  let syncColor = colors.primary;
15637
15721
  let syncText = "Never synced";
15638
15722
  let syncProject = "";
15639
- if (status2.lastSync) {
15640
- const timeSince = (/* @__PURE__ */ new Date()).getTime() - status2.lastSync.getTime();
15723
+ const lastSyncDate = serverLastSessionDate || status2.lastSync;
15724
+ if (lastSyncDate) {
15725
+ const timeSince = (/* @__PURE__ */ new Date()).getTime() - lastSyncDate.getTime();
15641
15726
  const minutes = Math.floor(timeSince / 6e4);
15642
15727
  const hours = Math.floor(minutes / 60);
15643
15728
  const days = Math.floor(hours / 24);
15644
- if (status2.lastSyncProject) {
15729
+ if (!serverLastSessionDate && status2.lastSyncProject) {
15645
15730
  syncProject = `${status2.lastSyncProject} `;
15646
15731
  }
15647
15732
  if (days > 0) {
@@ -15722,9 +15807,9 @@ function createLocalEngineSection(engine) {
15722
15807
  color: sectionColor
15723
15808
  });
15724
15809
  }
15725
- async function createStatusDashboard(cloud, local) {
15810
+ async function createStatusDashboard(cloud, local, serverLastSessionDate) {
15726
15811
  const sections = [];
15727
- sections.push(createCloudStatusSection(cloud));
15812
+ sections.push(createCloudStatusSection(cloud, serverLastSessionDate));
15728
15813
  sections.push("");
15729
15814
  sections.push(createLocalEngineSection(local));
15730
15815
  return sections.join("\n");
@@ -16135,7 +16220,18 @@ async function showMainMenu(state, packageUpdateInfo2) {
16135
16220
  statusLineStatus: state.statusLineStatus,
16136
16221
  configPath: "~/.claude/config"
16137
16222
  };
16138
- console.log(await createStatusDashboard(cloudStatus, localEngine));
16223
+ let serverLastSessionDate;
16224
+ if (state.hasAuth) {
16225
+ try {
16226
+ const { apiClient: apiClient2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
16227
+ const result = await apiClient2.getLastSessionDate();
16228
+ if (result.lastSessionTimestamp) {
16229
+ serverLastSessionDate = new Date(result.lastSessionTimestamp);
16230
+ }
16231
+ } catch {
16232
+ }
16233
+ }
16234
+ console.log(await createStatusDashboard(cloudStatus, localEngine, serverLastSessionDate));
16139
16235
  console.log("");
16140
16236
  const context = {
16141
16237
  state: state.state,