vibe-fabric 0.1.0

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 (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +171 -0
  3. package/dist/cli/commands/claude.d.ts +19 -0
  4. package/dist/cli/commands/claude.d.ts.map +1 -0
  5. package/dist/cli/commands/claude.js +107 -0
  6. package/dist/cli/commands/claude.js.map +1 -0
  7. package/dist/cli/commands/coverage.d.ts +37 -0
  8. package/dist/cli/commands/coverage.d.ts.map +1 -0
  9. package/dist/cli/commands/coverage.js +374 -0
  10. package/dist/cli/commands/coverage.js.map +1 -0
  11. package/dist/cli/commands/doctor.d.ts +30 -0
  12. package/dist/cli/commands/doctor.d.ts.map +1 -0
  13. package/dist/cli/commands/doctor.js +187 -0
  14. package/dist/cli/commands/doctor.js.map +1 -0
  15. package/dist/cli/commands/gaps.d.ts +52 -0
  16. package/dist/cli/commands/gaps.d.ts.map +1 -0
  17. package/dist/cli/commands/gaps.js +487 -0
  18. package/dist/cli/commands/gaps.js.map +1 -0
  19. package/dist/cli/commands/help.d.ts +7 -0
  20. package/dist/cli/commands/help.d.ts.map +1 -0
  21. package/dist/cli/commands/help.js +51 -0
  22. package/dist/cli/commands/help.js.map +1 -0
  23. package/dist/cli/commands/init.d.ts +39 -0
  24. package/dist/cli/commands/init.d.ts.map +1 -0
  25. package/dist/cli/commands/init.js +246 -0
  26. package/dist/cli/commands/init.js.map +1 -0
  27. package/dist/cli/commands/prd.d.ts +30 -0
  28. package/dist/cli/commands/prd.d.ts.map +1 -0
  29. package/dist/cli/commands/prd.js +179 -0
  30. package/dist/cli/commands/prd.js.map +1 -0
  31. package/dist/cli/commands/repo/add.d.ts +36 -0
  32. package/dist/cli/commands/repo/add.d.ts.map +1 -0
  33. package/dist/cli/commands/repo/add.js +303 -0
  34. package/dist/cli/commands/repo/add.js.map +1 -0
  35. package/dist/cli/commands/scope.d.ts +36 -0
  36. package/dist/cli/commands/scope.d.ts.map +1 -0
  37. package/dist/cli/commands/scope.js +312 -0
  38. package/dist/cli/commands/scope.js.map +1 -0
  39. package/dist/cli/commands/send.d.ts +43 -0
  40. package/dist/cli/commands/send.d.ts.map +1 -0
  41. package/dist/cli/commands/send.js +469 -0
  42. package/dist/cli/commands/send.js.map +1 -0
  43. package/dist/cli/commands/status.d.ts +32 -0
  44. package/dist/cli/commands/status.d.ts.map +1 -0
  45. package/dist/cli/commands/status.js +422 -0
  46. package/dist/cli/commands/status.js.map +1 -0
  47. package/dist/cli/commands/sync.d.ts +37 -0
  48. package/dist/cli/commands/sync.d.ts.map +1 -0
  49. package/dist/cli/commands/sync.js +299 -0
  50. package/dist/cli/commands/sync.js.map +1 -0
  51. package/dist/cli/commands/version.d.ts +7 -0
  52. package/dist/cli/commands/version.d.ts.map +1 -0
  53. package/dist/cli/commands/version.js +45 -0
  54. package/dist/cli/commands/version.js.map +1 -0
  55. package/dist/cli/index.d.ts +3 -0
  56. package/dist/cli/index.d.ts.map +1 -0
  57. package/dist/cli/index.js +65 -0
  58. package/dist/cli/index.js.map +1 -0
  59. package/dist/cli/ui/components/ActiveScopes.d.ts +13 -0
  60. package/dist/cli/ui/components/ActiveScopes.d.ts.map +1 -0
  61. package/dist/cli/ui/components/ActiveScopes.js +25 -0
  62. package/dist/cli/ui/components/ActiveScopes.js.map +1 -0
  63. package/dist/cli/ui/components/EmptyState.d.ts +24 -0
  64. package/dist/cli/ui/components/EmptyState.d.ts.map +1 -0
  65. package/dist/cli/ui/components/EmptyState.js +13 -0
  66. package/dist/cli/ui/components/EmptyState.js.map +1 -0
  67. package/dist/cli/ui/components/Header.d.ts +11 -0
  68. package/dist/cli/ui/components/Header.d.ts.map +1 -0
  69. package/dist/cli/ui/components/Header.js +32 -0
  70. package/dist/cli/ui/components/Header.js.map +1 -0
  71. package/dist/cli/ui/components/PrdCoverage.d.ts +12 -0
  72. package/dist/cli/ui/components/PrdCoverage.d.ts.map +1 -0
  73. package/dist/cli/ui/components/PrdCoverage.js +15 -0
  74. package/dist/cli/ui/components/PrdCoverage.js.map +1 -0
  75. package/dist/cli/ui/components/RecentActivity.d.ts +12 -0
  76. package/dist/cli/ui/components/RecentActivity.d.ts.map +1 -0
  77. package/dist/cli/ui/components/RecentActivity.js +40 -0
  78. package/dist/cli/ui/components/RecentActivity.js.map +1 -0
  79. package/dist/cli/ui/components/RepoList.d.ts +12 -0
  80. package/dist/cli/ui/components/RepoList.d.ts.map +1 -0
  81. package/dist/cli/ui/components/RepoList.js +24 -0
  82. package/dist/cli/ui/components/RepoList.js.map +1 -0
  83. package/dist/cli/ui/components/Shortcuts.d.ts +7 -0
  84. package/dist/cli/ui/components/Shortcuts.d.ts.map +1 -0
  85. package/dist/cli/ui/components/Shortcuts.js +7 -0
  86. package/dist/cli/ui/components/Shortcuts.js.map +1 -0
  87. package/dist/cli/ui/components/index.d.ts +12 -0
  88. package/dist/cli/ui/components/index.d.ts.map +1 -0
  89. package/dist/cli/ui/components/index.js +12 -0
  90. package/dist/cli/ui/components/index.js.map +1 -0
  91. package/dist/cli/ui/dashboard.d.ts +9 -0
  92. package/dist/cli/ui/dashboard.d.ts.map +1 -0
  93. package/dist/cli/ui/dashboard.js +102 -0
  94. package/dist/cli/ui/dashboard.js.map +1 -0
  95. package/dist/core/commands.d.ts +32 -0
  96. package/dist/core/commands.d.ts.map +1 -0
  97. package/dist/core/commands.js +361 -0
  98. package/dist/core/commands.js.map +1 -0
  99. package/dist/core/config.d.ts +18 -0
  100. package/dist/core/config.d.ts.map +1 -0
  101. package/dist/core/config.js +78 -0
  102. package/dist/core/config.js.map +1 -0
  103. package/dist/core/coverage.d.ts +32 -0
  104. package/dist/core/coverage.d.ts.map +1 -0
  105. package/dist/core/coverage.js +286 -0
  106. package/dist/core/coverage.js.map +1 -0
  107. package/dist/core/dashboard/data.d.ts +73 -0
  108. package/dist/core/dashboard/data.d.ts.map +1 -0
  109. package/dist/core/dashboard/data.js +250 -0
  110. package/dist/core/dashboard/data.js.map +1 -0
  111. package/dist/core/dependencies.d.ts +39 -0
  112. package/dist/core/dependencies.d.ts.map +1 -0
  113. package/dist/core/dependencies.js +160 -0
  114. package/dist/core/dependencies.js.map +1 -0
  115. package/dist/core/doctor/auth.d.ts +22 -0
  116. package/dist/core/doctor/auth.d.ts.map +1 -0
  117. package/dist/core/doctor/auth.js +147 -0
  118. package/dist/core/doctor/auth.js.map +1 -0
  119. package/dist/core/doctor/config.d.ts +26 -0
  120. package/dist/core/doctor/config.d.ts.map +1 -0
  121. package/dist/core/doctor/config.js +172 -0
  122. package/dist/core/doctor/config.js.map +1 -0
  123. package/dist/core/doctor/environment.d.ts +26 -0
  124. package/dist/core/doctor/environment.d.ts.map +1 -0
  125. package/dist/core/doctor/environment.js +145 -0
  126. package/dist/core/doctor/environment.js.map +1 -0
  127. package/dist/core/doctor/index.d.ts +44 -0
  128. package/dist/core/doctor/index.d.ts.map +1 -0
  129. package/dist/core/doctor/index.js +134 -0
  130. package/dist/core/doctor/index.js.map +1 -0
  131. package/dist/core/doctor/repos.d.ts +22 -0
  132. package/dist/core/doctor/repos.d.ts.map +1 -0
  133. package/dist/core/doctor/repos.js +262 -0
  134. package/dist/core/doctor/repos.js.map +1 -0
  135. package/dist/core/doctor/sync.d.ts +18 -0
  136. package/dist/core/doctor/sync.d.ts.map +1 -0
  137. package/dist/core/doctor/sync.js +146 -0
  138. package/dist/core/doctor/sync.js.map +1 -0
  139. package/dist/core/gaps.d.ts +70 -0
  140. package/dist/core/gaps.d.ts.map +1 -0
  141. package/dist/core/gaps.js +448 -0
  142. package/dist/core/gaps.js.map +1 -0
  143. package/dist/core/github.d.ts +38 -0
  144. package/dist/core/github.d.ts.map +1 -0
  145. package/dist/core/github.js +102 -0
  146. package/dist/core/github.js.map +1 -0
  147. package/dist/core/prd/analyzer.d.ts +44 -0
  148. package/dist/core/prd/analyzer.d.ts.map +1 -0
  149. package/dist/core/prd/analyzer.js +259 -0
  150. package/dist/core/prd/analyzer.js.map +1 -0
  151. package/dist/core/prd/check.d.ts +17 -0
  152. package/dist/core/prd/check.d.ts.map +1 -0
  153. package/dist/core/prd/check.js +154 -0
  154. package/dist/core/prd/check.js.map +1 -0
  155. package/dist/core/prd/index.d.ts +6 -0
  156. package/dist/core/prd/index.d.ts.map +1 -0
  157. package/dist/core/prd/index.js +6 -0
  158. package/dist/core/prd/index.js.map +1 -0
  159. package/dist/core/project.d.ts +13 -0
  160. package/dist/core/project.d.ts.map +1 -0
  161. package/dist/core/project.js +810 -0
  162. package/dist/core/project.js.map +1 -0
  163. package/dist/core/prompts.d.ts +52 -0
  164. package/dist/core/prompts.d.ts.map +1 -0
  165. package/dist/core/prompts.js +266 -0
  166. package/dist/core/prompts.js.map +1 -0
  167. package/dist/core/repo/framework.d.ts +38 -0
  168. package/dist/core/repo/framework.d.ts.map +1 -0
  169. package/dist/core/repo/framework.js +142 -0
  170. package/dist/core/repo/framework.js.map +1 -0
  171. package/dist/core/repo/index.d.ts +6 -0
  172. package/dist/core/repo/index.d.ts.map +1 -0
  173. package/dist/core/repo/index.js +6 -0
  174. package/dist/core/repo/index.js.map +1 -0
  175. package/dist/core/repo/templates/claude-agents.d.ts +6 -0
  176. package/dist/core/repo/templates/claude-agents.d.ts.map +1 -0
  177. package/dist/core/repo/templates/claude-agents.js +173 -0
  178. package/dist/core/repo/templates/claude-agents.js.map +1 -0
  179. package/dist/core/repo/templates/claude-commands.d.ts +6 -0
  180. package/dist/core/repo/templates/claude-commands.d.ts.map +1 -0
  181. package/dist/core/repo/templates/claude-commands.js +278 -0
  182. package/dist/core/repo/templates/claude-commands.js.map +1 -0
  183. package/dist/core/repo/templates/claude-prompts.d.ts +6 -0
  184. package/dist/core/repo/templates/claude-prompts.d.ts.map +1 -0
  185. package/dist/core/repo/templates/claude-prompts.js +258 -0
  186. package/dist/core/repo/templates/claude-prompts.js.map +1 -0
  187. package/dist/core/repo/templates/claude-scripts.d.ts +6 -0
  188. package/dist/core/repo/templates/claude-scripts.d.ts.map +1 -0
  189. package/dist/core/repo/templates/claude-scripts.js +212 -0
  190. package/dist/core/repo/templates/claude-scripts.js.map +1 -0
  191. package/dist/core/repo/templates/index.d.ts +22 -0
  192. package/dist/core/repo/templates/index.d.ts.map +1 -0
  193. package/dist/core/repo/templates/index.js +121 -0
  194. package/dist/core/repo/templates/index.js.map +1 -0
  195. package/dist/core/repo/templates/vibe-readme.d.ts +6 -0
  196. package/dist/core/repo/templates/vibe-readme.d.ts.map +1 -0
  197. package/dist/core/repo/templates/vibe-readme.js +204 -0
  198. package/dist/core/repo/templates/vibe-readme.js.map +1 -0
  199. package/dist/core/repo/templates/vibe-scripts.d.ts +6 -0
  200. package/dist/core/repo/templates/vibe-scripts.d.ts.map +1 -0
  201. package/dist/core/repo/templates/vibe-scripts.js +308 -0
  202. package/dist/core/repo/templates/vibe-scripts.js.map +1 -0
  203. package/dist/core/repo/validation.d.ts +46 -0
  204. package/dist/core/repo/validation.d.ts.map +1 -0
  205. package/dist/core/repo/validation.js +154 -0
  206. package/dist/core/repo/validation.js.map +1 -0
  207. package/dist/core/runner.d.ts +38 -0
  208. package/dist/core/runner.d.ts.map +1 -0
  209. package/dist/core/runner.js +124 -0
  210. package/dist/core/runner.js.map +1 -0
  211. package/dist/core/send.d.ts +83 -0
  212. package/dist/core/send.d.ts.map +1 -0
  213. package/dist/core/send.js +565 -0
  214. package/dist/core/send.js.map +1 -0
  215. package/dist/core/status.d.ts +76 -0
  216. package/dist/core/status.d.ts.map +1 -0
  217. package/dist/core/status.js +430 -0
  218. package/dist/core/status.js.map +1 -0
  219. package/dist/core/sync/aggregator.d.ts +22 -0
  220. package/dist/core/sync/aggregator.d.ts.map +1 -0
  221. package/dist/core/sync/aggregator.js +278 -0
  222. package/dist/core/sync/aggregator.js.map +1 -0
  223. package/dist/core/sync/completion.d.ts +37 -0
  224. package/dist/core/sync/completion.d.ts.map +1 -0
  225. package/dist/core/sync/completion.js +264 -0
  226. package/dist/core/sync/completion.js.map +1 -0
  227. package/dist/core/sync/index.d.ts +51 -0
  228. package/dist/core/sync/index.d.ts.map +1 -0
  229. package/dist/core/sync/index.js +200 -0
  230. package/dist/core/sync/index.js.map +1 -0
  231. package/dist/core/sync/scanner.d.ts +39 -0
  232. package/dist/core/sync/scanner.d.ts.map +1 -0
  233. package/dist/core/sync/scanner.js +364 -0
  234. package/dist/core/sync/scanner.js.map +1 -0
  235. package/dist/types/config.d.ts +157 -0
  236. package/dist/types/config.d.ts.map +1 -0
  237. package/dist/types/config.js +58 -0
  238. package/dist/types/config.js.map +1 -0
  239. package/dist/types/coverage.d.ts +100 -0
  240. package/dist/types/coverage.d.ts.map +1 -0
  241. package/dist/types/coverage.js +8 -0
  242. package/dist/types/coverage.js.map +1 -0
  243. package/dist/types/doctor.d.ts +68 -0
  244. package/dist/types/doctor.d.ts.map +1 -0
  245. package/dist/types/doctor.js +5 -0
  246. package/dist/types/doctor.js.map +1 -0
  247. package/dist/types/gaps.d.ts +129 -0
  248. package/dist/types/gaps.d.ts.map +1 -0
  249. package/dist/types/gaps.js +8 -0
  250. package/dist/types/gaps.js.map +1 -0
  251. package/dist/types/prompts.d.ts +99 -0
  252. package/dist/types/prompts.d.ts.map +1 -0
  253. package/dist/types/prompts.js +5 -0
  254. package/dist/types/prompts.js.map +1 -0
  255. package/dist/types/runner.d.ts +156 -0
  256. package/dist/types/runner.d.ts.map +1 -0
  257. package/dist/types/runner.js +41 -0
  258. package/dist/types/runner.js.map +1 -0
  259. package/dist/types/send.d.ts +157 -0
  260. package/dist/types/send.d.ts.map +1 -0
  261. package/dist/types/send.js +18 -0
  262. package/dist/types/send.js.map +1 -0
  263. package/dist/types/status.d.ts +150 -0
  264. package/dist/types/status.d.ts.map +1 -0
  265. package/dist/types/status.js +15 -0
  266. package/dist/types/status.js.map +1 -0
  267. package/dist/types/sync.d.ts +259 -0
  268. package/dist/types/sync.d.ts.map +1 -0
  269. package/dist/types/sync.js +38 -0
  270. package/dist/types/sync.js.map +1 -0
  271. package/package.json +72 -0
@@ -0,0 +1,430 @@
1
+ /**
2
+ * Core status module - loads and aggregates project status data
3
+ *
4
+ * Reads from cached files only (no network calls) to provide
5
+ * instant project health overview.
6
+ */
7
+ import { readFile, readdir } from 'fs/promises';
8
+ import { existsSync } from 'fs';
9
+ import path from 'path';
10
+ import { EXIT_CODES, } from '../types/status.js';
11
+ /**
12
+ * Default stale threshold in minutes
13
+ */
14
+ const DEFAULT_STALE_THRESHOLD = 30;
15
+ /**
16
+ * Load last sync data from cache
17
+ */
18
+ export async function loadLastSyncData(projectPath) {
19
+ const syncPath = path.join(projectPath, 'docs', 'sync-cache', 'last-sync.json');
20
+ try {
21
+ const content = await readFile(syncPath, 'utf-8');
22
+ return JSON.parse(content);
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ /**
29
+ * Load aggregated progress data from cache
30
+ */
31
+ export async function loadAggregatedData(projectPath) {
32
+ const aggPath = path.join(projectPath, 'docs', 'progress', 'aggregated.json');
33
+ try {
34
+ const content = await readFile(aggPath, 'utf-8');
35
+ return JSON.parse(content);
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ }
41
+ /**
42
+ * Get human-readable time since last sync
43
+ */
44
+ export function getTimeSinceSync(lastSyncTimestamp) {
45
+ if (!lastSyncTimestamp)
46
+ return 'never';
47
+ const lastSyncTime = new Date(lastSyncTimestamp).getTime();
48
+ const now = Date.now();
49
+ const diffMs = now - lastSyncTime;
50
+ const minutes = Math.floor(diffMs / 60000);
51
+ if (minutes < 1)
52
+ return 'just now';
53
+ if (minutes < 60)
54
+ return `${minutes}m ago`;
55
+ const hours = Math.floor(minutes / 60);
56
+ if (hours < 24)
57
+ return `${hours}h ago`;
58
+ const days = Math.floor(hours / 24);
59
+ return `${days}d ago`;
60
+ }
61
+ /**
62
+ * Check if data is stale
63
+ */
64
+ export function isStale(lastSyncTimestamp, thresholdMinutes = DEFAULT_STALE_THRESHOLD) {
65
+ if (!lastSyncTimestamp)
66
+ return true;
67
+ const lastSyncTime = new Date(lastSyncTimestamp).getTime();
68
+ const now = Date.now();
69
+ const diffMs = now - lastSyncTime;
70
+ return diffMs > thresholdMinutes * 60 * 1000;
71
+ }
72
+ /**
73
+ * Get freshness info from last sync data
74
+ */
75
+ export function getFreshnessInfo(lastSync, thresholdMinutes = DEFAULT_STALE_THRESHOLD) {
76
+ const timestamp = lastSync?.timestamp || null;
77
+ return {
78
+ lastSync: timestamp,
79
+ timeSinceSync: getTimeSinceSync(timestamp),
80
+ isStale: isStale(timestamp, thresholdMinutes),
81
+ staleThresholdMinutes: thresholdMinutes,
82
+ };
83
+ }
84
+ /**
85
+ * Build repo status from last sync and config
86
+ */
87
+ export function buildRepoStatus(config, lastSync) {
88
+ if (!lastSync) {
89
+ // No sync data yet - return basic info from config
90
+ return config.repos.map((repo) => ({
91
+ alias: repo.alias,
92
+ name: repo.name,
93
+ owner: repo.owner,
94
+ url: repo.url,
95
+ lastSync: null,
96
+ success: false,
97
+ filesScanned: 0,
98
+ activePlans: 0,
99
+ completedPlans: 0,
100
+ kbEntries: 0,
101
+ error: 'Not synced yet',
102
+ }));
103
+ }
104
+ return config.repos.map((repo) => {
105
+ const syncData = lastSync.repos[repo.alias];
106
+ return {
107
+ alias: repo.alias,
108
+ name: repo.name,
109
+ owner: repo.owner,
110
+ url: repo.url,
111
+ lastSync: lastSync.timestamp,
112
+ success: syncData?.success ?? false,
113
+ filesScanned: syncData?.files_scanned ?? 0,
114
+ activePlans: syncData?.active_plans ?? 0,
115
+ completedPlans: syncData?.completed_plans ?? 0,
116
+ kbEntries: syncData?.kb_entries ?? 0,
117
+ error: syncData?.error ?? null,
118
+ };
119
+ });
120
+ }
121
+ /**
122
+ * Count scopes by directory
123
+ */
124
+ export async function countScopesByDir(projectPath) {
125
+ const scopesDir = path.join(projectPath, 'docs', 'scopes');
126
+ const counts = {
127
+ drafts: 0,
128
+ ready: 0,
129
+ sent: 0,
130
+ inProgress: 0,
131
+ completed: 0,
132
+ blocked: 0,
133
+ };
134
+ const directories = ['drafts', 'ready', 'sent', 'completed'];
135
+ for (const dir of directories) {
136
+ const dirPath = path.join(scopesDir, dir);
137
+ try {
138
+ if (existsSync(dirPath)) {
139
+ const files = await readdir(dirPath);
140
+ const scopeFiles = files.filter((f) => f.startsWith('SCOPE-') && f.endsWith('.md'));
141
+ switch (dir) {
142
+ case 'drafts':
143
+ counts.drafts = scopeFiles.length;
144
+ break;
145
+ case 'ready':
146
+ counts.ready = scopeFiles.length;
147
+ break;
148
+ case 'sent':
149
+ counts.sent = scopeFiles.length;
150
+ break;
151
+ case 'completed':
152
+ counts.completed = scopeFiles.length;
153
+ break;
154
+ }
155
+ }
156
+ }
157
+ catch {
158
+ // Directory doesn't exist or can't be read
159
+ }
160
+ }
161
+ return counts;
162
+ }
163
+ /**
164
+ * Get scope counts from aggregated data (includes in_progress and blocked)
165
+ */
166
+ export function getScopeCountsFromAggregated(aggregated, fsCounts) {
167
+ if (!aggregated) {
168
+ return fsCounts;
169
+ }
170
+ return {
171
+ drafts: aggregated.hub_scopes?.drafts?.count ?? fsCounts.drafts,
172
+ ready: aggregated.hub_scopes?.ready?.count ?? fsCounts.ready,
173
+ sent: aggregated.hub_scopes?.sent?.count ?? fsCounts.sent,
174
+ inProgress: aggregated.scope_status?.in_progress?.length ?? 0,
175
+ completed: aggregated.hub_scopes?.completed?.count ?? fsCounts.completed,
176
+ blocked: aggregated.scope_status?.blocked?.length ?? 0,
177
+ };
178
+ }
179
+ /**
180
+ * Parse gaps from PRD modules
181
+ */
182
+ export async function parseGapsFromPrd(projectPath) {
183
+ const summary = { p1: 0, p2: 0, p3: 0, total: 0 };
184
+ const details = [];
185
+ const modulesDir = path.join(projectPath, 'docs', 'prd', 'modules');
186
+ try {
187
+ if (!existsSync(modulesDir)) {
188
+ return { summary, details };
189
+ }
190
+ const moduleDirs = await readdir(modulesDir);
191
+ for (const moduleDir of moduleDirs) {
192
+ const modulePath = path.join(modulesDir, moduleDir);
193
+ try {
194
+ const files = await readdir(modulePath);
195
+ for (const file of files) {
196
+ if (!file.endsWith('.md') || file.startsWith('_'))
197
+ continue;
198
+ const filePath = path.join(modulePath, file);
199
+ const content = await readFile(filePath, 'utf-8');
200
+ // Check if requirement is a gap (not implemented and not covered)
201
+ const statusMatch = content.match(/\*\*Status\*\*\s*\|\s*`?(\w+)`?/);
202
+ const coveredByMatch = content.match(/\*\*Covered By\*\*\s*\|\s*([^|\n]+)/);
203
+ const status = statusMatch?.[1]?.trim().toLowerCase();
204
+ const coveredBy = coveredByMatch?.[1]?.trim();
205
+ // A gap is a requirement that's not implemented and not covered
206
+ const isGap = status !== 'implemented' &&
207
+ (!coveredBy || coveredBy === '-' || coveredBy === '');
208
+ if (!isGap)
209
+ continue;
210
+ // Extract requirement details
211
+ const idMatch = content.match(/\*\*ID\*\*\s*\|\s*`?(REQ-[A-Z]+-\d+)`?/);
212
+ const priorityMatch = content.match(/\*\*Priority\*\*\s*\|\s*`?(P[123])`?/);
213
+ const descMatch = content.match(/## Description\s*\n\n([^\n]+)/);
214
+ const id = idMatch?.[1] ?? file.replace('.md', '');
215
+ const priority = priorityMatch?.[1] ?? 'P3';
216
+ const description = descMatch?.[1] ?? 'No description';
217
+ details.push({
218
+ id,
219
+ description: description.slice(0, 100),
220
+ priority,
221
+ module: moduleDir,
222
+ });
223
+ // Update summary
224
+ switch (priority) {
225
+ case 'P1':
226
+ summary.p1++;
227
+ break;
228
+ case 'P2':
229
+ summary.p2++;
230
+ break;
231
+ case 'P3':
232
+ summary.p3++;
233
+ break;
234
+ }
235
+ summary.total++;
236
+ }
237
+ }
238
+ catch {
239
+ // Can't read module directory
240
+ }
241
+ }
242
+ }
243
+ catch {
244
+ // Can't read modules directory
245
+ }
246
+ return { summary, details };
247
+ }
248
+ /**
249
+ * Calculate PRD coverage from modules
250
+ */
251
+ export async function calculateCoverage(projectPath) {
252
+ const coverage = {
253
+ totalRequirements: 0,
254
+ implementedRequirements: 0,
255
+ coveragePercentage: 0,
256
+ byModule: {},
257
+ };
258
+ const modulesDir = path.join(projectPath, 'docs', 'prd', 'modules');
259
+ try {
260
+ if (!existsSync(modulesDir)) {
261
+ return coverage;
262
+ }
263
+ const moduleDirs = await readdir(modulesDir);
264
+ for (const moduleDir of moduleDirs) {
265
+ const modulePath = path.join(modulesDir, moduleDir);
266
+ let moduleTotal = 0;
267
+ let moduleImplemented = 0;
268
+ try {
269
+ const files = await readdir(modulePath);
270
+ for (const file of files) {
271
+ if (!file.endsWith('.md') || file.startsWith('_'))
272
+ continue;
273
+ const filePath = path.join(modulePath, file);
274
+ const content = await readFile(filePath, 'utf-8');
275
+ // Check if this is a requirement file
276
+ const idMatch = content.match(/\*\*ID\*\*\s*\|\s*`?REQ-/);
277
+ if (!idMatch)
278
+ continue;
279
+ moduleTotal++;
280
+ coverage.totalRequirements++;
281
+ // Check status
282
+ const statusMatch = content.match(/\*\*Status\*\*\s*\|\s*`?(\w+)`?/);
283
+ const status = statusMatch?.[1]?.trim().toLowerCase();
284
+ if (status === 'implemented') {
285
+ moduleImplemented++;
286
+ coverage.implementedRequirements++;
287
+ }
288
+ }
289
+ if (moduleTotal > 0) {
290
+ coverage.byModule[moduleDir] = {
291
+ total: moduleTotal,
292
+ implemented: moduleImplemented,
293
+ percentage: Math.round((moduleImplemented / moduleTotal) * 100),
294
+ };
295
+ }
296
+ }
297
+ catch {
298
+ // Can't read module directory
299
+ }
300
+ }
301
+ if (coverage.totalRequirements > 0) {
302
+ coverage.coveragePercentage = Math.round((coverage.implementedRequirements / coverage.totalRequirements) * 100);
303
+ }
304
+ }
305
+ catch {
306
+ // Can't read modules directory
307
+ }
308
+ return coverage;
309
+ }
310
+ /**
311
+ * Determine health level and reasons
312
+ */
313
+ export function evaluateHealth(freshness, repos, gaps) {
314
+ const reasons = [];
315
+ // Critical conditions
316
+ if (gaps.p1 > 0) {
317
+ reasons.push(`${gaps.p1} P1 gap${gaps.p1 === 1 ? '' : 's'} found`);
318
+ }
319
+ const failedRepos = repos.filter((r) => !r.success && r.error);
320
+ if (failedRepos.length > 0) {
321
+ reasons.push(`${failedRepos.length} repo${failedRepos.length === 1 ? '' : 's'} failed to sync`);
322
+ }
323
+ if (reasons.length > 0) {
324
+ return { health: 'critical', reasons };
325
+ }
326
+ // Warning conditions
327
+ if (freshness.isStale) {
328
+ reasons.push(`Data is stale (>${freshness.staleThresholdMinutes}min)`);
329
+ }
330
+ if (gaps.p2 > 0) {
331
+ reasons.push(`${gaps.p2} P2 gap${gaps.p2 === 1 ? '' : 's'} found`);
332
+ }
333
+ if (reasons.length > 0) {
334
+ return { health: 'warning', reasons };
335
+ }
336
+ return { health: 'healthy', reasons: ['All checks passed'] };
337
+ }
338
+ /**
339
+ * Load complete project status
340
+ */
341
+ export async function loadProjectStatus(projectPath, config) {
342
+ // Load cached data
343
+ const lastSync = await loadLastSyncData(projectPath);
344
+ const aggregated = await loadAggregatedData(projectPath);
345
+ // Build freshness info
346
+ const freshness = getFreshnessInfo(lastSync);
347
+ // Build repo status
348
+ const repos = buildRepoStatus(config, lastSync);
349
+ // Get scope counts (from filesystem + aggregated)
350
+ const fsCounts = await countScopesByDir(projectPath);
351
+ const scopes = getScopeCountsFromAggregated(aggregated, fsCounts);
352
+ // Calculate coverage
353
+ const coverage = await calculateCoverage(projectPath);
354
+ // Parse gaps
355
+ const { summary: gaps, details: gapDetails } = await parseGapsFromPrd(projectPath);
356
+ // Evaluate health
357
+ const { health, reasons: healthReasons } = evaluateHealth(freshness, repos, gaps);
358
+ return {
359
+ projectName: config.project.name,
360
+ freshness,
361
+ repos,
362
+ coverage,
363
+ scopes,
364
+ gaps,
365
+ gapDetails,
366
+ health,
367
+ healthReasons,
368
+ };
369
+ }
370
+ /**
371
+ * Generate progress bar string
372
+ */
373
+ export function progressBar(percent, width = 20) {
374
+ const filled = Math.round((width * percent) / 100);
375
+ const empty = width - filled;
376
+ return '\u2588'.repeat(filled) + '\u2591'.repeat(empty);
377
+ }
378
+ /**
379
+ * Convert status to JSON output format
380
+ */
381
+ export function toJsonOutput(status) {
382
+ return {
383
+ project: status.projectName,
384
+ generatedAt: new Date().toISOString(),
385
+ health: {
386
+ status: status.health,
387
+ exitCode: EXIT_CODES[status.health],
388
+ reasons: status.healthReasons,
389
+ },
390
+ freshness: status.freshness,
391
+ repositories: {
392
+ count: status.repos.length,
393
+ synced: status.repos.filter((r) => r.success).length,
394
+ failed: status.repos.filter((r) => !r.success).length,
395
+ repos: status.repos,
396
+ },
397
+ coverage: {
398
+ percentage: status.coverage.coveragePercentage,
399
+ implemented: status.coverage.implementedRequirements,
400
+ total: status.coverage.totalRequirements,
401
+ byModule: status.coverage.byModule,
402
+ },
403
+ scopes: {
404
+ drafts: status.scopes.drafts,
405
+ ready: status.scopes.ready,
406
+ sent: status.scopes.sent,
407
+ inProgress: status.scopes.inProgress,
408
+ completed: status.scopes.completed,
409
+ blocked: status.scopes.blocked,
410
+ total: status.scopes.drafts +
411
+ status.scopes.ready +
412
+ status.scopes.sent +
413
+ status.scopes.completed,
414
+ },
415
+ gaps: {
416
+ p1: status.gaps.p1,
417
+ p2: status.gaps.p2,
418
+ p3: status.gaps.p3,
419
+ total: status.gaps.total,
420
+ details: status.gapDetails,
421
+ },
422
+ };
423
+ }
424
+ /**
425
+ * Get exit code for health level
426
+ */
427
+ export function getExitCode(health) {
428
+ return EXIT_CODES[health];
429
+ }
430
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/core/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Aggregator for multi-repo sync results
3
+ * Combines per-repo status into overall progress view
4
+ */
5
+ import { RepoSyncResult, AggregatedProgress, ScopeStatus } from '../../types/sync.js';
6
+ /**
7
+ * Get the minimum (lowest) status across multiple statuses
8
+ */
9
+ export declare function getMinStatus(statuses: ScopeStatus[]): ScopeStatus;
10
+ /**
11
+ * Aggregate sync results from multiple repositories
12
+ */
13
+ export declare function aggregateResults(repoResults: RepoSyncResult[], projectPath: string): Promise<AggregatedProgress>;
14
+ /**
15
+ * Detect scope status changes by comparing with previous aggregated data
16
+ */
17
+ export declare function detectStatusChanges(previous: AggregatedProgress | null, current: AggregatedProgress): Array<{
18
+ scopeId: string;
19
+ from: ScopeStatus;
20
+ to: ScopeStatus;
21
+ }>;
22
+ //# sourceMappingURL=aggregator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregator.d.ts","sourceRoot":"","sources":["../../../src/core/sync/aggregator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACL,cAAc,EACd,kBAAkB,EAElB,WAAW,EAGZ,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,CAejE;AAuBD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,cAAc,EAAE,EAC7B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC,CA4N7B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,EACnC,OAAO,EAAE,kBAAkB,GAC1B,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,WAAW,CAAA;CAAE,CAAC,CAiDhE"}