crosssync 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -82,7 +82,8 @@ crosssync sync --json # 机器可读报告
82
82
  ```
83
83
 
84
84
  如果配置的 profile(默认 `Default`)在某个浏览器中不存在,交互式终端会列出可用的
85
- profile 让你按序号选择(支持多选),并自动保存选择。
85
+ profile 让你按序号选择(支持多选),并自动保存选择。列表会附带 `Local State` 中记录的
86
+ 本地名称和已登录账号(如 `Profile 11 Roe <roe@example.com>`),便于区分 profile。
86
87
 
87
88
  ### `crosssync profiles`
88
89
 
package/dist/index.js CHANGED
@@ -3036,7 +3036,7 @@ var require_constants = __commonJS({
3036
3036
  "../shared/dist/constants.js"(exports2) {
3037
3037
  "use strict";
3038
3038
  Object.defineProperty(exports2, "__esModule", { value: true });
3039
- exports2.DEFAULT_CRON_SCHEDULE = exports2.DEFAULT_EXPORT_RETENTION = exports2.CONFIG_VERSION = exports2.DEFAULT_LOG_LEVEL = exports2.DEFAULT_PROFILE = exports2.PROFILE_NAME_PATTERN = exports2.HISTORY_FILE_NAME = exports2.BOOKMARKS_FILE_NAME = exports2.LOG_FILE_NAME = exports2.CONFIG_FILE_NAME = exports2.LOG_DIR_NAME = exports2.EXPORT_DIR_NAME = exports2.BACKUP_DIR_NAME = exports2.CROSSSYNC_DIR_NAME = exports2.CHROMIUM_EPOCH_OFFSET_MS = exports2.BROWSERS = exports2.LOG_LEVELS = exports2.SHARED_VERSION = exports2.SHARED_PACKAGE = void 0;
3039
+ exports2.DEFAULT_CRON_SCHEDULE = exports2.DEFAULT_EXPORT_RETENTION = exports2.CONFIG_VERSION = exports2.DEFAULT_LOG_LEVEL = exports2.DEFAULT_PROFILE = exports2.PROFILE_NAME_PATTERN = exports2.LOCAL_STATE_FILE_NAME = exports2.HISTORY_FILE_NAME = exports2.BOOKMARKS_FILE_NAME = exports2.LOG_FILE_NAME = exports2.CONFIG_FILE_NAME = exports2.LOG_DIR_NAME = exports2.EXPORT_DIR_NAME = exports2.BACKUP_DIR_NAME = exports2.CROSSSYNC_DIR_NAME = exports2.CHROMIUM_EPOCH_OFFSET_MS = exports2.BROWSERS = exports2.LOG_LEVELS = exports2.SHARED_VERSION = exports2.SHARED_PACKAGE = void 0;
3040
3040
  exports2.SHARED_PACKAGE = "@crosssync/shared";
3041
3041
  exports2.SHARED_VERSION = "0.1.0";
3042
3042
  exports2.LOG_LEVELS = ["debug", "info", "warn", "error"];
@@ -3050,6 +3050,7 @@ var require_constants = __commonJS({
3050
3050
  exports2.LOG_FILE_NAME = "crosssync.log";
3051
3051
  exports2.BOOKMARKS_FILE_NAME = "Bookmarks";
3052
3052
  exports2.HISTORY_FILE_NAME = "History";
3053
+ exports2.LOCAL_STATE_FILE_NAME = "Local State";
3053
3054
  exports2.PROFILE_NAME_PATTERN = /^(Default|Profile \d+)$/;
3054
3055
  exports2.DEFAULT_PROFILE = "Default";
3055
3056
  exports2.DEFAULT_LOG_LEVEL = "info";
@@ -3809,11 +3810,40 @@ var require_chromium = __commonJS({
3809
3810
  return mod && mod.__esModule ? mod : { "default": mod };
3810
3811
  };
3811
3812
  Object.defineProperty(exports2, "__esModule", { value: true });
3813
+ exports2.readProfileInfos = readProfileInfos;
3812
3814
  exports2.toHistoryEntry = toHistoryEntry;
3813
3815
  exports2.countBookmarkFileNodes = countBookmarkFileNodes;
3814
3816
  exports2.createBrowserReader = createBrowserReader3;
3815
3817
  var path_1 = __importDefault(require("path"));
3816
3818
  var shared_1 = require_dist();
3819
+ function readProfileInfos(dataDir) {
3820
+ const localState = (0, shared_1.readJsonFile)(path_1.default.join(dataDir, shared_1.LOCAL_STATE_FILE_NAME));
3821
+ const cache = localState?.profile?.info_cache ?? {};
3822
+ return (0, shared_1.listProfiles)(dataDir).map((profile) => toProfileInfo(profile, cache[profile]));
3823
+ }
3824
+ function toProfileInfo(profile, raw) {
3825
+ const info = { profile };
3826
+ const name = readString(raw, "name");
3827
+ const userName = readString(raw, "user_name");
3828
+ const gaiaName = readString(raw, "gaia_name");
3829
+ if (name !== void 0) {
3830
+ info.name = name;
3831
+ }
3832
+ if (userName !== void 0) {
3833
+ info.userName = userName;
3834
+ }
3835
+ if (gaiaName !== void 0) {
3836
+ info.gaiaName = gaiaName;
3837
+ }
3838
+ if (typeof raw?.is_using_default_name === "boolean") {
3839
+ info.isUsingDefaultName = raw.is_using_default_name;
3840
+ }
3841
+ return info;
3842
+ }
3843
+ function readString(raw, key) {
3844
+ const value = raw?.[key];
3845
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
3846
+ }
3817
3847
  function toHistoryEntry(row) {
3818
3848
  return {
3819
3849
  id: typeof row.id === "number" ? row.id : void 0,
@@ -3839,6 +3869,8 @@ var require_chromium = __commonJS({
3839
3869
  const bookmarksPath = (profile) => path_1.default.join((0, shared_1.resolveProfileDir)(dataDir, profile), shared_1.BOOKMARKS_FILE_NAME);
3840
3870
  const historyPath = (profile) => path_1.default.join((0, shared_1.resolveProfileDir)(dataDir, profile), shared_1.HISTORY_FILE_NAME);
3841
3871
  const profiles = () => (0, shared_1.listProfiles)(dataDir);
3872
+ const profileInfos = () => readProfileInfos(dataDir);
3873
+ const profileInfo = (profile) => profileInfos().find((info) => info.profile === profile) ?? null;
3842
3874
  const resolveSelectedProfiles = (profile) => {
3843
3875
  const found = profiles();
3844
3876
  if (profile.trim() === "all") {
@@ -3868,6 +3900,8 @@ var require_chromium = __commonJS({
3868
3900
  browser,
3869
3901
  dataDir,
3870
3902
  profiles,
3903
+ profileInfos,
3904
+ profileInfo,
3871
3905
  resolveProfiles: resolveSelectedProfiles,
3872
3906
  bookmarksPath,
3873
3907
  historyPath,
@@ -4231,6 +4265,7 @@ var require_sync = __commonJS({
4231
4265
  const outcome = {
4232
4266
  browser: reader.browser,
4233
4267
  profile,
4268
+ profileInfo: reader.profileInfo(profile),
4234
4269
  bookmarksRead: 0,
4235
4270
  historyRead: 0,
4236
4271
  writtenBack: false,
@@ -4395,7 +4430,7 @@ var require_dist2 = __commonJS({
4395
4430
  "../core/dist/index.js"(exports2) {
4396
4431
  "use strict";
4397
4432
  Object.defineProperty(exports2, "__esModule", { value: true });
4398
- exports2.writeBackBookmarks = exports2.runSync = exports2.pruneBackups = exports2.listBackups = exports2.formatBackupId = exports2.createBackup = exports2.backupFileName = exports2.BACKUP_MANIFEST_FILE = exports2.mergeHistory = exports2.mergeBookmarkFiles = exports2.toHistoryEntry = exports2.supportedBrowsers = exports2.createConfiguredBrowserReaders = exports2.createBrowserReader = exports2.countBookmarkFileNodes = exports2.parseProcessOutput = exports2.isBrowserRunning = exports2.getRunningBrowsers = exports2.getRunningBrowserNames = exports2.getProcessName = exports2.buildProcessQuery = exports2.readLogEntries = exports2.clearLogFile = exports2.Logger = exports2.MAX_BUFFERED_LOG_ENTRIES = exports2.DEFAULT_LOG_LIMIT = exports2.DEFAULT_BACKUP_RETENTION = exports2.BROWSER_PROCESS_NAMES = exports2.VERSION = exports2.PACKAGE = void 0;
4433
+ exports2.writeBackBookmarks = exports2.runSync = exports2.pruneBackups = exports2.listBackups = exports2.formatBackupId = exports2.createBackup = exports2.backupFileName = exports2.BACKUP_MANIFEST_FILE = exports2.mergeHistory = exports2.mergeBookmarkFiles = exports2.toHistoryEntry = exports2.supportedBrowsers = exports2.readProfileInfos = exports2.createConfiguredBrowserReaders = exports2.createBrowserReader = exports2.countBookmarkFileNodes = exports2.parseProcessOutput = exports2.isBrowserRunning = exports2.getRunningBrowsers = exports2.getRunningBrowserNames = exports2.getProcessName = exports2.buildProcessQuery = exports2.readLogEntries = exports2.clearLogFile = exports2.Logger = exports2.MAX_BUFFERED_LOG_ENTRIES = exports2.DEFAULT_LOG_LIMIT = exports2.DEFAULT_BACKUP_RETENTION = exports2.BROWSER_PROCESS_NAMES = exports2.VERSION = exports2.PACKAGE = void 0;
4399
4434
  var constants_1 = require_constants2();
4400
4435
  Object.defineProperty(exports2, "PACKAGE", { enumerable: true, get: function() {
4401
4436
  return constants_1.CORE_PACKAGE;
@@ -4455,6 +4490,9 @@ var require_dist2 = __commonJS({
4455
4490
  Object.defineProperty(exports2, "createConfiguredBrowserReaders", { enumerable: true, get: function() {
4456
4491
  return readers_1.createConfiguredBrowserReaders;
4457
4492
  } });
4493
+ Object.defineProperty(exports2, "readProfileInfos", { enumerable: true, get: function() {
4494
+ return readers_1.readProfileInfos;
4495
+ } });
4458
4496
  Object.defineProperty(exports2, "supportedBrowsers", { enumerable: true, get: function() {
4459
4497
  return readers_1.supportedBrowsers;
4460
4498
  } });
@@ -4528,7 +4566,7 @@ var {
4528
4566
  } = import_index.default;
4529
4567
 
4530
4568
  // src/constants.ts
4531
- var CLI_VERSION = "0.1.2";
4569
+ var CLI_VERSION = "0.1.3";
4532
4570
  var CLI_NAME = "crosssync";
4533
4571
  var CLI_DESCRIPTION = "Cross-browser bookmark & history sync CLI (Chrome + Edge)";
4534
4572
  var WINDOWS_TASK_NAME = "CrossSync";
@@ -5482,6 +5520,24 @@ function pruneExports(exportDir, keep) {
5482
5520
  var readline = __toESM(require("readline/promises"));
5483
5521
  var import_shared10 = __toESM(require_dist());
5484
5522
  var import_core4 = __toESM(require_dist2());
5523
+
5524
+ // src/profile-info.ts
5525
+ function formatProfileAccount(info) {
5526
+ if (!info) {
5527
+ return null;
5528
+ }
5529
+ const displayName = info.isUsingDefaultName ? info.gaiaName ?? info.name : info.name ?? info.gaiaName;
5530
+ const parts = [];
5531
+ if (displayName) {
5532
+ parts.push(displayName);
5533
+ }
5534
+ if (info.userName && info.userName !== displayName) {
5535
+ parts.push(`<${info.userName}>`);
5536
+ }
5537
+ return parts.length > 0 ? parts.join(" ") : null;
5538
+ }
5539
+
5540
+ // src/commands/sync.ts
5485
5541
  function resolveTargets(options) {
5486
5542
  if (options.all) {
5487
5543
  return { bookmarks: true, history: true };
@@ -5552,6 +5608,7 @@ async function ensureProfilesSelected(context, options) {
5552
5608
  browser: reader.browser,
5553
5609
  dataDir: reader.dataDir,
5554
5610
  available,
5611
+ infos: reader.profileInfos(),
5555
5612
  current: context.config.profile
5556
5613
  });
5557
5614
  if (!selected || selected.length === 0) {
@@ -5576,8 +5633,10 @@ No ${request.browser} profile matched "${request.current}".
5576
5633
  `);
