thought-cabinet 0.1.10 → 0.1.11

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
@@ -1721,12 +1721,34 @@ function getLastCommit(repoPath) {
1721
1721
  return "No commits yet";
1722
1722
  }
1723
1723
  }
1724
- function getRemoteStatus(repoPath) {
1724
+ var STALE_FETCH_THRESHOLD_HOURS = 6;
1725
+ function getFetchAgeMs(repoPath) {
1726
+ const fetchHead = path13.join(repoPath, ".git", "FETCH_HEAD");
1727
+ try {
1728
+ const stat = fs10.statSync(fetchHead);
1729
+ return Date.now() - stat.mtimeMs;
1730
+ } catch {
1731
+ return null;
1732
+ }
1733
+ }
1734
+ function formatDuration(ms) {
1735
+ const seconds = Math.floor(ms / 1e3);
1736
+ if (seconds < 60) return `${seconds}s`;
1737
+ const minutes = Math.floor(seconds / 60);
1738
+ if (minutes < 60) return `${minutes}m`;
1739
+ const hours = Math.floor(minutes / 60);
1740
+ if (hours < 24) return `${hours}h`;
1741
+ const days = Math.floor(hours / 24);
1742
+ return `${days}d`;
1743
+ }
1744
+ function getRemoteStatus(repoPath, doFetch) {
1725
1745
  try {
1726
1746
  execSync5("git remote get-url origin", { cwd: repoPath, stdio: "pipe" });
1727
- try {
1728
- execSync5("git fetch", { cwd: repoPath, stdio: "pipe" });
1729
- } catch {
1747
+ if (doFetch) {
1748
+ try {
1749
+ execSync5("git fetch", { cwd: repoPath, stdio: "pipe" });
1750
+ } catch {
1751
+ }
1730
1752
  }
1731
1753
  const status = execSync5("git status -sb", {
1732
1754
  cwd: repoPath,
@@ -1738,26 +1760,7 @@ function getRemoteStatus(repoPath) {
1738
1760
  return chalk8.yellow(`${ahead} commits ahead of remote`);
1739
1761
  } else if (status.includes("behind")) {
1740
1762
  const behind = status.match(/behind (\d+)/)?.[1] || "?";
1741
- try {
1742
- execSync5("git pull --rebase", {
1743
- stdio: "pipe",
1744
- cwd: repoPath
1745
- });
1746
- console.log(chalk8.green("\u2713 Automatically pulled latest changes"));
1747
- const newStatus = execSync5("git status -sb", {
1748
- encoding: "utf8",
1749
- cwd: repoPath,
1750
- stdio: "pipe"
1751
- });
1752
- if (newStatus.includes("behind")) {
1753
- const newBehind = newStatus.match(/behind (\d+)/)?.[1] || "?";
1754
- return chalk8.yellow(`${newBehind} commits behind remote (after pull)`);
1755
- } else {
1756
- return chalk8.green("Up to date with remote (after pull)");
1757
- }
1758
- } catch {
1759
- return chalk8.yellow(`${behind} commits behind remote`);
1760
- }
1763
+ return chalk8.yellow(`${behind} commits behind remote`);
1761
1764
  } else {
1762
1765
  return chalk8.green("Up to date with remote");
1763
1766
  }
@@ -1812,7 +1815,19 @@ async function thoughtsStatusCommand(options) {
1812
1815
  console.log(chalk8.gray(` (using profile: ${profileName})`));
1813
1816
  }
1814
1817
  console.log(` ${getGitStatus(expandedRepo)}`);
1815
- console.log(` Remote: ${getRemoteStatus(expandedRepo)}`);
1818
+ const doFetch = options.fetch ?? false;
1819
+ const staleThresholdMs = (parseInt(options.maxAgeSecs ?? "", 10) || STALE_FETCH_THRESHOLD_HOURS * 60 * 60) * 1e3;
1820
+ console.log(` Remote: ${getRemoteStatus(expandedRepo, doFetch)}`);
1821
+ if (!doFetch) {
1822
+ const fetchAgeMs = getFetchAgeMs(expandedRepo);
1823
+ if (fetchAgeMs === null) {
1824
+ console.log(chalk8.gray(" (never fetched, use --fetch to refresh)"));
1825
+ } else if (fetchAgeMs > staleThresholdMs) {
1826
+ console.log(
1827
+ chalk8.gray(` (last fetched ${formatDuration(fetchAgeMs)} ago, use --fetch to refresh)`)
1828
+ );
1829
+ }
1830
+ }
1816
1831
  console.log(` Last commit: ${getLastCommit(expandedRepo)}`);
1817
1832
  console.log("");
1818
1833
  const changes = getUncommittedChanges(expandedRepo);
@@ -2222,7 +2237,7 @@ function thoughtsCommand(program) {
2222
2237
  ).option("--profile <name>", "Use a specific thoughts profile").action(thoughtsInitCommand);
2223
2238
  cmd.command("destroy").description("Remove thoughts setup from current repository").option("--force", "Force removal even if not in configuration").option("--config-file <path>", "Path to config file").action(thoughtsDestoryCommand);
2224
2239
  cmd.command("sync").description("Manually sync thoughts to thoughts repository").option("-m, --message <message>", "Commit message for sync").option("--config-file <path>", "Path to config file").action(thoughtsSyncCommand);
2225
- cmd.command("status").description("Show status of thoughts repository").option("--config-file <path>", "Path to config file").action(thoughtsStatusCommand);
2240
+ cmd.command("status").description("Show status of thoughts repository").option("--config-file <path>", "Path to config file").option("--fetch", "Fetch from remote before showing status").action(thoughtsStatusCommand);
2226
2241
  cmd.command("config").description("View or edit thoughts configuration").option("--edit", "Open configuration in editor").option("--json", "Output configuration as JSON").option("--config-file <path>", "Path to config file").action(thoughtsConfigCommand);
2227
2242
  cmd.command("prune").description("Remove stale repository mappings (directories that no longer exist)").option("--apply", "Apply changes (default is dry-run)").option("--config-file <path>", "Path to config file").action(thoughtsPruneCommand);
2228
2243
  const profile = cmd.command("profile").description("Manage thoughts profiles");
@@ -3645,7 +3660,7 @@ var OPTIONS = {
3645
3660
  init: ["--force", "--config-file", "--directory", "--profile"],
3646
3661
  destroy: ["--force", "--config-file"],
3647
3662
  sync: ["-m", "--message", "--config-file"],
3648
- status: ["--config-file"],
3663
+ status: ["--config-file", "--fetch"],
3649
3664
  config: ["--edit", "--json", "--config-file"],
3650
3665
  prune: ["--apply", "--config-file"],
3651
3666
  "profile create": ["--repo", "--repos-dir", "--global-dir", "--config-file"],