thought-cabinet 0.1.10 → 0.1.12

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
@@ -24,7 +24,7 @@ Thought Cabinet solves these by providing:
24
24
  cd your-project
25
25
 
26
26
  # 1. Install
27
- npm install -g thought-cabinet
27
+ pnpm install -g thought-cabinet
28
28
 
29
29
  # 2. Initialize thoughts in your project
30
30
  thc init
@@ -33,7 +33,7 @@ thc init
33
33
  thc agent init
34
34
 
35
35
  # 4. Use skills in your agent session (e.g. Claude Code)
36
- > /researching-codebase How does the authentication system work?
36
+ > /research-codebase How does the authentication system work?
37
37
  > /creating-plan Add OAuth2 support based on the research
38
38
  > /implementing-plan thoughts/shared/plans/add-oauth.md
39
39
  > /validating-plan thoughts/shared/plans/add-oauth.md
@@ -43,14 +43,14 @@ thc agent init
43
43
 
44
44
  Skills are installed by `thc agent init` and invoked as slash commands in your agent session:
45
45
 
46
- | Skill | Description |
47
- | ----------------------- | --------------------------------------------------------------------- |
48
- | `/researching-codebase` | Deep-dive into codebase, save findings to `thoughts/shared/research/` |
49
- | `/creating-plan` | Create implementation plan with phases and success criteria |
50
- | `/iterating-plan` | Refine existing plans based on feedback |
51
- | `/implementing-plan` | Execute plan phase-by-phase with verification |
52
- | `/validating-plan` | Verify implementation against plan's success criteria |
53
- | `/commit` | Create git commits with clear, descriptive messages |
46
+ | Skill | Description |
47
+ | -------------------- | --------------------------------------------------------------------- |
48
+ | `/research-codebase` | Deep-dive into codebase, save findings to `thoughts/shared/research/` |
49
+ | `/creating-plan` | Create implementation plan with phases and success criteria |
50
+ | `/iterating-plan` | Refine existing plans based on feedback |
51
+ | `/implementing-plan` | Execute plan phase-by-phase with verification |
52
+ | `/validating-plan` | Verify implementation against plan's success criteria |
53
+ | `/commit` | Create git commits with clear, descriptive messages |
54
54
 
55
55
  **Typical workflow**: research the codebase to build understanding, create a plan, iterate until the plan is solid, implement it, then validate the result.
56
56
 
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"],