5577
5634
  output.write(`Available ${request.browser} profiles in ${request.dataDir}:
5578
5635
  `);
5636
+ const infos = new Map((request.infos ?? []).map((info) => [info.profile, info]));
5579
5637
  request.available.forEach((name, index) => {
5580
- output.write(` ${index + 1}) ${name}
5638
+ const account = formatProfileAccount(infos.get(name));
5639
+ output.write(` ${index + 1}) ${name}${account ? ` ${account}` : ""}
5581
5640
  `);
5582
5641
  });
5583
5642
  const rl = readline.createInterface({ input: process.stdin, output });
@@ -5672,7 +5731,8 @@ function formatSyncReport(report) {
5672
5731
  ].filter((kind) => kind !== null).join(" + ");
5673
5732
  lines.push(`CrossSync sync (${report.strategy}, ${kinds})${report.dryRun ? " [dry run]" : ""}`);
5674
5733
  for (const outcome of report.browsers) {
5675
- const parts = [`${outcome.browser}/${outcome.profile}`];
5734
+ const account = formatProfileAccount(outcome.profileInfo);
5735
+ const parts = [`${outcome.browser}/${outcome.profile}${account ? ` \u2014 ${account}` : ""}`];
5676
5736
  if (report.targets.bookmarks) {
5677
5737
  parts.push(`${outcome.bookmarksRead} bookmark nodes`);
5678
5738
  }
@@ -5871,9 +5931,13 @@ function listProfiles(context, options) {
5871
5931
  context.io.out(" (no profiles found)");
5872
5932
  continue;
5873
5933
  }
5934
+ const infos = new Map(reader.profileInfos().map((info) => [info.profile, info]));
5874
5935
  for (const name of available) {
5875
5936
  const isSelected = selected === null || selected.includes(name);
5876
- context.io.out(` ${name}${isSelected ? " [selected]" : ""}`);
5937
+ const account = formatProfileAccount(infos.get(name));
5938
+ context.io.out(
5939
+ ` ${name}${account ? ` ${account}` : ""}${isSelected ? " [selected]" : ""}`
5940
+ );
5877
5941
  }
5878
5942
  const missing = selected?.filter((name) => !available.includes(name)) ?? [];
5879
5943
  if (missing.length > 0) {