@shepai/cli 1.142.0 → 1.142.1

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.
Files changed (172) hide show
  1. package/dist/src/presentation/web/app/api/sessions/route.d.ts.map +1 -1
  2. package/dist/src/presentation/web/app/api/sessions/route.js +45 -13
  3. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  4. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +1 -1
  5. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.d.ts +3 -1
  6. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.d.ts.map +1 -1
  7. package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.js +13 -5
  8. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  9. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +1 -1
  10. package/dist/tsconfig.build.tsbuildinfo +1 -1
  11. package/package.json +1 -1
  12. package/web/.next/BUILD_ID +1 -1
  13. package/web/.next/build-manifest.json +2 -2
  14. package/web/.next/fallback-build-manifest.json +2 -2
  15. package/web/.next/prerender-manifest.json +3 -3
  16. package/web/.next/required-server-files.js +2 -2
  17. package/web/.next/required-server-files.json +2 -2
  18. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
  19. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -1
  20. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  21. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  22. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +28 -28
  23. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  24. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  25. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  26. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  27. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +1 -1
  28. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  29. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  30. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
  31. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +1 -1
  32. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  33. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  34. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  35. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  36. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  37. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  38. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +28 -28
  39. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  40. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  41. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  42. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  43. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +1 -1
  44. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  45. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  46. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
  47. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +1 -1
  48. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  49. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  50. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
  51. package/web/.next/server/app/(dashboard)/page.js +1 -1
  52. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  53. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  54. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  55. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  56. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  57. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  58. package/web/.next/server/app/_global-error.html +2 -2
  59. package/web/.next/server/app/_global-error.rsc +1 -1
  60. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  61. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  62. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +3 -3
  66. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  67. package/web/.next/server/app/api/sessions/route.js +3 -2
  68. package/web/.next/server/app/api/sessions/route.js.nft.json +1 -1
  69. package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  70. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  71. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  72. package/web/.next/server/app/skills/page/server-reference-manifest.json +8 -8
  73. package/web/.next/server/app/skills/page.js +1 -1
  74. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  75. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
  77. package/web/.next/server/app/tools/page.js +1 -1
  78. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  79. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  80. package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
  81. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  82. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_ff60e4a5.js +3 -0
  83. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_ff60e4a5.js.map +1 -0
  84. package/web/.next/server/chunks/[externals]__448264a3._.js +3 -0
  85. package/web/.next/server/chunks/[externals]__448264a3._.js.map +1 -0
  86. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  87. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  88. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  89. package/web/.next/server/chunks/ssr/{[root-of-the-server]__6ec59045._.js → [root-of-the-server]__0b150ddf._.js} +2 -2
  90. package/web/.next/server/chunks/ssr/{[root-of-the-server]__6ec59045._.js.map → [root-of-the-server]__0b150ddf._.js.map} +1 -1
  91. package/web/.next/server/chunks/ssr/{[root-of-the-server]__a5f9c6e5._.js → [root-of-the-server]__2138fa7e._.js} +3 -3
  92. package/web/.next/server/chunks/ssr/{[root-of-the-server]__a5f9c6e5._.js.map → [root-of-the-server]__2138fa7e._.js.map} +1 -1
  93. package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js +1 -1
  94. package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js.map +1 -1
  95. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  96. package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
  97. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
  98. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
  99. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
  100. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
  101. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
  102. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  103. package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js +1 -1
  104. package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js.map +1 -1
  105. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +1 -1
  106. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js.map +1 -1
  107. package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js +1 -1
  108. package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js.map +1 -1
  109. package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js +1 -1
  110. package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js.map +1 -1
  111. package/web/.next/server/chunks/ssr/_01046927._.js +1 -1
  112. package/web/.next/server/chunks/ssr/{_7e5c4d9c._.js → _05b4c375._.js} +2 -2
  113. package/web/.next/server/chunks/ssr/{_7e5c4d9c._.js.map → _05b4c375._.js.map} +1 -1
  114. package/web/.next/server/chunks/ssr/_0c5f56e3._.js +2 -2
  115. package/web/.next/server/chunks/ssr/_0c5f56e3._.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/_1b719e7f._.js +1 -1
  117. package/web/.next/server/chunks/ssr/_1b719e7f._.js.map +1 -1
  118. package/web/.next/server/chunks/ssr/_37e8548b._.js +1 -1
  119. package/web/.next/server/chunks/ssr/_37e8548b._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/_55d763e2._.js +1 -1
  121. package/web/.next/server/chunks/ssr/_55d763e2._.js.map +1 -1
  122. package/web/.next/server/chunks/ssr/_6256a985._.js +1 -1
  123. package/web/.next/server/chunks/ssr/_6256a985._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/_64bdfc6f._.js +2 -2
  125. package/web/.next/server/chunks/ssr/_64bdfc6f._.js.map +1 -1
  126. package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
  127. package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
  128. package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
  129. package/web/.next/server/chunks/ssr/_b71645b4._.js +1 -1
  130. package/web/.next/server/chunks/ssr/_b71645b4._.js.map +1 -1
  131. package/web/.next/server/chunks/ssr/{_1c6fbecf._.js → _be90dd43._.js} +2 -2
  132. package/web/.next/server/chunks/ssr/{_1c6fbecf._.js.map → _be90dd43._.js.map} +1 -1
  133. package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
  134. package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
  135. package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
  136. package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
  137. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  138. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  139. package/web/.next/server/chunks/ssr/{src_presentation_web_7bda2f00._.js → src_presentation_web_93e5fd0d._.js} +2 -2
  140. package/web/.next/server/chunks/ssr/{src_presentation_web_7bda2f00._.js.map → src_presentation_web_93e5fd0d._.js.map} +1 -1
  141. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
  142. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
  143. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
  144. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
  145. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  146. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  147. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  148. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  149. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  150. package/web/.next/server/pages/500.html +2 -2
  151. package/web/.next/server/server-reference-manifest.js +1 -1
  152. package/web/.next/server/server-reference-manifest.json +44 -44
  153. package/web/.next/static/chunks/{73889aad2b3356b1.js → 09084b604a4022a2.js} +2 -2
  154. package/web/.next/static/chunks/3cd98a2f7a8a33a8.js +1 -0
  155. package/web/.next/static/chunks/41d77b193b5df1b7.js +1 -0
  156. package/web/.next/static/chunks/{4adda8dd11458a46.js → 6b099ae0735b3c21.js} +2 -2
  157. package/web/.next/static/chunks/{e599050b1f6466fe.js → 7fe2bb39ee56a00a.js} +1 -1
  158. package/web/.next/static/chunks/{ea9969f79b2162ec.js → 86afa5ddfcbbbf94.js} +1 -1
  159. package/web/.next/static/chunks/{13978ecd00a81172.js → 8b7ba729b53257a1.js} +1 -1
  160. package/web/.next/static/chunks/{2eec9756f5220e22.js → 9f57fc63be1397a3.js} +1 -1
  161. package/web/.next/static/chunks/{74eef53714ab461d.js → a05f5913e43443d6.js} +1 -1
  162. package/web/.next/static/chunks/d2eb3a9e6fa8cdad.js +1 -0
  163. package/web/.next/static/chunks/{4d7e25ef4b8e2f62.js → d5475a9f1eed113d.js} +1 -1
  164. package/web/.next/static/chunks/{21ddf1d59c98adf0.js → f7251d9aebce001c.js} +1 -1
  165. package/web/.next/server/chunks/[root-of-the-server]__a62bd945._.js +0 -3
  166. package/web/.next/server/chunks/[root-of-the-server]__a62bd945._.js.map +0 -1
  167. package/web/.next/static/chunks/3f18dfdd07d48ecd.js +0 -1
  168. package/web/.next/static/chunks/6ad8d8682f4836c9.js +0 -1
  169. package/web/.next/static/chunks/a6a6a8387bae31f0.js +0 -1
  170. /package/web/.next/static/{G2BdtwIuunZEcXQ0FjJJF → Z9eZhnwItIVi_t0WGZSA4}/_buildManifest.js +0 -0
  171. /package/web/.next/static/{G2BdtwIuunZEcXQ0FjJJF → Z9eZhnwItIVi_t0WGZSA4}/_clientMiddlewareManifest.json +0 -0
  172. /package/web/.next/static/{G2BdtwIuunZEcXQ0FjJJF → Z9eZhnwItIVi_t0WGZSA4}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/sessions/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAgTvC;;;;;GAKG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO;;;;YAnTpC,MAAM;mBACC,MAAM;iBACR,MAAM,GAAG,IAAI;sBACR,MAAM;wBACJ,MAAM,GAAG,IAAI;uBACd,MAAM,GAAG,IAAI;mBACjB,MAAM,GAAG,IAAI;qBACX,MAAM;kBACT,MAAM;;IAwUjB"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/sessions/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3C,eAAO,MAAM,OAAO,kBAAkB,CAAC;AA2VvC;;;;;GAKG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO;;;;YA9VpC,MAAM;mBACC,MAAM;iBACR,MAAM,GAAG,IAAI;sBACR,MAAM;wBACJ,MAAM,GAAG,IAAI;uBACd,MAAM,GAAG,IAAI;mBACjB,MAAM,GAAG,IAAI;qBACX,MAAM;kBACT,MAAM;;IAoXjB"}
