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.
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/dist/cli/commands/claude.d.ts +19 -0
- package/dist/cli/commands/claude.d.ts.map +1 -0
- package/dist/cli/commands/claude.js +107 -0
- package/dist/cli/commands/claude.js.map +1 -0
- package/dist/cli/commands/coverage.d.ts +37 -0
- package/dist/cli/commands/coverage.d.ts.map +1 -0
- package/dist/cli/commands/coverage.js +374 -0
- package/dist/cli/commands/coverage.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +30 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +187 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/gaps.d.ts +52 -0
- package/dist/cli/commands/gaps.d.ts.map +1 -0
- package/dist/cli/commands/gaps.js +487 -0
- package/dist/cli/commands/gaps.js.map +1 -0
- package/dist/cli/commands/help.d.ts +7 -0
- package/dist/cli/commands/help.d.ts.map +1 -0
- package/dist/cli/commands/help.js +51 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/init.d.ts +39 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +246 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/prd.d.ts +30 -0
- package/dist/cli/commands/prd.d.ts.map +1 -0
- package/dist/cli/commands/prd.js +179 -0
- package/dist/cli/commands/prd.js.map +1 -0
- package/dist/cli/commands/repo/add.d.ts +36 -0
- package/dist/cli/commands/repo/add.d.ts.map +1 -0
- package/dist/cli/commands/repo/add.js +303 -0
- package/dist/cli/commands/repo/add.js.map +1 -0
- package/dist/cli/commands/scope.d.ts +36 -0
- package/dist/cli/commands/scope.d.ts.map +1 -0
- package/dist/cli/commands/scope.js +312 -0
- package/dist/cli/commands/scope.js.map +1 -0
- package/dist/cli/commands/send.d.ts +43 -0
- package/dist/cli/commands/send.d.ts.map +1 -0
- package/dist/cli/commands/send.js +469 -0
- package/dist/cli/commands/send.js.map +1 -0
- package/dist/cli/commands/status.d.ts +32 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +422 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +37 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +299 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/commands/version.d.ts +7 -0
- package/dist/cli/commands/version.d.ts.map +1 -0
- package/dist/cli/commands/version.js +45 -0
- package/dist/cli/commands/version.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +65 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui/components/ActiveScopes.d.ts +13 -0
- package/dist/cli/ui/components/ActiveScopes.d.ts.map +1 -0
- package/dist/cli/ui/components/ActiveScopes.js +25 -0
- package/dist/cli/ui/components/ActiveScopes.js.map +1 -0
- package/dist/cli/ui/components/EmptyState.d.ts +24 -0
- package/dist/cli/ui/components/EmptyState.d.ts.map +1 -0
- package/dist/cli/ui/components/EmptyState.js +13 -0
- package/dist/cli/ui/components/EmptyState.js.map +1 -0
- package/dist/cli/ui/components/Header.d.ts +11 -0
- package/dist/cli/ui/components/Header.d.ts.map +1 -0
- package/dist/cli/ui/components/Header.js +32 -0
- package/dist/cli/ui/components/Header.js.map +1 -0
- package/dist/cli/ui/components/PrdCoverage.d.ts +12 -0
- package/dist/cli/ui/components/PrdCoverage.d.ts.map +1 -0
- package/dist/cli/ui/components/PrdCoverage.js +15 -0
- package/dist/cli/ui/components/PrdCoverage.js.map +1 -0
- package/dist/cli/ui/components/RecentActivity.d.ts +12 -0
- package/dist/cli/ui/components/RecentActivity.d.ts.map +1 -0
- package/dist/cli/ui/components/RecentActivity.js +40 -0
- package/dist/cli/ui/components/RecentActivity.js.map +1 -0
- package/dist/cli/ui/components/RepoList.d.ts +12 -0
- package/dist/cli/ui/components/RepoList.d.ts.map +1 -0
- package/dist/cli/ui/components/RepoList.js +24 -0
- package/dist/cli/ui/components/RepoList.js.map +1 -0
- package/dist/cli/ui/components/Shortcuts.d.ts +7 -0
- package/dist/cli/ui/components/Shortcuts.d.ts.map +1 -0
- package/dist/cli/ui/components/Shortcuts.js +7 -0
- package/dist/cli/ui/components/Shortcuts.js.map +1 -0
- package/dist/cli/ui/components/index.d.ts +12 -0
- package/dist/cli/ui/components/index.d.ts.map +1 -0
- package/dist/cli/ui/components/index.js +12 -0
- package/dist/cli/ui/components/index.js.map +1 -0
- package/dist/cli/ui/dashboard.d.ts +9 -0
- package/dist/cli/ui/dashboard.d.ts.map +1 -0
- package/dist/cli/ui/dashboard.js +102 -0
- package/dist/cli/ui/dashboard.js.map +1 -0
- package/dist/core/commands.d.ts +32 -0
- package/dist/core/commands.d.ts.map +1 -0
- package/dist/core/commands.js +361 -0
- package/dist/core/commands.js.map +1 -0
- package/dist/core/config.d.ts +18 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +78 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/coverage.d.ts +32 -0
- package/dist/core/coverage.d.ts.map +1 -0
- package/dist/core/coverage.js +286 -0
- package/dist/core/coverage.js.map +1 -0
- package/dist/core/dashboard/data.d.ts +73 -0
- package/dist/core/dashboard/data.d.ts.map +1 -0
- package/dist/core/dashboard/data.js +250 -0
- package/dist/core/dashboard/data.js.map +1 -0
- package/dist/core/dependencies.d.ts +39 -0
- package/dist/core/dependencies.d.ts.map +1 -0
- package/dist/core/dependencies.js +160 -0
- package/dist/core/dependencies.js.map +1 -0
- package/dist/core/doctor/auth.d.ts +22 -0
- package/dist/core/doctor/auth.d.ts.map +1 -0
- package/dist/core/doctor/auth.js +147 -0
- package/dist/core/doctor/auth.js.map +1 -0
- package/dist/core/doctor/config.d.ts +26 -0
- package/dist/core/doctor/config.d.ts.map +1 -0
- package/dist/core/doctor/config.js +172 -0
- package/dist/core/doctor/config.js.map +1 -0
- package/dist/core/doctor/environment.d.ts +26 -0
- package/dist/core/doctor/environment.d.ts.map +1 -0
- package/dist/core/doctor/environment.js +145 -0
- package/dist/core/doctor/environment.js.map +1 -0
- package/dist/core/doctor/index.d.ts +44 -0
- package/dist/core/doctor/index.d.ts.map +1 -0
- package/dist/core/doctor/index.js +134 -0
- package/dist/core/doctor/index.js.map +1 -0
- package/dist/core/doctor/repos.d.ts +22 -0
- package/dist/core/doctor/repos.d.ts.map +1 -0
- package/dist/core/doctor/repos.js +262 -0
- package/dist/core/doctor/repos.js.map +1 -0
- package/dist/core/doctor/sync.d.ts +18 -0
- package/dist/core/doctor/sync.d.ts.map +1 -0
- package/dist/core/doctor/sync.js +146 -0
- package/dist/core/doctor/sync.js.map +1 -0
- package/dist/core/gaps.d.ts +70 -0
- package/dist/core/gaps.d.ts.map +1 -0
- package/dist/core/gaps.js +448 -0
- package/dist/core/gaps.js.map +1 -0
- package/dist/core/github.d.ts +38 -0
- package/dist/core/github.d.ts.map +1 -0
- package/dist/core/github.js +102 -0
- package/dist/core/github.js.map +1 -0
- package/dist/core/prd/analyzer.d.ts +44 -0
- package/dist/core/prd/analyzer.d.ts.map +1 -0
- package/dist/core/prd/analyzer.js +259 -0
- package/dist/core/prd/analyzer.js.map +1 -0
- package/dist/core/prd/check.d.ts +17 -0
- package/dist/core/prd/check.d.ts.map +1 -0
- package/dist/core/prd/check.js +154 -0
- package/dist/core/prd/check.js.map +1 -0
- package/dist/core/prd/index.d.ts +6 -0
- package/dist/core/prd/index.d.ts.map +1 -0
- package/dist/core/prd/index.js +6 -0
- package/dist/core/prd/index.js.map +1 -0
- package/dist/core/project.d.ts +13 -0
- package/dist/core/project.d.ts.map +1 -0
- package/dist/core/project.js +810 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/prompts.d.ts +52 -0
- package/dist/core/prompts.d.ts.map +1 -0
- package/dist/core/prompts.js +266 -0
- package/dist/core/prompts.js.map +1 -0
- package/dist/core/repo/framework.d.ts +38 -0
- package/dist/core/repo/framework.d.ts.map +1 -0
- package/dist/core/repo/framework.js +142 -0
- package/dist/core/repo/framework.js.map +1 -0
- package/dist/core/repo/index.d.ts +6 -0
- package/dist/core/repo/index.d.ts.map +1 -0
- package/dist/core/repo/index.js +6 -0
- package/dist/core/repo/index.js.map +1 -0
- package/dist/core/repo/templates/claude-agents.d.ts +6 -0
- package/dist/core/repo/templates/claude-agents.d.ts.map +1 -0
- package/dist/core/repo/templates/claude-agents.js +173 -0
- package/dist/core/repo/templates/claude-agents.js.map +1 -0
- package/dist/core/repo/templates/claude-commands.d.ts +6 -0
- package/dist/core/repo/templates/claude-commands.d.ts.map +1 -0
- package/dist/core/repo/templates/claude-commands.js +278 -0
- package/dist/core/repo/templates/claude-commands.js.map +1 -0
- package/dist/core/repo/templates/claude-prompts.d.ts +6 -0
- package/dist/core/repo/templates/claude-prompts.d.ts.map +1 -0
- package/dist/core/repo/templates/claude-prompts.js +258 -0
- package/dist/core/repo/templates/claude-prompts.js.map +1 -0
- package/dist/core/repo/templates/claude-scripts.d.ts +6 -0
- package/dist/core/repo/templates/claude-scripts.d.ts.map +1 -0
- package/dist/core/repo/templates/claude-scripts.js +212 -0
- package/dist/core/repo/templates/claude-scripts.js.map +1 -0
- package/dist/core/repo/templates/index.d.ts +22 -0
- package/dist/core/repo/templates/index.d.ts.map +1 -0
- package/dist/core/repo/templates/index.js +121 -0
- package/dist/core/repo/templates/index.js.map +1 -0
- package/dist/core/repo/templates/vibe-readme.d.ts +6 -0
- package/dist/core/repo/templates/vibe-readme.d.ts.map +1 -0
- package/dist/core/repo/templates/vibe-readme.js +204 -0
- package/dist/core/repo/templates/vibe-readme.js.map +1 -0
- package/dist/core/repo/templates/vibe-scripts.d.ts +6 -0
- package/dist/core/repo/templates/vibe-scripts.d.ts.map +1 -0
- package/dist/core/repo/templates/vibe-scripts.js +308 -0
- package/dist/core/repo/templates/vibe-scripts.js.map +1 -0
- package/dist/core/repo/validation.d.ts +46 -0
- package/dist/core/repo/validation.d.ts.map +1 -0
- package/dist/core/repo/validation.js +154 -0
- package/dist/core/repo/validation.js.map +1 -0
- package/dist/core/runner.d.ts +38 -0
- package/dist/core/runner.d.ts.map +1 -0
- package/dist/core/runner.js +124 -0
- package/dist/core/runner.js.map +1 -0
- package/dist/core/send.d.ts +83 -0
- package/dist/core/send.d.ts.map +1 -0
- package/dist/core/send.js +565 -0
- package/dist/core/send.js.map +1 -0
- package/dist/core/status.d.ts +76 -0
- package/dist/core/status.d.ts.map +1 -0
- package/dist/core/status.js +430 -0
- package/dist/core/status.js.map +1 -0
- package/dist/core/sync/aggregator.d.ts +22 -0
- package/dist/core/sync/aggregator.d.ts.map +1 -0
- package/dist/core/sync/aggregator.js +278 -0
- package/dist/core/sync/aggregator.js.map +1 -0
- package/dist/core/sync/completion.d.ts +37 -0
- package/dist/core/sync/completion.d.ts.map +1 -0
- package/dist/core/sync/completion.js +264 -0
- package/dist/core/sync/completion.js.map +1 -0
- package/dist/core/sync/index.d.ts +51 -0
- package/dist/core/sync/index.d.ts.map +1 -0
- package/dist/core/sync/index.js +200 -0
- package/dist/core/sync/index.js.map +1 -0
- package/dist/core/sync/scanner.d.ts +39 -0
- package/dist/core/sync/scanner.d.ts.map +1 -0
- package/dist/core/sync/scanner.js +364 -0
- package/dist/core/sync/scanner.js.map +1 -0
- package/dist/types/config.d.ts +157 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +58 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/coverage.d.ts +100 -0
- package/dist/types/coverage.d.ts.map +1 -0
- package/dist/types/coverage.js +8 -0
- package/dist/types/coverage.js.map +1 -0
- package/dist/types/doctor.d.ts +68 -0
- package/dist/types/doctor.d.ts.map +1 -0
- package/dist/types/doctor.js +5 -0
- package/dist/types/doctor.js.map +1 -0
- package/dist/types/gaps.d.ts +129 -0
- package/dist/types/gaps.d.ts.map +1 -0
- package/dist/types/gaps.js +8 -0
- package/dist/types/gaps.js.map +1 -0
- package/dist/types/prompts.d.ts +99 -0
- package/dist/types/prompts.d.ts.map +1 -0
- package/dist/types/prompts.js +5 -0
- package/dist/types/prompts.js.map +1 -0
- package/dist/types/runner.d.ts +156 -0
- package/dist/types/runner.d.ts.map +1 -0
- package/dist/types/runner.js +41 -0
- package/dist/types/runner.js.map +1 -0
- package/dist/types/send.d.ts +157 -0
- package/dist/types/send.d.ts.map +1 -0
- package/dist/types/send.js +18 -0
- package/dist/types/send.js.map +1 -0
- package/dist/types/status.d.ts +150 -0
- package/dist/types/status.d.ts.map +1 -0
- package/dist/types/status.js +15 -0
- package/dist/types/status.js.map +1 -0
- package/dist/types/sync.d.ts +259 -0
- package/dist/types/sync.d.ts.map +1 -0
- package/dist/types/sync.js +38 -0
- package/dist/types/sync.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EACL,UAAU,EAEV,WAAW,EACX,UAAU,EAEV,YAAY,EACZ,kBAAkB,EAEnB,MAAM,qBAAqB,CAAC;AAa7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAEhC;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAI1D;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CASpF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CASpC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,YAAY,GAAG,IAAI,EAC7B,MAAM,EAAE,UAAU,GACjB,OAAO,CAQT;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,GAAG,MAAM,CAmB1E;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC,CAsGrB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAUD"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main sync module - coordinates repository syncing
|
|
3
|
+
*/
|
|
4
|
+
import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { DEFAULT_SYNC_CONFIG, } from '../../types/sync.js';
|
|
8
|
+
import { syncRepository, withRetry } from './scanner.js';
|
|
9
|
+
import { aggregateResults, detectStatusChanges } from './aggregator.js';
|
|
10
|
+
import { findCompletedScopes, moveCompletedScopes, getSentScopeIds, updatePrdStatuses, updateCoverageJson, buildStatusChanges, } from './completion.js';
|
|
11
|
+
// Re-export types and functions
|
|
12
|
+
export * from './scanner.js';
|
|
13
|
+
export * from './aggregator.js';
|
|
14
|
+
export * from './completion.js';
|
|
15
|
+
/**
|
|
16
|
+
* Load sync configuration from project
|
|
17
|
+
*/
|
|
18
|
+
export function loadSyncConfig(_config) {
|
|
19
|
+
// For now, return defaults
|
|
20
|
+
// In the future, this could be read from vibe-fabric.toml
|
|
21
|
+
return DEFAULT_SYNC_CONFIG;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Load last sync data
|
|
25
|
+
*/
|
|
26
|
+
export async function loadLastSync(projectPath) {
|
|
27
|
+
const syncPath = path.join(projectPath, 'docs', 'sync-cache', 'last-sync.json');
|
|
28
|
+
try {
|
|
29
|
+
const content = await readFile(syncPath, 'utf-8');
|
|
30
|
+
return JSON.parse(content);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Save last sync data
|
|
38
|
+
*/
|
|
39
|
+
export async function saveLastSync(projectPath, data) {
|
|
40
|
+
const syncDir = path.join(projectPath, 'docs', 'sync-cache');
|
|
41
|
+
const syncPath = path.join(syncDir, 'last-sync.json');
|
|
42
|
+
if (!existsSync(syncDir)) {
|
|
43
|
+
await mkdir(syncDir, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
await writeFile(syncPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Load previous aggregated progress
|
|
49
|
+
*/
|
|
50
|
+
export async function loadAggregatedProgress(projectPath) {
|
|
51
|
+
const aggPath = path.join(projectPath, 'docs', 'progress', 'aggregated.json');
|
|
52
|
+
try {
|
|
53
|
+
const content = await readFile(aggPath, 'utf-8');
|
|
54
|
+
return JSON.parse(content);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Save aggregated progress
|
|
62
|
+
*/
|
|
63
|
+
export async function saveAggregatedProgress(projectPath, data) {
|
|
64
|
+
const progressDir = path.join(projectPath, 'docs', 'progress');
|
|
65
|
+
const aggPath = path.join(progressDir, 'aggregated.json');
|
|
66
|
+
if (!existsSync(progressDir)) {
|
|
67
|
+
await mkdir(progressDir, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
await writeFile(aggPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if data is stale
|
|
73
|
+
*/
|
|
74
|
+
export function isDataStale(lastSync, config) {
|
|
75
|
+
if (!lastSync)
|
|
76
|
+
return true;
|
|
77
|
+
const lastSyncTime = new Date(lastSync.timestamp).getTime();
|
|
78
|
+
const now = Date.now();
|
|
79
|
+
const staleThresholdMs = config.stale_threshold_minutes * 60 * 1000;
|
|
80
|
+
return now - lastSyncTime > staleThresholdMs;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get time since last sync in human-readable format
|
|
84
|
+
*/
|
|
85
|
+
export function getTimeSinceLastSync(lastSync) {
|
|
86
|
+
if (!lastSync)
|
|
87
|
+
return 'never';
|
|
88
|
+
const lastSyncTime = new Date(lastSync.timestamp).getTime();
|
|
89
|
+
const now = Date.now();
|
|
90
|
+
const diffMs = now - lastSyncTime;
|
|
91
|
+
const minutes = Math.floor(diffMs / 60000);
|
|
92
|
+
if (minutes < 60) {
|
|
93
|
+
return `${minutes} minute${minutes !== 1 ? 's' : ''} ago`;
|
|
94
|
+
}
|
|
95
|
+
const hours = Math.floor(minutes / 60);
|
|
96
|
+
if (hours < 24) {
|
|
97
|
+
return `${hours} hour${hours !== 1 ? 's' : ''} ago`;
|
|
98
|
+
}
|
|
99
|
+
const days = Math.floor(hours / 24);
|
|
100
|
+
return `${days} day${days !== 1 ? 's' : ''} ago`;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Perform full sync operation
|
|
104
|
+
*/
|
|
105
|
+
export async function performSync(octokit, projectPath, config, repos, options) {
|
|
106
|
+
const startTime = Date.now();
|
|
107
|
+
const syncConfig = loadSyncConfig(config);
|
|
108
|
+
// Load previous data
|
|
109
|
+
const lastSync = await loadLastSync(projectPath);
|
|
110
|
+
const prevAggregated = await loadAggregatedProgress(projectPath);
|
|
111
|
+
// Check staleness
|
|
112
|
+
const stale = isDataStale(lastSync, syncConfig);
|
|
113
|
+
// Sync each repository
|
|
114
|
+
const repoResults = [];
|
|
115
|
+
for (const repo of repos) {
|
|
116
|
+
const result = await withRetry(() => syncRepository(octokit, repo, {
|
|
117
|
+
kbEnabled: options.kbOnly || syncConfig.kb_sync_enabled,
|
|
118
|
+
verbose: options.verbose,
|
|
119
|
+
}), syncConfig.max_retries, syncConfig.retry_delay_seconds * 1000);
|
|
120
|
+
repoResults.push(result);
|
|
121
|
+
}
|
|
122
|
+
// Aggregate results
|
|
123
|
+
const aggregated = await aggregateResults(repoResults, projectPath);
|
|
124
|
+
// Detect status changes
|
|
125
|
+
const rawChanges = detectStatusChanges(prevAggregated, aggregated);
|
|
126
|
+
// Auto-complete scopes
|
|
127
|
+
let movedScopes = [];
|
|
128
|
+
let prdUpdates = [];
|
|
129
|
+
if (!options.noAutoMove && syncConfig.auto_complete_scopes) {
|
|
130
|
+
const sentScopeIds = await getSentScopeIds(projectPath);
|
|
131
|
+
const scopesToMove = findCompletedScopes(aggregated, sentScopeIds);
|
|
132
|
+
movedScopes = await moveCompletedScopes(projectPath, scopesToMove);
|
|
133
|
+
}
|
|
134
|
+
// Update PRD statuses
|
|
135
|
+
if (!options.noPrdUpdate && syncConfig.auto_update_prd && movedScopes.length > 0) {
|
|
136
|
+
prdUpdates = await updatePrdStatuses(projectPath, movedScopes);
|
|
137
|
+
}
|
|
138
|
+
// Build status changes with auto-moved flag
|
|
139
|
+
const statusChanges = buildStatusChanges(rawChanges, movedScopes, aggregated);
|
|
140
|
+
// Update coverage.json
|
|
141
|
+
await updateCoverageJson(projectPath, aggregated);
|
|
142
|
+
// Save aggregated progress
|
|
143
|
+
await saveAggregatedProgress(projectPath, aggregated);
|
|
144
|
+
// Build last sync data
|
|
145
|
+
const duration = Date.now() - startTime;
|
|
146
|
+
const lastSyncData = {
|
|
147
|
+
timestamp: new Date().toISOString(),
|
|
148
|
+
duration_ms: duration,
|
|
149
|
+
repos: {},
|
|
150
|
+
totals: {
|
|
151
|
+
repos_synced: repoResults.filter((r) => r.success).length,
|
|
152
|
+
repos_failed: repoResults.filter((r) => !r.success).length,
|
|
153
|
+
files_scanned: repoResults.reduce((sum, r) => sum + r.filesScanned, 0),
|
|
154
|
+
kb_entries: repoResults.reduce((sum, r) => sum + r.kbEntries, 0),
|
|
155
|
+
},
|
|
156
|
+
changes: {
|
|
157
|
+
scope_status_changes: statusChanges,
|
|
158
|
+
scopes_auto_moved: movedScopes,
|
|
159
|
+
prd_updates: prdUpdates,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
for (const result of repoResults) {
|
|
163
|
+
lastSyncData.repos[result.alias] = {
|
|
164
|
+
success: result.success,
|
|
165
|
+
files_scanned: result.filesScanned,
|
|
166
|
+
active_plans: result.activePlans.length,
|
|
167
|
+
completed_plans: result.completedPlans.length,
|
|
168
|
+
kb_entries: result.kbEntries,
|
|
169
|
+
warnings: result.warnings,
|
|
170
|
+
error: result.error || null,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// Save last sync
|
|
174
|
+
await saveLastSync(projectPath, lastSyncData);
|
|
175
|
+
return {
|
|
176
|
+
success: repoResults.every((r) => r.success),
|
|
177
|
+
repoResults,
|
|
178
|
+
aggregated,
|
|
179
|
+
statusChanges,
|
|
180
|
+
movedScopes,
|
|
181
|
+
prdUpdates,
|
|
182
|
+
duration,
|
|
183
|
+
isStale: stale,
|
|
184
|
+
lastSync: lastSync?.timestamp,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Check staleness only (--check mode)
|
|
189
|
+
*/
|
|
190
|
+
export async function checkStaleness(projectPath, config) {
|
|
191
|
+
const syncConfig = loadSyncConfig(config);
|
|
192
|
+
const lastSync = await loadLastSync(projectPath);
|
|
193
|
+
return {
|
|
194
|
+
isStale: isDataStale(lastSync, syncConfig),
|
|
195
|
+
lastSync: lastSync?.timestamp || null,
|
|
196
|
+
timeSinceSync: getTimeSinceLastSync(lastSync),
|
|
197
|
+
threshold: syncConfig.stale_threshold_minutes,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/sync/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub repository scanner for sync operations
|
|
3
|
+
* Scans vibe/ folders in dev repos to detect scope status
|
|
4
|
+
*/
|
|
5
|
+
import { Octokit } from 'octokit';
|
|
6
|
+
import { Repo } from '../../types/config.js';
|
|
7
|
+
import { ParsedPlan, RepoSyncResult, ScopeStatusInfo, KbEntry } from '../../types/sync.js';
|
|
8
|
+
/**
|
|
9
|
+
* Scan a folder in a repository and return file names
|
|
10
|
+
*/
|
|
11
|
+
export declare function scanRepoFolder(octokit: Octokit, owner: string, repo: string, path: string, branch: string): Promise<string[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Get file content from repository
|
|
14
|
+
*/
|
|
15
|
+
export declare function getFileContent(octokit: Octokit, owner: string, repo: string, path: string, branch: string): Promise<string | null>;
|
|
16
|
+
/**
|
|
17
|
+
* Parse plan metadata from markdown content
|
|
18
|
+
*/
|
|
19
|
+
export declare function parsePlanMetadata(filename: string, content: string): ParsedPlan;
|
|
20
|
+
/**
|
|
21
|
+
* Calculate scope statuses from scanned data
|
|
22
|
+
*/
|
|
23
|
+
export declare function calculateScopeStatuses(incomingScopes: string[], activePlans: ParsedPlan[], completedPlans: ParsedPlan[]): Record<string, ScopeStatusInfo>;
|
|
24
|
+
/**
|
|
25
|
+
* Scan knowledge base entries
|
|
26
|
+
*/
|
|
27
|
+
export declare function scanKnowledgeBase(octokit: Octokit, owner: string, repo: string, branch: string, repoAlias: string): Promise<KbEntry[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Sync a single repository
|
|
30
|
+
*/
|
|
31
|
+
export declare function syncRepository(octokit: Octokit, repo: Repo, options: {
|
|
32
|
+
kbEnabled: boolean;
|
|
33
|
+
verbose?: boolean;
|
|
34
|
+
}): Promise<RepoSyncResult>;
|
|
35
|
+
/**
|
|
36
|
+
* Retry wrapper for network operations
|
|
37
|
+
*/
|
|
38
|
+
export declare function withRetry<T>(fn: () => Promise<T>, maxRetries: number, delayMs: number): Promise<T>;
|
|
39
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/core/sync/scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EACL,UAAU,EACV,cAAc,EACd,eAAe,EACf,OAAO,EACR,MAAM,qBAAqB,CAAC;AAY7B;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC,CAuBnB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqBxB;AA0BD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,UAAU,CAyCZ;AAWD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,EAAE,EACxB,WAAW,EAAE,UAAU,EAAE,EACzB,cAAc,EAAE,UAAU,EAAE,GAC3B,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAiGjC;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,EAAE,CAAC,CAyCpB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACjD,OAAO,CAAC,cAAc,CAAC,CAkIzB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,CAAC,CA+BZ"}
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub repository scanner for sync operations
|
|
3
|
+
* Scans vibe/ folders in dev repos to detect scope status
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Paths to scan in dev repositories
|
|
7
|
+
*/
|
|
8
|
+
const SCAN_PATHS = {
|
|
9
|
+
incomingScopes: 'vibe/incoming-scopes',
|
|
10
|
+
activePlans: 'vibe/implementation-plans/active',
|
|
11
|
+
completedPlans: 'vibe/implementation-plans/completed',
|
|
12
|
+
knowledgeBase: 'vibe/knowledge-base',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Scan a folder in a repository and return file names
|
|
16
|
+
*/
|
|
17
|
+
export async function scanRepoFolder(octokit, owner, repo, path, branch) {
|
|
18
|
+
try {
|
|
19
|
+
const { data } = await octokit.rest.repos.getContent({
|
|
20
|
+
owner,
|
|
21
|
+
repo,
|
|
22
|
+
path,
|
|
23
|
+
ref: branch,
|
|
24
|
+
});
|
|
25
|
+
if (!Array.isArray(data)) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
return data
|
|
29
|
+
.filter((item) => item.type === 'file' && item.name.endsWith('.md'))
|
|
30
|
+
.map((item) => item.name);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
// 404 = folder doesn't exist, which is fine
|
|
34
|
+
if (error.status === 404) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get file content from repository
|
|
42
|
+
*/
|
|
43
|
+
export async function getFileContent(octokit, owner, repo, path, branch) {
|
|
44
|
+
try {
|
|
45
|
+
const { data } = await octokit.rest.repos.getContent({
|
|
46
|
+
owner,
|
|
47
|
+
repo,
|
|
48
|
+
path,
|
|
49
|
+
ref: branch,
|
|
50
|
+
});
|
|
51
|
+
if (Array.isArray(data)) {
|
|
52
|
+
return null; // It's a directory
|
|
53
|
+
}
|
|
54
|
+
if (data.type !== 'file' || !data.content) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return Buffer.from(data.content, 'base64').toString('utf-8');
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Extract metadata value from markdown content
|
|
65
|
+
* Supports both table format and inline format
|
|
66
|
+
*/
|
|
67
|
+
function extractMetadata(content, field) {
|
|
68
|
+
// Table format: | **Field** | `value` | or | **Field** | value |
|
|
69
|
+
const tableMatch = content.match(new RegExp(`\\|\\s*\\*\\*${field}\\*\\*\\s*\\|\\s*\`?([^\`|\\n]+)\`?\\s*\\|`, 'i'));
|
|
70
|
+
if (tableMatch && tableMatch[1]) {
|
|
71
|
+
return tableMatch[1].trim();
|
|
72
|
+
}
|
|
73
|
+
// Inline format: **Field:** value or **Field**: value
|
|
74
|
+
const inlineMatch = content.match(new RegExp(`\\*\\*${field}:?\\*\\*:?\\s*(.+)`, 'i'));
|
|
75
|
+
if (inlineMatch && inlineMatch[1]) {
|
|
76
|
+
return inlineMatch[1].trim();
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse plan metadata from markdown content
|
|
82
|
+
*/
|
|
83
|
+
export function parsePlanMetadata(filename, content) {
|
|
84
|
+
const id = filename.replace('.md', '');
|
|
85
|
+
// Extract title from first heading
|
|
86
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
87
|
+
const title = titleMatch && titleMatch[1] ? titleMatch[1].trim() : undefined;
|
|
88
|
+
// Extract metadata fields
|
|
89
|
+
const sourceScope = extractMetadata(content, 'Source Scope');
|
|
90
|
+
const status = extractMetadata(content, 'Status');
|
|
91
|
+
const blockedBy = extractMetadata(content, 'Blocked By');
|
|
92
|
+
const assignedTo = extractMetadata(content, 'Assigned To');
|
|
93
|
+
// Parse Part: X of Y format
|
|
94
|
+
const partStr = extractMetadata(content, 'Part');
|
|
95
|
+
let partNumber = null;
|
|
96
|
+
let totalParts = null;
|
|
97
|
+
if (partStr) {
|
|
98
|
+
const partMatch = partStr.match(/(\d+)\s*of\s*(\d+)/i);
|
|
99
|
+
if (partMatch && partMatch[1] && partMatch[2]) {
|
|
100
|
+
partNumber = parseInt(partMatch[1], 10);
|
|
101
|
+
totalParts = parseInt(partMatch[2], 10);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Determine if blocked
|
|
105
|
+
const blocked = status?.toLowerCase() === 'blocked' || !!blockedBy;
|
|
106
|
+
return {
|
|
107
|
+
id,
|
|
108
|
+
filename,
|
|
109
|
+
title,
|
|
110
|
+
sourceScope,
|
|
111
|
+
status,
|
|
112
|
+
blocked,
|
|
113
|
+
blockedBy: blocked ? blockedBy : null,
|
|
114
|
+
partNumber,
|
|
115
|
+
totalParts,
|
|
116
|
+
assignedTo: assignedTo || undefined,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Extract scope ID from filename
|
|
121
|
+
*/
|
|
122
|
+
function extractScopeId(filename) {
|
|
123
|
+
// Match SCOPE-XXX pattern
|
|
124
|
+
const match = filename.match(/(SCOPE-\d{3})/);
|
|
125
|
+
return match && match[1] ? match[1] : filename.replace('.md', '');
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Calculate scope statuses from scanned data
|
|
129
|
+
*/
|
|
130
|
+
export function calculateScopeStatuses(incomingScopes, activePlans, completedPlans) {
|
|
131
|
+
const statuses = {};
|
|
132
|
+
// Process completed plans first
|
|
133
|
+
for (const plan of completedPlans) {
|
|
134
|
+
if (!plan.sourceScope)
|
|
135
|
+
continue;
|
|
136
|
+
const scopeId = plan.sourceScope;
|
|
137
|
+
if (!statuses[scopeId]) {
|
|
138
|
+
statuses[scopeId] = {
|
|
139
|
+
status: 'completed',
|
|
140
|
+
parts: [],
|
|
141
|
+
plans: [],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
statuses[scopeId].plans.push(plan.id);
|
|
145
|
+
if (plan.partNumber && plan.totalParts) {
|
|
146
|
+
statuses[scopeId].parts.push({
|
|
147
|
+
part: plan.partNumber,
|
|
148
|
+
total: plan.totalParts,
|
|
149
|
+
status: 'completed',
|
|
150
|
+
planId: plan.id,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Process active plans (may override completed status)
|
|
155
|
+
for (const plan of activePlans) {
|
|
156
|
+
if (!plan.sourceScope)
|
|
157
|
+
continue;
|
|
158
|
+
const scopeId = plan.sourceScope;
|
|
159
|
+
if (!statuses[scopeId]) {
|
|
160
|
+
statuses[scopeId] = {
|
|
161
|
+
status: 'in_progress',
|
|
162
|
+
parts: [],
|
|
163
|
+
plans: [],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
// If there's an active plan, status is in_progress (not completed)
|
|
168
|
+
statuses[scopeId].status = 'in_progress';
|
|
169
|
+
}
|
|
170
|
+
statuses[scopeId].plans.push(plan.id);
|
|
171
|
+
if (plan.partNumber && plan.totalParts) {
|
|
172
|
+
statuses[scopeId].parts.push({
|
|
173
|
+
part: plan.partNumber,
|
|
174
|
+
total: plan.totalParts,
|
|
175
|
+
status: plan.blocked ? 'blocked' : 'in_progress',
|
|
176
|
+
planId: plan.id,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// Handle blocked status
|
|
180
|
+
if (plan.blocked) {
|
|
181
|
+
statuses[scopeId].blocked = true;
|
|
182
|
+
statuses[scopeId].blockedBy = plan.blockedBy;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Process incoming scopes (pending)
|
|
186
|
+
for (const scopeFile of incomingScopes) {
|
|
187
|
+
// Skip processed folder indicator
|
|
188
|
+
if (scopeFile === 'processed' || scopeFile.startsWith('.'))
|
|
189
|
+
continue;
|
|
190
|
+
const scopeId = extractScopeId(scopeFile);
|
|
191
|
+
if (!statuses[scopeId]) {
|
|
192
|
+
statuses[scopeId] = {
|
|
193
|
+
status: 'pending',
|
|
194
|
+
parts: [],
|
|
195
|
+
plans: [],
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Calculate completion percentages for split plans
|
|
200
|
+
for (const [, info] of Object.entries(statuses)) {
|
|
201
|
+
if (info.parts.length > 0) {
|
|
202
|
+
const firstPart = info.parts[0];
|
|
203
|
+
const totalParts = firstPart ? firstPart.total : 1;
|
|
204
|
+
const completedParts = info.parts.filter((p) => p.status === 'completed').length;
|
|
205
|
+
info.completionPercentage = Math.round((completedParts / totalParts) * 100);
|
|
206
|
+
// Only mark as completed if ALL parts are done
|
|
207
|
+
if (completedParts === totalParts) {
|
|
208
|
+
info.status = 'completed';
|
|
209
|
+
}
|
|
210
|
+
else if (info.blocked) {
|
|
211
|
+
info.status = 'blocked';
|
|
212
|
+
}
|
|
213
|
+
else if (completedParts > 0 || info.parts.some((p) => p.status === 'in_progress')) {
|
|
214
|
+
info.status = 'in_progress';
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return statuses;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Scan knowledge base entries
|
|
222
|
+
*/
|
|
223
|
+
export async function scanKnowledgeBase(octokit, owner, repo, branch, repoAlias) {
|
|
224
|
+
const entries = [];
|
|
225
|
+
try {
|
|
226
|
+
const files = await scanRepoFolder(octokit, owner, repo, SCAN_PATHS.knowledgeBase, branch);
|
|
227
|
+
for (const file of files) {
|
|
228
|
+
if (file === '_index.md')
|
|
229
|
+
continue;
|
|
230
|
+
const content = await getFileContent(octokit, owner, repo, `${SCAN_PATHS.knowledgeBase}/${file}`, branch);
|
|
231
|
+
if (content) {
|
|
232
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
233
|
+
const categoryMatch = extractMetadata(content, 'Category');
|
|
234
|
+
entries.push({
|
|
235
|
+
id: file.replace('.md', ''),
|
|
236
|
+
title: titleMatch && titleMatch[1] ? titleMatch[1].trim() : file.replace('.md', ''),
|
|
237
|
+
category: categoryMatch || 'general',
|
|
238
|
+
repo: repoAlias,
|
|
239
|
+
path: `${SCAN_PATHS.knowledgeBase}/${file}`,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// KB not found is not an error
|
|
246
|
+
}
|
|
247
|
+
return entries;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Sync a single repository
|
|
251
|
+
*/
|
|
252
|
+
export async function syncRepository(octokit, repo, options) {
|
|
253
|
+
const startTime = Date.now();
|
|
254
|
+
const warnings = [];
|
|
255
|
+
let filesScanned = 0;
|
|
256
|
+
try {
|
|
257
|
+
// Scan incoming scopes
|
|
258
|
+
const incomingScopes = await scanRepoFolder(octokit, repo.owner, repo.name, SCAN_PATHS.incomingScopes, repo.branch);
|
|
259
|
+
filesScanned += incomingScopes.length;
|
|
260
|
+
// Scan active plans
|
|
261
|
+
const activePlanFiles = await scanRepoFolder(octokit, repo.owner, repo.name, SCAN_PATHS.activePlans, repo.branch);
|
|
262
|
+
filesScanned += activePlanFiles.length;
|
|
263
|
+
// Parse active plans
|
|
264
|
+
const activePlans = [];
|
|
265
|
+
for (const file of activePlanFiles) {
|
|
266
|
+
const content = await getFileContent(octokit, repo.owner, repo.name, `${SCAN_PATHS.activePlans}/${file}`, repo.branch);
|
|
267
|
+
if (content) {
|
|
268
|
+
const plan = parsePlanMetadata(file, content);
|
|
269
|
+
if (!plan.sourceScope) {
|
|
270
|
+
warnings.push(`Plan ${plan.id} has no Source Scope`);
|
|
271
|
+
}
|
|
272
|
+
activePlans.push(plan);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// Scan completed plans
|
|
276
|
+
const completedPlanFiles = await scanRepoFolder(octokit, repo.owner, repo.name, SCAN_PATHS.completedPlans, repo.branch);
|
|
277
|
+
filesScanned += completedPlanFiles.length;
|
|
278
|
+
// Parse completed plans
|
|
279
|
+
const completedPlans = [];
|
|
280
|
+
for (const file of completedPlanFiles) {
|
|
281
|
+
const content = await getFileContent(octokit, repo.owner, repo.name, `${SCAN_PATHS.completedPlans}/${file}`, repo.branch);
|
|
282
|
+
if (content) {
|
|
283
|
+
const plan = parsePlanMetadata(file, content);
|
|
284
|
+
if (!plan.sourceScope) {
|
|
285
|
+
warnings.push(`Plan ${plan.id} has no Source Scope`);
|
|
286
|
+
}
|
|
287
|
+
completedPlans.push(plan);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// Calculate scope statuses
|
|
291
|
+
const scopeStatus = calculateScopeStatuses(incomingScopes, activePlans, completedPlans);
|
|
292
|
+
// Sync knowledge base
|
|
293
|
+
let kbEntries = 0;
|
|
294
|
+
if (options.kbEnabled) {
|
|
295
|
+
const entries = await scanKnowledgeBase(octokit, repo.owner, repo.name, repo.branch, repo.alias);
|
|
296
|
+
kbEntries = entries.length;
|
|
297
|
+
}
|
|
298
|
+
const duration = Date.now() - startTime;
|
|
299
|
+
return {
|
|
300
|
+
repo: repo.name,
|
|
301
|
+
alias: repo.alias,
|
|
302
|
+
success: true,
|
|
303
|
+
filesScanned,
|
|
304
|
+
incomingScopes,
|
|
305
|
+
activePlans,
|
|
306
|
+
completedPlans,
|
|
307
|
+
scopeStatus,
|
|
308
|
+
kbEntries,
|
|
309
|
+
warnings,
|
|
310
|
+
duration,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
const duration = Date.now() - startTime;
|
|
315
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
316
|
+
return {
|
|
317
|
+
repo: repo.name,
|
|
318
|
+
alias: repo.alias,
|
|
319
|
+
success: false,
|
|
320
|
+
error: errorMessage,
|
|
321
|
+
filesScanned,
|
|
322
|
+
incomingScopes: [],
|
|
323
|
+
activePlans: [],
|
|
324
|
+
completedPlans: [],
|
|
325
|
+
scopeStatus: {},
|
|
326
|
+
kbEntries: 0,
|
|
327
|
+
warnings,
|
|
328
|
+
duration,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Retry wrapper for network operations
|
|
334
|
+
*/
|
|
335
|
+
export async function withRetry(fn, maxRetries, delayMs) {
|
|
336
|
+
let lastError;
|
|
337
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
338
|
+
try {
|
|
339
|
+
return await fn();
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
343
|
+
// Check for rate limit
|
|
344
|
+
if (error.status === 403) {
|
|
345
|
+
const resetHeader = error
|
|
346
|
+
.response?.headers?.['x-ratelimit-reset'];
|
|
347
|
+
if (resetHeader) {
|
|
348
|
+
const resetTime = parseInt(resetHeader, 10) * 1000;
|
|
349
|
+
const waitTime = Math.max(0, resetTime - Date.now());
|
|
350
|
+
if (waitTime > 0 && waitTime < 60000) {
|
|
351
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime + 1000));
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
// Retry on network errors
|
|
357
|
+
if (attempt < maxRetries) {
|
|
358
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs * attempt));
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
throw lastError || new Error('Max retries exceeded');
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../../src/core/sync/scanner.ts"],"names":[],"mappings":"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"}
|