claude-brain 0.30.2 → 0.30.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +241 -191
- package/VERSION +1 -1
- package/assets/CLAUDE-unified.md +11 -11
- package/assets/CLAUDE.md +29 -29
- package/package.json +7 -3
- package/packs/backend/node.json +173 -173
- package/packs/core/javascript.json +176 -176
- package/packs/core/typescript.json +222 -222
- package/packs/frontend/react.json +254 -254
- package/packs/meta/testing.json +172 -172
- package/scripts/postinstall.mjs +531 -531
- package/src/automation/decision-detector.ts +452 -452
- package/src/automation/phase12-manager.ts +456 -456
- package/src/automation/proactive-recall.ts +373 -373
- package/src/automation/project-detector.ts +310 -310
- package/src/automation/repo-scanner.ts +210 -205
- package/src/cli/auto-setup.ts +75 -75
- package/src/cli/auto-start.ts +266 -266
- package/src/cli/bin.ts +264 -264
- package/src/cli/commands/autostart.ts +90 -90
- package/src/cli/commands/chroma.ts +578 -577
- package/src/cli/commands/export-training.ts +70 -70
- package/src/cli/commands/export.ts +130 -130
- package/src/cli/commands/git-hook.ts +183 -183
- package/src/cli/commands/hooks.ts +217 -217
- package/src/cli/commands/init.ts +123 -123
- package/src/cli/commands/install-mcp.ts +122 -111
- package/src/cli/commands/models.ts +979 -979
- package/src/cli/commands/pack.ts +200 -200
- package/src/cli/commands/refresh.ts +344 -339
- package/src/cli/commands/reindex.ts +120 -120
- package/src/cli/commands/serve.ts +466 -463
- package/src/cli/commands/start.ts +44 -44
- package/src/cli/commands/status.ts +220 -203
- package/src/cli/commands/uninstall-mcp.ts +45 -41
- package/src/cli/commands/update.ts +130 -124
- package/src/cli/migrate-chroma.ts +106 -106
- package/src/cli/ui/animations.ts +80 -80
- package/src/cli/ui/components.ts +82 -82
- package/src/cli/ui/index.ts +4 -4
- package/src/cli/ui/logo.ts +36 -36
- package/src/cli/ui/theme.ts +55 -55
- package/src/code-intelligence/indexer.ts +352 -352
- package/src/code-intelligence/linker.ts +178 -178
- package/src/code-intelligence/parser.ts +484 -484
- package/src/code-intelligence/query.ts +291 -291
- package/src/code-intelligence/schema.ts +83 -83
- package/src/code-intelligence/types.ts +95 -95
- package/src/config/defaults.ts +52 -52
- package/src/config/home.ts +56 -56
- package/src/config/index.ts +5 -5
- package/src/config/loader.ts +192 -192
- package/src/config/schema.ts +446 -415
- package/src/config/validator.ts +182 -182
- package/src/context/assembler.ts +407 -400
- package/src/context/index.ts +79 -79
- package/src/context/progress-tracker.ts +174 -174
- package/src/context/standards-manager.ts +287 -287
- package/src/context/validator.ts +58 -58
- package/src/diagnostics/index.ts +122 -121
- package/src/health/index.ts +233 -232
- package/src/hooks/brain-hook.ts +134 -131
- package/src/hooks/capture.ts +168 -168
- package/src/hooks/claude-code-mastery.md +112 -112
- package/src/hooks/context-hook.ts +260 -245
- package/src/hooks/deduplicator.ts +72 -72
- package/src/hooks/git-capture.ts +109 -109
- package/src/hooks/git-hook-installer.ts +211 -207
- package/src/hooks/index.ts +20 -20
- package/src/hooks/installer.ts +306 -288
- package/src/hooks/interceptor-hook.ts +204 -201
- package/src/hooks/passive-classifier.ts +397 -397
- package/src/hooks/queue.ts +160 -129
- package/src/hooks/session-tracker.ts +312 -312
- package/src/hooks/types.ts +52 -52
- package/src/index.ts +7 -7
- package/src/intelligence/cross-project/generalizer.ts +283 -283
- package/src/intelligence/cross-project/index.ts +7 -7
- package/src/intelligence/hf-downloader.ts +222 -222
- package/src/intelligence/hf-manifest.json +78 -78
- package/src/intelligence/index.ts +24 -24
- package/src/intelligence/inference-router.ts +762 -762
- package/src/intelligence/model-manager.ts +263 -245
- package/src/intelligence/optimization/index.ts +10 -10
- package/src/intelligence/optimization/precompute.ts +202 -202
- package/src/intelligence/optimization/semantic-cache.ts +213 -207
- package/src/intelligence/prediction/index.ts +7 -7
- package/src/intelligence/prediction/recommender.ts +276 -268
- package/src/intelligence/reasoning/chain-retrieval.ts +243 -247
- package/src/intelligence/reasoning/index.ts +7 -7
- package/src/intelligence/temporal/evolution.ts +193 -197
- package/src/intelligence/temporal/index.ts +16 -16
- package/src/intelligence/temporal/query-processor.ts +190 -190
- package/src/intelligence/temporal/timeline.ts +272 -259
- package/src/intelligence/temporal/trends.ts +263 -263
- package/src/intelligence/tokenizer.ts +118 -118
- package/src/knowledge/entity-extractor.ts +447 -443
- package/src/knowledge/graph/builder.ts +185 -185
- package/src/knowledge/graph/linker.ts +201 -201
- package/src/knowledge/graph/memory-graph.ts +359 -359
- package/src/knowledge/graph/schema.ts +99 -99
- package/src/knowledge/graph/search.ts +166 -166
- package/src/knowledge/relationship-extractor.ts +108 -108
- package/src/memory/chroma/client.ts +211 -192
- package/src/memory/chroma/collection-manager.ts +92 -92
- package/src/memory/chroma/config.ts +57 -57
- package/src/memory/chroma/embeddings.ts +177 -175
- package/src/memory/chroma/index.ts +82 -82
- package/src/memory/chroma/migration.ts +270 -270
- package/src/memory/chroma/schemas.ts +69 -69
- package/src/memory/chroma/search.ts +319 -315
- package/src/memory/chroma/store.ts +755 -747
- package/src/memory/compression.ts +121 -121
- package/src/memory/consolidation/archiver.ts +162 -165
- package/src/memory/consolidation/merger.ts +182 -186
- package/src/memory/consolidation/scorer.ts +136 -136
- package/src/memory/database.ts +9 -0
- package/src/memory/dual-write.ts +145 -0
- package/src/memory/embeddings.ts +226 -226
- package/src/memory/episodic/detector.ts +108 -108
- package/src/memory/episodic/manager.ts +347 -351
- package/src/memory/episodic/summarizer.ts +179 -179
- package/src/memory/episodic/types.ts +52 -52
- package/src/memory/fts5-search.ts +692 -633
- package/src/memory/index.ts +943 -1060
- package/src/memory/migrations/add-fts5.ts +118 -108
- package/src/memory/patterns.ts +438 -438
- package/src/memory/pruning.ts +60 -60
- package/src/memory/schema.ts +88 -88
- package/src/memory/store.ts +911 -787
- package/src/orchestrator/handlers/decision-handler.ts +204 -204
- package/src/packs/index.ts +9 -9
- package/src/packs/loader.ts +134 -134
- package/src/packs/manager.ts +204 -204
- package/src/packs/ranker.ts +78 -78
- package/src/packs/types.ts +81 -81
- package/src/phase12/index.ts +5 -5
- package/src/retrieval/bm25/index.ts +300 -297
- package/src/retrieval/bm25/tokenizer.ts +184 -184
- package/src/retrieval/feedback/adaptive.ts +221 -221
- package/src/retrieval/feedback/index.ts +16 -16
- package/src/retrieval/feedback/metrics.ts +221 -221
- package/src/retrieval/feedback/store.ts +283 -283
- package/src/retrieval/fusion/index.ts +194 -194
- package/src/retrieval/fusion/rrf.ts +165 -165
- package/src/retrieval/index.ts +12 -12
- package/src/retrieval/pipeline.ts +375 -375
- package/src/retrieval/query/expander.ts +203 -203
- package/src/retrieval/query/index.ts +27 -27
- package/src/retrieval/query/intent-classifier.ts +252 -252
- package/src/retrieval/query/temporal-parser.ts +295 -295
- package/src/retrieval/reranker/index.ts +189 -188
- package/src/retrieval/reranker/model.ts +99 -95
- package/src/retrieval/service.ts +125 -125
- package/src/retrieval/types.ts +162 -162
- package/src/routing/entity-extractor.ts +454 -454
- package/src/routing/handlers/exploration-handler.ts +369 -0
- package/src/routing/handlers/index.ts +19 -0
- package/src/routing/handlers/memory-handler.ts +273 -0
- package/src/routing/handlers/mutation-handler.ts +241 -0
- package/src/routing/handlers/recall-handler.ts +642 -0
- package/src/routing/handlers/shared.ts +515 -0
- package/src/routing/handlers/types.ts +48 -0
- package/src/routing/intent-classifier.ts +552 -552
- package/src/routing/response-filter.ts +399 -391
- package/src/routing/router.ts +245 -2193
- package/src/routing/search-engine.ts +521 -514
- package/src/routing/types.ts +104 -94
- package/src/scripts/health-check.ts +118 -118
- package/src/scripts/setup.ts +122 -122
- package/src/server/auto-updater.ts +283 -276
- package/src/server/handlers/call-tool.ts +159 -159
- package/src/server/handlers/list-tools.ts +35 -35
- package/src/server/handlers/tools/auto-remember.ts +165 -165
- package/src/server/handlers/tools/brain.ts +86 -86
- package/src/server/handlers/tools/create-project.ts +135 -135
- package/src/server/handlers/tools/get-code-standards.ts +123 -123
- package/src/server/handlers/tools/get-corrections.ts +152 -152
- package/src/server/handlers/tools/get-patterns.ts +156 -156
- package/src/server/handlers/tools/get-project-context.ts +75 -75
- package/src/server/handlers/tools/index.ts +30 -30
- package/src/server/handlers/tools/init-project.ts +756 -756
- package/src/server/handlers/tools/list-projects.ts +126 -126
- package/src/server/handlers/tools/recall-similar.ts +87 -87
- package/src/server/handlers/tools/recognize-pattern.ts +132 -132
- package/src/server/handlers/tools/record-correction.ts +131 -131
- package/src/server/handlers/tools/remember-decision.ts +168 -168
- package/src/server/handlers/tools/schemas.ts +179 -179
- package/src/server/handlers/tools/search-code.ts +122 -122
- package/src/server/handlers/tools/smart-context.ts +146 -146
- package/src/server/handlers/tools/update-progress.ts +131 -131
- package/src/server/http-api.ts +215 -1229
- package/src/server/mcp-proxy.ts +85 -84
- package/src/server/mcp-server.ts +285 -284
- package/src/server/middleware/auth.ts +39 -0
- package/src/server/middleware/error-handler.ts +37 -0
- package/src/server/middleware/rate-limit.ts +53 -0
- package/src/server/middleware/validate.ts +42 -0
- package/src/server/pid-manager.ts +137 -136
- package/src/server/providers/resources.ts +581 -581
- package/src/server/routes/code.ts +228 -0
- package/src/server/routes/context.ts +26 -0
- package/src/server/routes/health.ts +19 -0
- package/src/server/routes/helpers.ts +100 -0
- package/src/server/routes/hooks.ts +197 -0
- package/src/server/routes/mcp.ts +47 -0
- package/src/server/routes/memory.ts +397 -0
- package/src/server/routes/models.ts +96 -0
- package/src/server/routes/projects.ts +89 -0
- package/src/server/routes/types.ts +21 -0
- package/src/server/schemas/api-schemas.ts +202 -0
- package/src/server/services.ts +720 -720
- package/src/server/utils/memory-indicator.ts +84 -84
- package/src/server/utils/response-formatter.ts +129 -129
- package/src/server/web-viewer.ts +1145 -1115
- package/src/setup/index.ts +38 -38
- package/src/tools/registry.ts +115 -115
- package/src/tools/schemas.ts +666 -666
- package/src/tools/types.ts +412 -412
- package/src/training/data-store.ts +320 -298
- package/src/training/retrain-pipeline.ts +399 -394
- package/src/utils/error-handler.ts +136 -136
- package/src/utils/index.ts +58 -58
- package/src/utils/kill-port.ts +55 -53
- package/src/utils/phase12-helper.ts +56 -56
- package/src/utils/safe-path.ts +43 -0
- package/src/utils/timing.ts +47 -47
- package/src/utils/transaction.ts +63 -63
- package/src/vault/index.ts +4 -3
- package/src/vault/paths.ts +106 -106
- package/src/vault/query.ts +4 -1
- package/src/vault/reader.ts +44 -1
- package/src/vault/watcher.ts +24 -1
- package/src/vault/writer.ts +487 -413
- package/skills/persistent-memory/SKILL.md +0 -148
- package/skills/persistent-memory/references/tool-reference.md +0 -90
package/src/context/index.ts
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Context Management System
|
|
3
|
-
* Main module that combines all context components
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Logger } from 'pino'
|
|
7
|
-
import type { VaultManager } from '@/vault'
|
|
8
|
-
import type { MemoryManager } from '@/memory'
|
|
9
|
-
import { ContextAssembler } from './assembler'
|
|
10
|
-
import { ContextFormatter } from './formatter'
|
|
11
|
-
import { StandardsManager } from './standards-manager'
|
|
12
|
-
import { ProgressTracker } from './progress-tracker'
|
|
13
|
-
import { ContextCacheManager } from './cache-manager'
|
|
14
|
-
import type { ContextOptions, AssembledContext } from './types'
|
|
15
|
-
|
|
16
|
-
export * from './types'
|
|
17
|
-
export * from './assembler'
|
|
18
|
-
export * from './formatter'
|
|
19
|
-
export * from './standards-manager'
|
|
20
|
-
export * from './progress-tracker'
|
|
21
|
-
export * from './cache-manager'
|
|
22
|
-
export * from './hierarchy'
|
|
23
|
-
export * from './validator'
|
|
24
|
-
|
|
25
|
-
export class ContextManager {
|
|
26
|
-
readonly assembler: ContextAssembler
|
|
27
|
-
readonly formatter: typeof ContextFormatter
|
|
28
|
-
readonly standards: StandardsManager
|
|
29
|
-
readonly progress: ProgressTracker
|
|
30
|
-
readonly cache: ContextCacheManager
|
|
31
|
-
|
|
32
|
-
constructor(
|
|
33
|
-
logger: Logger,
|
|
34
|
-
vault: VaultManager,
|
|
35
|
-
memory: MemoryManager
|
|
36
|
-
) {
|
|
37
|
-
this.assembler = new ContextAssembler(logger, vault, memory)
|
|
38
|
-
this.formatter = ContextFormatter
|
|
39
|
-
this.standards = new StandardsManager(logger, vault)
|
|
40
|
-
this.progress = new ProgressTracker(logger, vault)
|
|
41
|
-
this.cache = new ContextCacheManager(logger)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async getContext(
|
|
45
|
-
projectName: string,
|
|
46
|
-
options?: ContextOptions
|
|
47
|
-
): Promise<AssembledContext> {
|
|
48
|
-
const cached = this.cache.get(projectName)
|
|
49
|
-
if (cached && !options?.maxTokens) {
|
|
50
|
-
return cached
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const context = await this.assembler.assembleContext(projectName, options)
|
|
54
|
-
|
|
55
|
-
const dependencies = context.metadata.sources
|
|
56
|
-
this.cache.set(projectName, context, dependencies)
|
|
57
|
-
|
|
58
|
-
return context
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async getFormattedContext(
|
|
62
|
-
projectName: string,
|
|
63
|
-
options?: ContextOptions
|
|
64
|
-
): Promise<string> {
|
|
65
|
-
const context = await this.getContext(projectName, options)
|
|
66
|
-
return this.formatter.format(context)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
invalidateContext(projectName: string): void {
|
|
70
|
-
this.cache.invalidate(projectName)
|
|
71
|
-
this.standards.clearCache()
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
getStats() {
|
|
75
|
-
return {
|
|
76
|
-
cache: this.cache.getStats()
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Context Management System
|
|
3
|
+
* Main module that combines all context components
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { VaultManager } from '@/vault'
|
|
8
|
+
import type { MemoryManager } from '@/memory'
|
|
9
|
+
import { ContextAssembler } from './assembler'
|
|
10
|
+
import { ContextFormatter } from './formatter'
|
|
11
|
+
import { StandardsManager } from './standards-manager'
|
|
12
|
+
import { ProgressTracker } from './progress-tracker'
|
|
13
|
+
import { ContextCacheManager } from './cache-manager'
|
|
14
|
+
import type { ContextOptions, AssembledContext } from './types'
|
|
15
|
+
|
|
16
|
+
export * from './types'
|
|
17
|
+
export * from './assembler'
|
|
18
|
+
export * from './formatter'
|
|
19
|
+
export * from './standards-manager'
|
|
20
|
+
export * from './progress-tracker'
|
|
21
|
+
export * from './cache-manager'
|
|
22
|
+
export * from './hierarchy'
|
|
23
|
+
export * from './validator'
|
|
24
|
+
|
|
25
|
+
export class ContextManager {
|
|
26
|
+
readonly assembler: ContextAssembler
|
|
27
|
+
readonly formatter: typeof ContextFormatter
|
|
28
|
+
readonly standards: StandardsManager
|
|
29
|
+
readonly progress: ProgressTracker
|
|
30
|
+
readonly cache: ContextCacheManager
|
|
31
|
+
|
|
32
|
+
constructor(
|
|
33
|
+
logger: Logger,
|
|
34
|
+
vault: VaultManager,
|
|
35
|
+
memory: MemoryManager
|
|
36
|
+
) {
|
|
37
|
+
this.assembler = new ContextAssembler(logger, vault, memory)
|
|
38
|
+
this.formatter = ContextFormatter
|
|
39
|
+
this.standards = new StandardsManager(logger, vault)
|
|
40
|
+
this.progress = new ProgressTracker(logger, vault)
|
|
41
|
+
this.cache = new ContextCacheManager(logger)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async getContext(
|
|
45
|
+
projectName: string,
|
|
46
|
+
options?: ContextOptions
|
|
47
|
+
): Promise<AssembledContext> {
|
|
48
|
+
const cached = this.cache.get(projectName)
|
|
49
|
+
if (cached && !options?.maxTokens) {
|
|
50
|
+
return cached
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const context = await this.assembler.assembleContext(projectName, options)
|
|
54
|
+
|
|
55
|
+
const dependencies = context.metadata.sources
|
|
56
|
+
this.cache.set(projectName, context, dependencies)
|
|
57
|
+
|
|
58
|
+
return context
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async getFormattedContext(
|
|
62
|
+
projectName: string,
|
|
63
|
+
options?: ContextOptions
|
|
64
|
+
): Promise<string> {
|
|
65
|
+
const context = await this.getContext(projectName, options)
|
|
66
|
+
return this.formatter.format(context)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
invalidateContext(projectName: string): void {
|
|
70
|
+
this.cache.invalidate(projectName)
|
|
71
|
+
this.standards.clearCache()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getStats() {
|
|
75
|
+
return {
|
|
76
|
+
cache: this.cache.getStats()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -1,174 +1,174 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Progress Tracker
|
|
3
|
-
* Monitors and reports project development progress
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Logger } from 'pino'
|
|
7
|
-
import type { VaultManager } from '@/vault'
|
|
8
|
-
import type { ProgressState, TaskSummary, Blocker } from './types'
|
|
9
|
-
|
|
10
|
-
export class ProgressTracker {
|
|
11
|
-
private logger: Logger
|
|
12
|
-
private vault: VaultManager
|
|
13
|
-
|
|
14
|
-
constructor(logger: Logger, vault: VaultManager) {
|
|
15
|
-
this.logger = logger.child({ component: 'progress-tracker' })
|
|
16
|
-
this.vault = vault
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async getProgress(projectName: string): Promise<ProgressState> {
|
|
20
|
-
try {
|
|
21
|
-
const projectPaths = this.vault.getProjectPaths(projectName)
|
|
22
|
-
const file = await this.vault.reader.readMarkdownFile(projectPaths.progress)
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
currentPhase: file.frontmatter.current_phase as string || 'unknown',
|
|
26
|
-
completionPercentage: (file.frontmatter.completion_percentage as number) || 0,
|
|
27
|
-
completedTasks: this.parseCompletedTasks(file.content),
|
|
28
|
-
currentTasks: this.parseCurrentTasks(file.content),
|
|
29
|
-
nextSteps: this.extractNextSteps(file.content),
|
|
30
|
-
blockers: this.parseBlockers(file.content),
|
|
31
|
-
velocity: this.calculateVelocity(file.content)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
} catch (error) {
|
|
35
|
-
this.logger.error({ error, projectName }, 'Failed to get progress')
|
|
36
|
-
return this.createEmptyProgress()
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async updateProgress(
|
|
41
|
-
projectName: string,
|
|
42
|
-
updates: Partial<ProgressState>
|
|
43
|
-
): Promise<void> {
|
|
44
|
-
try {
|
|
45
|
-
const projectPaths = this.vault.getProjectPaths(projectName)
|
|
46
|
-
|
|
47
|
-
await this.vault.writer.updateFrontmatter(projectPaths.progress, {
|
|
48
|
-
current_phase: updates.currentPhase,
|
|
49
|
-
completion_percentage: updates.completionPercentage,
|
|
50
|
-
last_updated: new Date().toISOString().split('T')[0]
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
this.logger.info({ projectName }, 'Progress updated')
|
|
54
|
-
|
|
55
|
-
} catch (error) {
|
|
56
|
-
this.logger.error({ error, projectName }, 'Failed to update progress')
|
|
57
|
-
throw error
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async addCompletedTask(
|
|
62
|
-
projectName: string,
|
|
63
|
-
task: TaskSummary
|
|
64
|
-
): Promise<void> {
|
|
65
|
-
try {
|
|
66
|
-
const projectPaths = this.vault.getProjectPaths(projectName)
|
|
67
|
-
|
|
68
|
-
const entry = `\n- [x] ${task.title} (completed ${task.completedAt?.toLocaleDateString()})`
|
|
69
|
-
|
|
70
|
-
await this.vault.writer.appendContent(projectPaths.progress, entry, '\n')
|
|
71
|
-
|
|
72
|
-
this.logger.info({ projectName, task: task.title }, 'Task marked complete')
|
|
73
|
-
|
|
74
|
-
} catch (error) {
|
|
75
|
-
this.logger.error({ error, projectName }, 'Failed to add completed task')
|
|
76
|
-
throw error
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
private parseCompletedTasks(content: string): TaskSummary[] {
|
|
81
|
-
const tasks: TaskSummary[] = []
|
|
82
|
-
const completedRegex = /^[-*]\s+\[x\]\s+(.+?)(?:\(completed (.+?)\))?$/gim
|
|
83
|
-
|
|
84
|
-
let match
|
|
85
|
-
while ((match = completedRegex.exec(content)) !== null) {
|
|
86
|
-
tasks.push({
|
|
87
|
-
id: (match[1] ?? '').toLowerCase().replace(/[^a-z0-9]+/g, '-').slice(0, 50),
|
|
88
|
-
title: (match[1] ?? '').trim(),
|
|
89
|
-
status: 'done',
|
|
90
|
-
completedAt: match[2] ? new Date(match[2]) : undefined
|
|
91
|
-
})
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return tasks
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private parseCurrentTasks(content: string): TaskSummary[] {
|
|
98
|
-
const tasks: TaskSummary[] = []
|
|
99
|
-
const currentRegex = /^[-*]\s+\[([ >])\]\s+(.+?)$/gim
|
|
100
|
-
|
|
101
|
-
let match
|
|
102
|
-
while ((match = currentRegex.exec(content)) !== null) {
|
|
103
|
-
const status = match[1] === '>' ? 'in-progress' : 'todo'
|
|
104
|
-
tasks.push({
|
|
105
|
-
id: (match[2] ?? '').toLowerCase().replace(/[^a-z0-9]+/g, '-').slice(0, 50),
|
|
106
|
-
title: (match[2] ?? '').trim(),
|
|
107
|
-
status
|
|
108
|
-
})
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return tasks
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private extractNextSteps(content: string): string[] {
|
|
115
|
-
const section = /##\s+Next Steps\s+(.+?)(?=\n##|$)/is.exec(content)
|
|
116
|
-
if (!section) return []
|
|
117
|
-
|
|
118
|
-
const steps: string[] = []
|
|
119
|
-
const listRegex = /^[-*]\s+(.+)$/gm
|
|
120
|
-
|
|
121
|
-
let match
|
|
122
|
-
while ((match = listRegex.exec(section[1]!)) !== null) {
|
|
123
|
-
steps.push((match[1] ?? '').trim())
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return steps
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
private parseBlockers(content: string): Blocker[] {
|
|
130
|
-
const section = /##\s+Blockers\s+(.+?)(?=\n##|$)/is.exec(content)
|
|
131
|
-
if (!section) return []
|
|
132
|
-
|
|
133
|
-
const blockers: Blocker[] = []
|
|
134
|
-
const blockerRegex = /^[-*]\s+\[(\w+)\]\s+(.+?)(?:\(since (.+?)\))?$/gim
|
|
135
|
-
|
|
136
|
-
let match
|
|
137
|
-
while ((match = blockerRegex.exec(section[1]!)) !== null) {
|
|
138
|
-
blockers.push({
|
|
139
|
-
description: (match[2] ?? '').trim(),
|
|
140
|
-
severity: (match[1] ?? '').toLowerCase() as any,
|
|
141
|
-
since: match[3] ? new Date(match[3]) : new Date()
|
|
142
|
-
})
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return blockers
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
private calculateVelocity(content: string): number {
|
|
149
|
-
const completedTasks = this.parseCompletedTasks(content)
|
|
150
|
-
|
|
151
|
-
if (completedTasks.length === 0) return 0
|
|
152
|
-
|
|
153
|
-
const oneWeekAgo = new Date()
|
|
154
|
-
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7)
|
|
155
|
-
|
|
156
|
-
const recentTasks = completedTasks.filter(task =>
|
|
157
|
-
task.completedAt && task.completedAt >= oneWeekAgo
|
|
158
|
-
)
|
|
159
|
-
|
|
160
|
-
return recentTasks.length
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private createEmptyProgress(): ProgressState {
|
|
164
|
-
return {
|
|
165
|
-
currentPhase: 'unknown',
|
|
166
|
-
completionPercentage: 0,
|
|
167
|
-
completedTasks: [],
|
|
168
|
-
currentTasks: [],
|
|
169
|
-
nextSteps: [],
|
|
170
|
-
blockers: [],
|
|
171
|
-
velocity: 0
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Progress Tracker
|
|
3
|
+
* Monitors and reports project development progress
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { VaultManager } from '@/vault'
|
|
8
|
+
import type { ProgressState, TaskSummary, Blocker } from './types'
|
|
9
|
+
|
|
10
|
+
export class ProgressTracker {
|
|
11
|
+
private logger: Logger
|
|
12
|
+
private vault: VaultManager
|
|
13
|
+
|
|
14
|
+
constructor(logger: Logger, vault: VaultManager) {
|
|
15
|
+
this.logger = logger.child({ component: 'progress-tracker' })
|
|
16
|
+
this.vault = vault
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async getProgress(projectName: string): Promise<ProgressState> {
|
|
20
|
+
try {
|
|
21
|
+
const projectPaths = this.vault.getProjectPaths(projectName)
|
|
22
|
+
const file = await this.vault.reader.readMarkdownFile(projectPaths.progress)
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
currentPhase: file.frontmatter.current_phase as string || 'unknown',
|
|
26
|
+
completionPercentage: (file.frontmatter.completion_percentage as number) || 0,
|
|
27
|
+
completedTasks: this.parseCompletedTasks(file.content),
|
|
28
|
+
currentTasks: this.parseCurrentTasks(file.content),
|
|
29
|
+
nextSteps: this.extractNextSteps(file.content),
|
|
30
|
+
blockers: this.parseBlockers(file.content),
|
|
31
|
+
velocity: this.calculateVelocity(file.content)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
} catch (error) {
|
|
35
|
+
this.logger.error({ error, projectName }, 'Failed to get progress')
|
|
36
|
+
return this.createEmptyProgress()
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async updateProgress(
|
|
41
|
+
projectName: string,
|
|
42
|
+
updates: Partial<ProgressState>
|
|
43
|
+
): Promise<void> {
|
|
44
|
+
try {
|
|
45
|
+
const projectPaths = this.vault.getProjectPaths(projectName)
|
|
46
|
+
|
|
47
|
+
await this.vault.writer.updateFrontmatter(projectPaths.progress, {
|
|
48
|
+
current_phase: updates.currentPhase,
|
|
49
|
+
completion_percentage: updates.completionPercentage,
|
|
50
|
+
last_updated: new Date().toISOString().split('T')[0]
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
this.logger.info({ projectName }, 'Progress updated')
|
|
54
|
+
|
|
55
|
+
} catch (error) {
|
|
56
|
+
this.logger.error({ error, projectName }, 'Failed to update progress')
|
|
57
|
+
throw error
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async addCompletedTask(
|
|
62
|
+
projectName: string,
|
|
63
|
+
task: TaskSummary
|
|
64
|
+
): Promise<void> {
|
|
65
|
+
try {
|
|
66
|
+
const projectPaths = this.vault.getProjectPaths(projectName)
|
|
67
|
+
|
|
68
|
+
const entry = `\n- [x] ${task.title} (completed ${task.completedAt?.toLocaleDateString()})`
|
|
69
|
+
|
|
70
|
+
await this.vault.writer.appendContent(projectPaths.progress, entry, '\n')
|
|
71
|
+
|
|
72
|
+
this.logger.info({ projectName, task: task.title }, 'Task marked complete')
|
|
73
|
+
|
|
74
|
+
} catch (error) {
|
|
75
|
+
this.logger.error({ error, projectName }, 'Failed to add completed task')
|
|
76
|
+
throw error
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private parseCompletedTasks(content: string): TaskSummary[] {
|
|
81
|
+
const tasks: TaskSummary[] = []
|
|
82
|
+
const completedRegex = /^[-*]\s+\[x\]\s+(.+?)(?:\(completed (.+?)\))?$/gim
|
|
83
|
+
|
|
84
|
+
let match
|
|
85
|
+
while ((match = completedRegex.exec(content)) !== null) {
|
|
86
|
+
tasks.push({
|
|
87
|
+
id: (match[1] ?? '').toLowerCase().replace(/[^a-z0-9]+/g, '-').slice(0, 50),
|
|
88
|
+
title: (match[1] ?? '').trim(),
|
|
89
|
+
status: 'done',
|
|
90
|
+
completedAt: match[2] ? new Date(match[2]) : undefined
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return tasks
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private parseCurrentTasks(content: string): TaskSummary[] {
|
|
98
|
+
const tasks: TaskSummary[] = []
|
|
99
|
+
const currentRegex = /^[-*]\s+\[([ >])\]\s+(.+?)$/gim
|
|
100
|
+
|
|
101
|
+
let match
|
|
102
|
+
while ((match = currentRegex.exec(content)) !== null) {
|
|
103
|
+
const status = match[1] === '>' ? 'in-progress' : 'todo'
|
|
104
|
+
tasks.push({
|
|
105
|
+
id: (match[2] ?? '').toLowerCase().replace(/[^a-z0-9]+/g, '-').slice(0, 50),
|
|
106
|
+
title: (match[2] ?? '').trim(),
|
|
107
|
+
status
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return tasks
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private extractNextSteps(content: string): string[] {
|
|
115
|
+
const section = /##\s+Next Steps\s+(.+?)(?=\n##|$)/is.exec(content)
|
|
116
|
+
if (!section) return []
|
|
117
|
+
|
|
118
|
+
const steps: string[] = []
|
|
119
|
+
const listRegex = /^[-*]\s+(.+)$/gm
|
|
120
|
+
|
|
121
|
+
let match
|
|
122
|
+
while ((match = listRegex.exec(section[1]!)) !== null) {
|
|
123
|
+
steps.push((match[1] ?? '').trim())
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return steps
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private parseBlockers(content: string): Blocker[] {
|
|
130
|
+
const section = /##\s+Blockers\s+(.+?)(?=\n##|$)/is.exec(content)
|
|
131
|
+
if (!section) return []
|
|
132
|
+
|
|
133
|
+
const blockers: Blocker[] = []
|
|
134
|
+
const blockerRegex = /^[-*]\s+\[(\w+)\]\s+(.+?)(?:\(since (.+?)\))?$/gim
|
|
135
|
+
|
|
136
|
+
let match
|
|
137
|
+
while ((match = blockerRegex.exec(section[1]!)) !== null) {
|
|
138
|
+
blockers.push({
|
|
139
|
+
description: (match[2] ?? '').trim(),
|
|
140
|
+
severity: (match[1] ?? '').toLowerCase() as any,
|
|
141
|
+
since: match[3] ? new Date(match[3]) : new Date()
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return blockers
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private calculateVelocity(content: string): number {
|
|
149
|
+
const completedTasks = this.parseCompletedTasks(content)
|
|
150
|
+
|
|
151
|
+
if (completedTasks.length === 0) return 0
|
|
152
|
+
|
|
153
|
+
const oneWeekAgo = new Date()
|
|
154
|
+
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7)
|
|
155
|
+
|
|
156
|
+
const recentTasks = completedTasks.filter(task =>
|
|
157
|
+
task.completedAt && task.completedAt >= oneWeekAgo
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
return recentTasks.length
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private createEmptyProgress(): ProgressState {
|
|
164
|
+
return {
|
|
165
|
+
currentPhase: 'unknown',
|
|
166
|
+
completionPercentage: 0,
|
|
167
|
+
completedTasks: [],
|
|
168
|
+
currentTasks: [],
|
|
169
|
+
nextSteps: [],
|
|
170
|
+
blockers: [],
|
|
171
|
+
velocity: 0
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|