@@ -1,4 +1,5 @@
1
1
  import { NextResponse } from 'next/server';
2
+ import { createHash } from 'node:crypto';
2
3
  import { homedir } from 'node:os';
3
4
  import { join } from 'node:path';
4
5
  import { readdir, stat } from 'node:fs/promises';
@@ -20,28 +21,58 @@ function cursorEncodePath(p) {
20
21
  return p.replace(/^\//, '').replace(/\./g, '').replace(/[/\\]/g, '-');
21
22
  }
22
23
  // ── Claude Code session scanner ───────────────────────────────────────
23
- async function scanClaudeSessions(repositoryPath, limit) {
24
- const dirName = claudeEncodePath(repositoryPath);
25
- const projectDir = join(homedir(), '.claude', 'projects', dirName);
26
- let files;
24
+ /**
25
+ * Collect .jsonl session files from a single Claude project directory.
26
+ */
27
+ async function collectJsonlFiles(projectDir) {
28
+ let entries;
27
29
  try {
28
- const entries = await readdir(projectDir);
29
- files = entries.filter((e) => e.endsWith('.jsonl'));
30
+ entries = await readdir(projectDir);
30
31
  }
31
32
  catch {
32
33
  return [];
33
34
  }
34
- // Stat all files for mtime sorting
35
- const fileInfos = await Promise.allSettled(files.map(async (name) => {
35
+ const jsonlFiles = entries.filter((e) => e.endsWith('.jsonl'));
36
+ const fileInfos = await Promise.allSettled(jsonlFiles.map(async (name) => {
36
37
  const filePath = join(projectDir, name);
37
38
  const s = await stat(filePath);
38
39
  return { name, filePath, mtime: s.mtime.getTime() };
39
40
  }));
40
- const valid = fileInfos
41
+ return fileInfos
41
42
  .filter((r) => r.status === 'fulfilled')
42
- .map((r) => r.value)
43
- .sort((a, b) => b.mtime - a.mtime)
44
- .slice(0, limit);
43
+ .map((r) => r.value);
44
+ }
45
+ async function scanClaudeSessions(repositoryPath, limit, includeWorktrees = false) {
46
+ const dirName = claudeEncodePath(repositoryPath);
47
+ const projectsRoot = join(homedir(), '.claude', 'projects');
48
+ // Collect files from the exact directory
49
+ const primaryDir = join(projectsRoot, dirName);
50
+ let allFiles = await collectJsonlFiles(primaryDir);
51
+ // When includeWorktrees is set, also scan:
52
+ // 1. Directories whose name starts with the encoded repo path (git worktrees, .worktrees)
53
+ // 2. Shep worktree directories (~/.shep/repos/<hash>/wt/*) which use a hash of the repo path
54
+ if (includeWorktrees) {
55
+ try {
56
+ const allDirs = await readdir(projectsRoot);
57
+ // Match git-style worktrees (same prefix as repo path)
58
+ const prefixMatches = allDirs.filter((d) => d !== dirName && d.startsWith(dirName));
59
+ // Match shep worktrees: compute repo hash → find dirs starting with encoded shep path
60
+ const normalizedRepoPath = repositoryPath.replace(/\\/g, '/');
61
+ const repoHash = createHash('sha256').update(normalizedRepoPath).digest('hex').slice(0, 16);
62
+ const shepHome = join(homedir(), '.shep').replace(/\\/g, '/');
63
+ const shepWorktreePrefix = claudeEncodePath(join(shepHome, 'repos', repoHash));
64
+ const shepMatches = allDirs.filter((d) => d.startsWith(shepWorktreePrefix) && !prefixMatches.includes(d) && d !== dirName);
65
+ const worktreeDirs = [...prefixMatches, ...shepMatches];
66
+ const worktreeResults = await Promise.all(worktreeDirs.map((d) => collectJsonlFiles(join(projectsRoot, d))));
67
+ for (const files of worktreeResults) {
68
+ allFiles = allFiles.concat(files);
69
+ }
70
+ }
71
+ catch {
72
+ // projectsRoot doesn't exist — no sessions at all
73
+ }
74
+ }
75
+ const valid = allFiles.sort((a, b) => b.mtime - a.mtime).slice(0, limit);
45
76
  // Parse each file
46
77
  const results = await Promise.allSettled(valid.map(async (fi) => parseClaudeSession(fi.filePath, fi.name, fi.mtime, repositoryPath)));
47
78
  return results
@@ -238,13 +269,14 @@ export async function GET(request) {
238
269
  const url = new URL(request.url);
239
270
  const repositoryPath = url.searchParams.get('repositoryPath');
240
271
  const limit = parseInt(url.searchParams.get('limit') ?? '10', 10);
272
+ const includeWorktrees = url.searchParams.get('includeWorktrees') === 'true';
241
273
  if (!repositoryPath?.trim()) {
242
274
  return NextResponse.json({ error: 'repositoryPath is required' }, { status: 400 });
243
275
  }
244
276
  try {
245
277
  // Scan all providers in parallel
246
278
  const [claudeSessions, cursorSessions] = await Promise.all([
247
- scanClaudeSessions(repositoryPath, limit),
279
+ scanClaudeSessions(repositoryPath, limit, includeWorktrees),
248
280
  scanCursorSessions(repositoryPath, limit),
249
281
  ]);
250
282
  // Merge and sort by mtime descending, apply limit
@@ -1 +1 @@
1
- {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6CnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CA8dA"}
1
+ {"version":3,"file":"feature-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-node.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6CnE,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAgeA"}
@@ -112,7 +112,7 @@ export function FeatureNode({ data, selected, }) {
112
112
  ? 'cursor-pointer opacity-80 transition-opacity hover:opacity-100'
113
113
  : 'cursor-default'), children: data.deployment.status === DeploymentState.Booting ? (_jsx(Loader2, { className: "h-3 w-3 animate-spin text-blue-500" })) : (_jsx(Globe, { className: "h-3 w-3 text-green-600" })) }) }), _jsx(TooltipContent, { side: "top", children: data.deployment.status === DeploymentState.Booting
114
114
  ? 'Deploying...'
115
- : (data.deployment.url ?? 'Live') })] }) })) : null, data.fastMode ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", children: _jsx(Zap, { className: "h-3 w-3 text-amber-500" }) }) }), _jsx(TooltipContent, { side: "top", children: "Fast Mode" })] }) })) : null, data.repositoryPath ? (_jsx(FeatureSessionsDropdown, { repositoryPath: data.repositoryPath })) : null] }), data.state === 'deleting' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-gray-400" }), _jsx("span", { className: "text-muted-foreground", children: "Deleting\u2026" })] })) : data.state === 'creating' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-teal-600 dark:text-teal-400" }), _jsx("span", { className: "font-medium text-teal-600 dark:text-teal-400", children: getBadgeText(data) })] })) : data.state === 'running' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-teal-600 dark:text-teal-400" }), _jsx("span", { className: "font-medium text-teal-600 dark:text-teal-400", children: getBadgeText(data) })] })) : data.state === 'action-required' ? (_jsxs(Button, { variant: "default", size: "xs", "aria-label": getActionRequiredLabel(data), "data-testid": "feature-node-approve-button",
115
+ : (data.deployment.url ?? 'Live') })] }) })) : null, data.fastMode ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", children: _jsx(Zap, { className: "h-3 w-3 text-amber-500" }) }) }), _jsx(TooltipContent, { side: "top", children: "Fast Mode" })] }) })) : null, (data.worktreePath ?? data.repositoryPath) ? (_jsx(FeatureSessionsDropdown, { repositoryPath: data.worktreePath ?? data.repositoryPath })) : null] }), data.state === 'deleting' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-gray-400" }), _jsx("span", { className: "text-muted-foreground", children: "Deleting\u2026" })] })) : data.state === 'creating' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-teal-600 dark:text-teal-400" }), _jsx("span", { className: "font-medium text-teal-600 dark:text-teal-400", children: getBadgeText(data) })] })) : data.state === 'running' ? (_jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [_jsx(Icon, { className: "h-3.5 w-3.5 shrink-0 animate-spin text-teal-600 dark:text-teal-400" }), _jsx("span", { className: "font-medium text-teal-600 dark:text-teal-400", children: getBadgeText(data) })] })) : data.state === 'action-required' ? (_jsxs(Button, { variant: "default", size: "xs", "aria-label": getActionRequiredLabel(data), "data-testid": "feature-node-approve-button",
116
116
  // eslint-disable-next-line @typescript-eslint/no-empty-function -- click bubbles to card's onNodeClick
117
117
  onClick: () => { }, className: "nodrag dark:bg-primary dark:text-primary-foreground dark:hover:bg-primary/90 cursor-pointer bg-neutral-900 text-[11px] text-white hover:bg-neutral-800", children: [_jsx(Eye, { className: "h-3 w-3" }), getActionRequiredLabel(data)] })) : data.state === 'error' && data.onRetry ? (_jsxs(Button, { variant: "outline", size: "xs", "aria-label": "Retry", "data-testid": "feature-node-retry-button", onClick: (e) => {
118
118
  e.stopPropagation();
@@ -13,9 +13,11 @@ export interface SessionSummary {
13
13
  interface FeatureSessionsDropdownProps {
14
14
  repositoryPath: string;
15
15
  className?: string;
16
+ /** When true, also scan worktree session directories (used by repo nodes). */
17
+ includeWorktrees?: boolean;
16
18
  /** Callback to create a feature from a session. Only shown on repo nodes. */
17
19
  onCreateFromSession?: (session: SessionSummary, sessionFilePath: string) => void;
18
20
  }
19
- export declare function FeatureSessionsDropdown({ repositoryPath, className, onCreateFromSession, }: FeatureSessionsDropdownProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function FeatureSessionsDropdown({ repositoryPath, className, includeWorktrees, onCreateFromSession, }: FeatureSessionsDropdownProps): import("react/jsx-runtime").JSX.Element;
20
22
  export {};
21
23
  //# sourceMappingURL=feature-sessions-dropdown.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-sessions-dropdown.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-sessions-dropdown.tsx"],"names":[],"mappings":"AA8BA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,4BAA4B;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;CAClF;AAmDD,wBAAgB,uBAAuB,CAAC,EACtC,cAAc,EACd,SAAS,EACT,mBAAmB,GACpB,EAAE,4BAA4B,2CA2J9B"}
1
+ {"version":3,"file":"feature-sessions-dropdown.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-node/feature-sessions-dropdown.tsx"],"names":[],"mappings":"AA8BA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,4BAA4B;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;CAClF;AAmDD,wBAAgB,uBAAuB,CAAC,EACtC,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,mBAAmB,GACpB,EAAE,4BAA4B,2CAmK9B"}
@@ -56,7 +56,7 @@ async function copyToClipboard(text) {
56
56
  function stopNodeEvent(e) {
57
57
  e.stopPropagation();
58
58
  }
59
- export function FeatureSessionsDropdown({ repositoryPath, className, onCreateFromSession, }) {
59
+ export function FeatureSessionsDropdown({ repositoryPath, className, includeWorktrees, onCreateFromSession, }) {
60
60
  const [sessions, setSessions] = useState([]);
61
61
  const [loading, setLoading] = useState(false);
62
62
  const [fetched, setFetched] = useState(false);
@@ -77,7 +77,11 @@ export function FeatureSessionsDropdown({ repositoryPath, className, onCreateFro
77
77
  // Populates count badge + active indicator, and pre-loads the dropdown.
78
78
  useEffect(() => {
79
79
  let cancelled = false;
80
- const params = new URLSearchParams({ repositoryPath, limit: '10' });
80
+ const params = new URLSearchParams({
81
+ repositoryPath,
82
+ limit: '10',
83
+ ...(includeWorktrees && { includeWorktrees: 'true' }),
84
+ });
81
85
  fetch(`/api/sessions?${params.toString()}`)
82
86
  .then((res) => (res.ok ? res.json() : null))
83
87
  .then((data) => {
@@ -91,14 +95,18 @@ export function FeatureSessionsDropdown({ repositoryPath, className, onCreateFro
91
95
  return () => {
92
96
  cancelled = true;
93
97
  };
94
- }, [repositoryPath]);
98
+ }, [repositoryPath, includeWorktrees]);
95
99
  // Re-fetch on dropdown open if not already loaded (e.g. path changed)
96
100
  const doFetch = useCallback(async () => {
97
101
  if (fetched)
98
102
  return;
99
103
  setLoading(true);
100
104
  try {
101
- const params = new URLSearchParams({ repositoryPath, limit: '10' });
105
+ const params = new URLSearchParams({
106
+ repositoryPath,
107
+ limit: '10',
108
+ ...(includeWorktrees && { includeWorktrees: 'true' }),
109
+ });
102
110
  const res = await fetch(`/api/sessions?${params.toString()}`);
103
111
  if (res.ok) {
104
112
  const data = (await res.json());
@@ -113,7 +121,7 @@ export function FeatureSessionsDropdown({ repositoryPath, className, onCreateFro
113
121
  setLoading(false);
114
122
  setFetched(true);
115
123
  }
116
- }, [repositoryPath, fetched]);
124
+ }, [repositoryPath, fetched, includeWorktrees]);
117
125
  const handleOpenChange = useCallback((open) => {
118
126
  if (open)
119
127
  void doFetch();
@@ -1 +1 @@
1
- {"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAOnE,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CAyaA"}
1
+ {"version":3,"file":"repository-node.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-node.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAOnE,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,2CA0aA"}
@@ -71,7 +71,7 @@ export function RepositoryNode({ data, selected, }) {
71
71
  e.stopPropagation();
72
72
  data.onClick?.();
73
73
  }
74
- }, className: cn('nodrag bg-card flex w-[26rem] cursor-pointer flex-col overflow-hidden rounded-xl border shadow-sm transition-[border-color,box-shadow] duration-200 dark:bg-neutral-800/80', selected && 'border-blue-400 dark:border-amber-500/60'), children: [_jsxs("div", { className: "flex items-center gap-3 px-4 py-3", children: [_jsx(Github, { className: "text-muted-foreground h-5 w-5 shrink-0" }), _jsx("span", { "data-testid": "repository-node-name", className: "min-w-0 truncate text-sm font-medium", children: data.name }), _jsxs("div", { className: cn('flex shrink-0 items-center gap-2', (data.repositoryPath ?? data.onAdd) && 'ml-auto'), onClick: (e) => e.stopPropagation(), children: [data.repositoryPath ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in IDE", onClick: actions.openInIde, loading: actions.ideLoading, error: !!actions.ideError, icon: Code2, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in IDE" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in Shell", onClick: actions.openInShell, loading: actions.shellLoading, error: !!actions.shellError, icon: Terminal, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in Shell" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open Folder", onClick: actions.openFolder, loading: actions.folderLoading, error: !!actions.folderError, icon: FolderOpen, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open Folder" })] }) }), _jsx(FeatureSessionsDropdown, { repositoryPath: data.repositoryPath, onCreateFromSession: handleCreateFromSession })] })) : null, data.onAdd ? _jsx("div", { className: "ml-1.5" }) : null, data.onAdd ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { "aria-label": "New feature", "data-testid": "repository-node-add-button", onClick: (e) => {
74
+ }, className: cn('nodrag bg-card flex w-[26rem] cursor-pointer flex-col overflow-hidden rounded-xl border shadow-sm transition-[border-color,box-shadow] duration-200 dark:bg-neutral-800/80', selected && 'border-blue-400 dark:border-amber-500/60'), children: [_jsxs("div", { className: "flex items-center gap-3 px-4 py-3", children: [_jsx(Github, { className: "text-muted-foreground h-5 w-5 shrink-0" }), _jsx("span", { "data-testid": "repository-node-name", className: "min-w-0 truncate text-sm font-medium", children: data.name }), _jsxs("div", { className: cn('flex shrink-0 items-center gap-2', (data.repositoryPath ?? data.onAdd) && 'ml-auto'), onClick: (e) => e.stopPropagation(), children: [data.repositoryPath ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in IDE", onClick: actions.openInIde, loading: actions.ideLoading, error: !!actions.ideError, icon: Code2, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in IDE" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open in Shell", onClick: actions.openInShell, loading: actions.shellLoading, error: !!actions.shellError, icon: Terminal, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open in Shell" })] }) }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex items-center", children: _jsx(ActionButton, { label: "Open Folder", onClick: actions.openFolder, loading: actions.folderLoading, error: !!actions.folderError, icon: FolderOpen, iconOnly: true, variant: "ghost", size: "icon-xs" }) }) }), _jsx(TooltipContent, { children: "Open Folder" })] }) }), _jsx(FeatureSessionsDropdown, { repositoryPath: data.repositoryPath, includeWorktrees: true, onCreateFromSession: handleCreateFromSession })] })) : null, data.onAdd ? _jsx("div", { className: "ml-1.5" }) : null, data.onAdd ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { "aria-label": "New feature", "data-testid": "repository-node-add-button", onClick: (e) => {
75
75
  e.stopPropagation();
76
76
  data.onAdd?.();
77
77
  }, className: cn('flex h-6 shrink-0 cursor-pointer items-center gap-0.5 rounded bg-blue-500 px-1.5 text-[11px] font-bold text-white transition-colors hover:bg-blue-600 dark:bg-amber-500 dark:hover:bg-amber-400', data.pulseAdd && 'animate-pulse-cta'), children: [_jsx(Plus, { className: "h-3 w-3" }), _jsx("span", { className: "translate-y-px", children: "New" })] }) }), _jsx(TooltipContent, { side: "top", children: "New feature" })] }) })) : null] })] }), data.branch ? (_jsxs(_Fragment, { children: [_jsx("div", { "data-testid": "repository-node-git-info", className: "text-muted-foreground border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-3 text-xs", children: [_jsxs("span", { className: "flex items-center gap-1 truncate", "data-testid": "repository-node-branch", children: [_jsx(GitBranch, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: data.branch })] }), data.behindCount != null && data.behindCount > 0 ? (_jsxs("span", { className: "flex shrink-0 items-center gap-1 whitespace-nowrap text-amber-500", "data-testid": "repository-node-behind", children: [_jsx(ArrowDown, { className: "h-3 w-3 shrink-0" }), data.behindCount, " behind"] })) : null] }) }), data.commitMessage ? (_jsx("div", { "data-testid": "repository-node-commit-info", className: "text-muted-foreground border-border/50 border-t px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-2 text-xs", children: [_jsx(GitCommitHorizontal, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "min-w-0 truncate", "data-testid": "repository-node-commit-message", children: data.commitMessage }), data.committer ? (_jsxs("span", { className: "text-muted-foreground/70 ml-auto flex shrink-0 items-center gap-1", "data-testid": "repository-node-committer", children: [_jsx(User, { className: "h-3 w-3 shrink-0" }), _jsx("span", { children: data.committer })] })) : null] }) })) : null] })) : data.gitInfoStatus === 'not-a-repo' ? (