prjct-cli 1.22.0 → 1.23.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/CHANGELOG.md +147 -0
- package/bin/prjct +30 -13
- package/dist/bin/prjct.mjs +917 -35845
- package/dist/bin/prjct.mjs.map +7 -0
- package/dist/cli/linear.mjs +16 -0
- package/dist/cli/linear.mjs.map +7 -0
- package/dist/templates.json +1 -0
- package/package.json +4 -5
- package/bin/prjct.ts +0 -342
- package/core/__tests__/agentic/analysis-injection.test.ts +0 -377
- package/core/__tests__/agentic/cache-eviction.test.ts +0 -294
- package/core/__tests__/agentic/command-context.test.ts +0 -281
- package/core/__tests__/agentic/command-executor.test.ts +0 -659
- package/core/__tests__/agentic/domain-classifier.test.ts +0 -330
- package/core/__tests__/agentic/injection-validator.test.ts +0 -255
- package/core/__tests__/agentic/memory-system.test.ts +0 -281
- package/core/__tests__/agentic/plan-mode.test.ts +0 -386
- package/core/__tests__/agentic/prompt-assembly.test.ts +0 -298
- package/core/__tests__/agentic/prompt-builder.test.ts +0 -243
- package/core/__tests__/agentic/response-validator.test.ts +0 -263
- package/core/__tests__/agentic/semantic-matching.test.ts +0 -131
- package/core/__tests__/agentic/smart-context.test.ts +0 -372
- package/core/__tests__/agentic/tech-normalizer.test.ts +0 -136
- package/core/__tests__/agentic/token-budget.test.ts +0 -294
- package/core/__tests__/ai-tools/formatters.test.ts +0 -476
- package/core/__tests__/domain/bm25.test.ts +0 -225
- package/core/__tests__/domain/change-propagator.test.ts +0 -100
- package/core/__tests__/domain/fibonacci.test.ts +0 -113
- package/core/__tests__/domain/file-hasher.test.ts +0 -146
- package/core/__tests__/domain/file-ranker.test.ts +0 -169
- package/core/__tests__/domain/git-cochange.test.ts +0 -121
- package/core/__tests__/domain/import-graph.test.ts +0 -156
- package/core/__tests__/domain/velocity.test.ts +0 -623
- package/core/__tests__/infrastructure/performance-tracker.test.ts +0 -328
- package/core/__tests__/schemas/model.test.ts +0 -272
- package/core/__tests__/services/dependency-validator.test.ts +0 -175
- package/core/__tests__/services/hierarchical-agent-resolver.test.ts +0 -359
- package/core/__tests__/services/nested-context-resolver.test.ts +0 -443
- package/core/__tests__/services/project-index.test.ts +0 -355
- package/core/__tests__/services/staleness-checker.test.ts +0 -204
- package/core/__tests__/storage/analysis-storage.test.ts +0 -641
- package/core/__tests__/storage/archive-storage.test.ts +0 -455
- package/core/__tests__/storage/safe-reader.test.ts +0 -262
- package/core/__tests__/storage/sqlite-migration.test.ts +0 -1016
- package/core/__tests__/storage/state-storage-feedback.test.ts +0 -463
- package/core/__tests__/storage/state-storage-history.test.ts +0 -469
- package/core/__tests__/storage/storage-manager.test.ts +0 -383
- package/core/__tests__/storage/subtask-handoff.test.ts +0 -237
- package/core/__tests__/types/fs.test.ts +0 -125
- package/core/__tests__/utils/date-helper.test.ts +0 -449
- package/core/__tests__/utils/output.test.ts +0 -278
- package/core/__tests__/utils/preserve-sections.test.ts +0 -216
- package/core/__tests__/utils/project-commands.test.ts +0 -71
- package/core/__tests__/utils/retry.test.ts +0 -381
- package/core/__tests__/workflow/state-machine.test.ts +0 -216
- package/core/agentic/agent-router.ts +0 -150
- package/core/agentic/anti-hallucination.ts +0 -141
- package/core/agentic/chain-of-thought.ts +0 -234
- package/core/agentic/command-classifier.ts +0 -141
- package/core/agentic/command-context.ts +0 -168
- package/core/agentic/command-executor.ts +0 -471
- package/core/agentic/context-builder.ts +0 -285
- package/core/agentic/domain-classifier.ts +0 -525
- package/core/agentic/environment-block.ts +0 -102
- package/core/agentic/ground-truth.ts +0 -706
- package/core/agentic/index.ts +0 -193
- package/core/agentic/injection-validator.ts +0 -208
- package/core/agentic/loop-detector.ts +0 -451
- package/core/agentic/memory-system.ts +0 -1547
- package/core/agentic/orchestrator-executor.ts +0 -579
- package/core/agentic/plan-mode.ts +0 -525
- package/core/agentic/prompt-builder.ts +0 -1069
- package/core/agentic/response-validator.ts +0 -98
- package/core/agentic/services.ts +0 -167
- package/core/agentic/skill-loader.ts +0 -106
- package/core/agentic/smart-context.ts +0 -393
- package/core/agentic/tech-normalizer.ts +0 -167
- package/core/agentic/template-executor.ts +0 -272
- package/core/agentic/template-loader.ts +0 -109
- package/core/agentic/token-budget.ts +0 -226
- package/core/agentic/tool-registry.ts +0 -146
- package/core/agents/index.ts +0 -28
- package/core/agents/performance.ts +0 -429
- package/core/ai-tools/formatters.ts +0 -341
- package/core/ai-tools/generator.ts +0 -144
- package/core/ai-tools/index.ts +0 -15
- package/core/ai-tools/registry.ts +0 -201
- package/core/bus/bus.ts +0 -314
- package/core/bus/index.ts +0 -8
- package/core/cli/linear.ts +0 -500
- package/core/cli/lint-meta-commentary.ts +0 -177
- package/core/cli/start.ts +0 -386
- package/core/commands/analysis.ts +0 -1274
- package/core/commands/analytics.ts +0 -342
- package/core/commands/base.ts +0 -118
- package/core/commands/cleanup.ts +0 -157
- package/core/commands/command-data.ts +0 -463
- package/core/commands/commands.ts +0 -306
- package/core/commands/context.ts +0 -238
- package/core/commands/design.ts +0 -77
- package/core/commands/index.ts +0 -19
- package/core/commands/maintenance.ts +0 -77
- package/core/commands/performance.ts +0 -114
- package/core/commands/planning.ts +0 -662
- package/core/commands/register.ts +0 -127
- package/core/commands/registry.ts +0 -444
- package/core/commands/setup.ts +0 -280
- package/core/commands/shipping.ts +0 -267
- package/core/commands/snapshots.ts +0 -297
- package/core/commands/uninstall.ts +0 -542
- package/core/commands/velocity.ts +0 -149
- package/core/commands/workflow.ts +0 -505
- package/core/config/command-context.config.json +0 -66
- package/core/constants/index.ts +0 -379
- package/core/context/generator.ts +0 -368
- package/core/context-tools/files-tool.ts +0 -577
- package/core/context-tools/imports-tool.ts +0 -400
- package/core/context-tools/index.ts +0 -434
- package/core/context-tools/recent-tool.ts +0 -301
- package/core/context-tools/signatures-tool.ts +0 -495
- package/core/context-tools/summary-tool.ts +0 -301
- package/core/context-tools/token-counter.ts +0 -273
- package/core/context-tools/types.ts +0 -253
- package/core/domain/agent-generator.ts +0 -186
- package/core/domain/agent-loader.ts +0 -419
- package/core/domain/analyzer.ts +0 -387
- package/core/domain/architecture-generator.ts +0 -108
- package/core/domain/bm25.ts +0 -525
- package/core/domain/change-propagator.ts +0 -162
- package/core/domain/context-estimator.ts +0 -175
- package/core/domain/fibonacci.ts +0 -128
- package/core/domain/file-hasher.ts +0 -296
- package/core/domain/file-ranker.ts +0 -151
- package/core/domain/git-cochange.ts +0 -250
- package/core/domain/import-graph.ts +0 -315
- package/core/domain/snapshot-manager.ts +0 -415
- package/core/domain/task-stack.ts +0 -578
- package/core/domain/velocity.ts +0 -470
- package/core/errors.ts +0 -335
- package/core/events/events.ts +0 -85
- package/core/events/index.ts +0 -8
- package/core/index.ts +0 -481
- package/core/infrastructure/agent-detector.ts +0 -135
- package/core/infrastructure/ai-provider.ts +0 -578
- package/core/infrastructure/author-detector.ts +0 -133
- package/core/infrastructure/capability-installer.ts +0 -76
- package/core/infrastructure/claude-agent.ts +0 -297
- package/core/infrastructure/command-installer.ts +0 -752
- package/core/infrastructure/config-manager.ts +0 -364
- package/core/infrastructure/editors-config.ts +0 -172
- package/core/infrastructure/path-manager.ts +0 -571
- package/core/infrastructure/performance-tracker.ts +0 -326
- package/core/infrastructure/permission-manager.ts +0 -289
- package/core/infrastructure/setup.ts +0 -1061
- package/core/infrastructure/update-checker.ts +0 -246
- package/core/integrations/issue-tracker/enricher.ts +0 -271
- package/core/integrations/issue-tracker/index.ts +0 -8
- package/core/integrations/issue-tracker/manager.ts +0 -286
- package/core/integrations/issue-tracker/types.ts +0 -310
- package/core/integrations/jira/cache.ts +0 -57
- package/core/integrations/jira/client.ts +0 -688
- package/core/integrations/jira/index.ts +0 -23
- package/core/integrations/jira/service.ts +0 -244
- package/core/integrations/linear/cache.ts +0 -68
- package/core/integrations/linear/client.ts +0 -436
- package/core/integrations/linear/index.ts +0 -20
- package/core/integrations/linear/service.ts +0 -260
- package/core/integrations/linear/sync.ts +0 -314
- package/core/outcomes/analyzer.ts +0 -286
- package/core/outcomes/index.ts +0 -34
- package/core/outcomes/recorder.ts +0 -195
- package/core/plugin/builtin/webhook.ts +0 -148
- package/core/plugin/hooks.ts +0 -315
- package/core/plugin/index.ts +0 -50
- package/core/plugin/loader.ts +0 -354
- package/core/plugin/registry.ts +0 -326
- package/core/schemas/agents.ts +0 -27
- package/core/schemas/analysis.ts +0 -530
- package/core/schemas/classification.ts +0 -91
- package/core/schemas/command-context.ts +0 -29
- package/core/schemas/enriched-task.ts +0 -291
- package/core/schemas/ideas.ts +0 -114
- package/core/schemas/index.ts +0 -53
- package/core/schemas/issues.ts +0 -159
- package/core/schemas/llm-output.ts +0 -170
- package/core/schemas/metrics.ts +0 -143
- package/core/schemas/model.ts +0 -153
- package/core/schemas/outcomes.ts +0 -487
- package/core/schemas/performance.ts +0 -128
- package/core/schemas/permissions.ts +0 -180
- package/core/schemas/prd.ts +0 -450
- package/core/schemas/project.ts +0 -57
- package/core/schemas/roadmap.ts +0 -322
- package/core/schemas/schemas.ts +0 -38
- package/core/schemas/shipped.ts +0 -109
- package/core/schemas/state.ts +0 -284
- package/core/schemas/velocity.ts +0 -103
- package/core/server/index.ts +0 -21
- package/core/server/routes-extended.ts +0 -566
- package/core/server/routes.ts +0 -176
- package/core/server/server.ts +0 -149
- package/core/server/sse.ts +0 -192
- package/core/services/agent-generator.ts +0 -385
- package/core/services/agent-service.ts +0 -168
- package/core/services/breakdown-service.ts +0 -124
- package/core/services/context-generator.ts +0 -445
- package/core/services/context-selector.ts +0 -429
- package/core/services/dependency-validator.ts +0 -318
- package/core/services/diff-generator.ts +0 -313
- package/core/services/doctor-service.ts +0 -423
- package/core/services/file-categorizer.ts +0 -448
- package/core/services/file-scorer.ts +0 -270
- package/core/services/git-analyzer.ts +0 -293
- package/core/services/hierarchical-agent-resolver.ts +0 -236
- package/core/services/hooks-service.ts +0 -685
- package/core/services/index.ts +0 -46
- package/core/services/local-state-generator.ts +0 -158
- package/core/services/memory-service.ts +0 -181
- package/core/services/nested-context-resolver.ts +0 -842
- package/core/services/project-index.ts +0 -911
- package/core/services/project-service.ts +0 -155
- package/core/services/session-tracker.ts +0 -287
- package/core/services/skill-installer.ts +0 -447
- package/core/services/skill-lock.ts +0 -132
- package/core/services/skill-service.ts +0 -306
- package/core/services/stack-detector.ts +0 -229
- package/core/services/staleness-checker.ts +0 -327
- package/core/services/sync-service.ts +0 -1515
- package/core/services/sync-verifier.ts +0 -253
- package/core/services/watch-service.ts +0 -312
- package/core/session/compaction.ts +0 -248
- package/core/session/index.ts +0 -35
- package/core/session/log-migration.ts +0 -88
- package/core/session/metrics.ts +0 -323
- package/core/session/session-log-manager.ts +0 -307
- package/core/session/task-session-manager.ts +0 -404
- package/core/session/utils.ts +0 -51
- package/core/storage/analysis-storage.ts +0 -373
- package/core/storage/archive-storage.ts +0 -205
- package/core/storage/database.ts +0 -575
- package/core/storage/ideas-storage.ts +0 -298
- package/core/storage/index-storage.ts +0 -523
- package/core/storage/index.ts +0 -79
- package/core/storage/metrics-storage.ts +0 -321
- package/core/storage/migrate-json.ts +0 -720
- package/core/storage/queue-storage.ts +0 -336
- package/core/storage/safe-reader.ts +0 -105
- package/core/storage/shipped-storage.ts +0 -253
- package/core/storage/state-storage.ts +0 -1035
- package/core/storage/storage-manager.ts +0 -205
- package/core/storage/storage.ts +0 -177
- package/core/storage/velocity-storage.ts +0 -149
- package/core/sync/auth-config.ts +0 -138
- package/core/sync/index.ts +0 -31
- package/core/sync/oauth-handler.ts +0 -143
- package/core/sync/sync-client.ts +0 -251
- package/core/sync/sync-manager.ts +0 -327
- package/core/tsconfig.json +0 -22
- package/core/types/agentic.ts +0 -760
- package/core/types/agents.ts +0 -150
- package/core/types/bus.ts +0 -193
- package/core/types/citations.ts +0 -22
- package/core/types/commands.ts +0 -399
- package/core/types/config.ts +0 -92
- package/core/types/core.ts +0 -96
- package/core/types/diff.ts +0 -41
- package/core/types/domain.ts +0 -71
- package/core/types/errors.ts +0 -111
- package/core/types/events.ts +0 -42
- package/core/types/fs.ts +0 -72
- package/core/types/index.ts +0 -510
- package/core/types/infrastructure.ts +0 -210
- package/core/types/integrations.ts +0 -31
- package/core/types/jira.ts +0 -51
- package/core/types/logger.ts +0 -17
- package/core/types/memory.ts +0 -313
- package/core/types/outcomes.ts +0 -190
- package/core/types/output.ts +0 -47
- package/core/types/plugin.ts +0 -25
- package/core/types/project-sync.ts +0 -129
- package/core/types/provider.ts +0 -163
- package/core/types/server.ts +0 -71
- package/core/types/services.ts +0 -84
- package/core/types/session.ts +0 -135
- package/core/types/stack.ts +0 -19
- package/core/types/storage.ts +0 -318
- package/core/types/sync-verifier.ts +0 -33
- package/core/types/sync.ts +0 -121
- package/core/types/task.ts +0 -72
- package/core/types/template.ts +0 -24
- package/core/types/utils.ts +0 -92
- package/core/types/workflow.ts +0 -23
- package/core/utils/agent-stream.ts +0 -140
- package/core/utils/animations.ts +0 -251
- package/core/utils/branding.ts +0 -88
- package/core/utils/cache.ts +0 -187
- package/core/utils/citations.ts +0 -39
- package/core/utils/collection-filters.ts +0 -209
- package/core/utils/date-helper.ts +0 -176
- package/core/utils/error-messages.ts +0 -38
- package/core/utils/file-helper.ts +0 -277
- package/core/utils/fs-helpers.ts +0 -14
- package/core/utils/help.ts +0 -314
- package/core/utils/jsonl-helper.ts +0 -290
- package/core/utils/keychain.ts +0 -127
- package/core/utils/logger.ts +0 -77
- package/core/utils/markdown-builder.ts +0 -280
- package/core/utils/next-steps.ts +0 -95
- package/core/utils/output.ts +0 -403
- package/core/utils/preserve-sections.ts +0 -218
- package/core/utils/project-commands.ts +0 -126
- package/core/utils/project-credentials.ts +0 -143
- package/core/utils/provider-cache.ts +0 -49
- package/core/utils/retry.ts +0 -318
- package/core/utils/runtime.ts +0 -108
- package/core/utils/session-helper.ts +0 -278
- package/core/utils/subtask-table.ts +0 -227
- package/core/utils/version.ts +0 -128
- package/core/wizard/index.ts +0 -13
- package/core/wizard/onboarding.ts +0 -633
- package/core/workflow/index.ts +0 -7
- package/core/workflow/state-machine.ts +0 -198
- package/core/workflow/workflow-preferences.ts +0 -294
- package/dist/core/infrastructure/command-installer.js +0 -1141
- package/dist/core/infrastructure/editors-config.js +0 -177
- package/dist/core/infrastructure/setup.js +0 -2244
- package/dist/core/utils/version.js +0 -141
- package/templates/agentic/agent-routing.md +0 -45
- package/templates/agentic/agents/uxui.md +0 -63
- package/templates/agentic/checklist-routing.md +0 -98
- package/templates/agentic/orchestrator.md +0 -68
- package/templates/agentic/task-fragmentation.md +0 -89
- package/templates/agents/AGENTS.md +0 -68
- package/templates/analysis/analyze.md +0 -84
- package/templates/analysis/patterns.md +0 -60
- package/templates/antigravity/SKILL.md +0 -39
- package/templates/architect/discovery.md +0 -67
- package/templates/architect/phases.md +0 -59
- package/templates/checklists/architecture.md +0 -28
- package/templates/checklists/code-quality.md +0 -28
- package/templates/checklists/data.md +0 -33
- package/templates/checklists/documentation.md +0 -33
- package/templates/checklists/infrastructure.md +0 -33
- package/templates/checklists/performance.md +0 -33
- package/templates/checklists/security.md +0 -33
- package/templates/checklists/testing.md +0 -33
- package/templates/checklists/ux-ui.md +0 -37
- package/templates/commands/analyze.md +0 -56
- package/templates/commands/auth.md +0 -234
- package/templates/commands/bug.md +0 -163
- package/templates/commands/cleanup.md +0 -19
- package/templates/commands/dash.md +0 -99
- package/templates/commands/design.md +0 -15
- package/templates/commands/done.md +0 -291
- package/templates/commands/enrich.md +0 -174
- package/templates/commands/git.md +0 -295
- package/templates/commands/history.md +0 -389
- package/templates/commands/idea.md +0 -88
- package/templates/commands/impact.md +0 -864
- package/templates/commands/init.md +0 -54
- package/templates/commands/jira.md +0 -278
- package/templates/commands/linear.md +0 -288
- package/templates/commands/merge.md +0 -206
- package/templates/commands/next.md +0 -80
- package/templates/commands/p.md +0 -67
- package/templates/commands/p.toml +0 -37
- package/templates/commands/pause.md +0 -136
- package/templates/commands/plan.md +0 -696
- package/templates/commands/prd.md +0 -356
- package/templates/commands/resume.md +0 -171
- package/templates/commands/review.md +0 -276
- package/templates/commands/serve.md +0 -118
- package/templates/commands/setup.md +0 -91
- package/templates/commands/ship.md +0 -475
- package/templates/commands/skill.md +0 -259
- package/templates/commands/spec.md +0 -218
- package/templates/commands/status.md +0 -207
- package/templates/commands/sync.md +0 -104
- package/templates/commands/task.md +0 -312
- package/templates/commands/test.md +0 -93
- package/templates/commands/update.md +0 -63
- package/templates/commands/verify.md +0 -204
- package/templates/commands/workflow.md +0 -150
- package/templates/config/skill-mappings.json +0 -82
- package/templates/context/dashboard.md +0 -256
- package/templates/context/roadmap.md +0 -221
- package/templates/cursor/commands/bug.md +0 -8
- package/templates/cursor/commands/done.md +0 -4
- package/templates/cursor/commands/pause.md +0 -6
- package/templates/cursor/commands/resume.md +0 -4
- package/templates/cursor/commands/ship.md +0 -8
- package/templates/cursor/commands/sync.md +0 -4
- package/templates/cursor/commands/task.md +0 -8
- package/templates/cursor/p.md +0 -29
- package/templates/cursor/router.mdc +0 -28
- package/templates/design/api.md +0 -95
- package/templates/design/architecture.md +0 -77
- package/templates/design/component.md +0 -89
- package/templates/design/database.md +0 -78
- package/templates/design/flow.md +0 -94
- package/templates/global/ANTIGRAVITY.md +0 -254
- package/templates/global/CLAUDE.md +0 -497
- package/templates/global/CURSOR.mdc +0 -266
- package/templates/global/GEMINI.md +0 -293
- package/templates/global/STORAGE-SPEC.md +0 -391
- package/templates/global/WINDSURF.md +0 -266
- package/templates/global/modules/CLAUDE-commands.md +0 -70
- package/templates/global/modules/CLAUDE-core.md +0 -105
- package/templates/global/modules/CLAUDE-git.md +0 -50
- package/templates/global/modules/CLAUDE-intelligence.md +0 -92
- package/templates/global/modules/CLAUDE-storage.md +0 -50
- package/templates/global/modules/module-config.json +0 -36
- package/templates/mcp-config.json +0 -19
- package/templates/permissions/default.jsonc +0 -60
- package/templates/permissions/permissive.jsonc +0 -49
- package/templates/permissions/strict.jsonc +0 -58
- package/templates/planning-methodology.md +0 -195
- package/templates/skills/code-review.md +0 -47
- package/templates/skills/debug.md +0 -61
- package/templates/skills/refactor.md +0 -47
- package/templates/subagents/agent-base.md +0 -20
- package/templates/subagents/domain/backend.md +0 -109
- package/templates/subagents/domain/database.md +0 -121
- package/templates/subagents/domain/devops.md +0 -152
- package/templates/subagents/domain/frontend.md +0 -103
- package/templates/subagents/domain/testing.md +0 -169
- package/templates/subagents/pm-expert.md +0 -366
- package/templates/subagents/workflow/chief-architect.md +0 -657
- package/templates/subagents/workflow/prjct-planner.md +0 -159
- package/templates/subagents/workflow/prjct-shipper.md +0 -188
- package/templates/subagents/workflow/prjct-workflow.md +0 -98
- package/templates/tools/bash.txt +0 -22
- package/templates/tools/edit.txt +0 -18
- package/templates/tools/glob.txt +0 -19
- package/templates/tools/grep.txt +0 -21
- package/templates/tools/read.txt +0 -14
- package/templates/tools/task.txt +0 -20
- package/templates/tools/webfetch.txt +0 -16
- package/templates/tools/websearch.txt +0 -18
- package/templates/tools/write.txt +0 -17
- package/templates/windsurf/router.md +0 -28
- package/templates/windsurf/workflows/bug.md +0 -8
- package/templates/windsurf/workflows/done.md +0 -4
- package/templates/windsurf/workflows/pause.md +0 -4
- package/templates/windsurf/workflows/resume.md +0 -4
- package/templates/windsurf/workflows/ship.md +0 -8
- package/templates/windsurf/workflows/sync.md +0 -4
- package/templates/windsurf/workflows/task.md +0 -8
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool Registry
|
|
3
|
-
* Maps tool names to implementations for agentic execution.
|
|
4
|
-
*
|
|
5
|
-
* @module agentic/tool-registry
|
|
6
|
-
* @version 1.0.0
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { exec } from 'node:child_process'
|
|
10
|
-
import fs from 'node:fs/promises'
|
|
11
|
-
import { promisify } from 'node:util'
|
|
12
|
-
import type { ToolFunction, ToolRegistryInterface } from '../types'
|
|
13
|
-
import { defaultToolRetryPolicy, isPermanentError, isTransientError } from '../utils/retry'
|
|
14
|
-
|
|
15
|
-
// Re-export types for convenience
|
|
16
|
-
export type { ToolFunction, ToolRegistryInterface } from '../types'
|
|
17
|
-
|
|
18
|
-
const execAsync = promisify(exec)
|
|
19
|
-
|
|
20
|
-
const toolRegistry: ToolRegistryInterface = {
|
|
21
|
-
tools: new Map(),
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Register a tool
|
|
25
|
-
*/
|
|
26
|
-
register(name: string, fn: ToolFunction): void {
|
|
27
|
-
this.tools.set(name, fn)
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Get a tool by name
|
|
32
|
-
*/
|
|
33
|
-
get(name: string): ToolFunction | undefined {
|
|
34
|
-
return this.tools.get(name)
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Check if tool is allowed for command
|
|
39
|
-
*/
|
|
40
|
-
isAllowed(name: string, allowedTools: string[]): boolean {
|
|
41
|
-
// If no restrictions, allow all
|
|
42
|
-
if (!allowedTools || allowedTools.length === 0) {
|
|
43
|
-
return true
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Check if tool name matches or starts with allowed pattern
|
|
47
|
-
return allowedTools.some((allowed) => {
|
|
48
|
-
if (allowed.endsWith('*')) {
|
|
49
|
-
return name.startsWith(allowed.slice(0, -1))
|
|
50
|
-
}
|
|
51
|
-
return name === allowed
|
|
52
|
-
})
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* List all registered tools
|
|
57
|
-
*/
|
|
58
|
-
list(): string[] {
|
|
59
|
-
return Array.from(this.tools.keys())
|
|
60
|
-
},
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Register built-in tools
|
|
64
|
-
|
|
65
|
-
// Read file with retry for transient errors
|
|
66
|
-
toolRegistry.register('Read', async (filePath: unknown): Promise<string | null> => {
|
|
67
|
-
try {
|
|
68
|
-
return await defaultToolRetryPolicy.execute(
|
|
69
|
-
async () => await fs.readFile(filePath as string, 'utf-8'),
|
|
70
|
-
`read-${filePath}`
|
|
71
|
-
)
|
|
72
|
-
} catch (error) {
|
|
73
|
-
// Permanent errors (ENOENT, EPERM) - return null (expected)
|
|
74
|
-
if (isPermanentError(error)) {
|
|
75
|
-
return null
|
|
76
|
-
}
|
|
77
|
-
// Transient errors exhausted retries - return null
|
|
78
|
-
if (isTransientError(error)) {
|
|
79
|
-
return null
|
|
80
|
-
}
|
|
81
|
-
// Unknown errors - return null (fail gracefully)
|
|
82
|
-
return null
|
|
83
|
-
}
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
// Write file with retry for transient errors
|
|
87
|
-
toolRegistry.register('Write', async (filePath: unknown, content: unknown): Promise<boolean> => {
|
|
88
|
-
try {
|
|
89
|
-
await defaultToolRetryPolicy.execute(
|
|
90
|
-
async () => await fs.writeFile(filePath as string, content as string, 'utf-8'),
|
|
91
|
-
`write-${filePath}`
|
|
92
|
-
)
|
|
93
|
-
return true
|
|
94
|
-
} catch (error) {
|
|
95
|
-
// Permanent errors (EPERM, EISDIR) - return false (expected)
|
|
96
|
-
if (isPermanentError(error)) {
|
|
97
|
-
return false
|
|
98
|
-
}
|
|
99
|
-
// Transient errors exhausted retries - return false
|
|
100
|
-
if (isTransientError(error)) {
|
|
101
|
-
return false
|
|
102
|
-
}
|
|
103
|
-
// Unknown errors - return false (fail gracefully)
|
|
104
|
-
return false
|
|
105
|
-
}
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
// Execute bash command with retry for transient errors
|
|
109
|
-
toolRegistry.register(
|
|
110
|
-
'Bash',
|
|
111
|
-
async (command: unknown): Promise<{ stdout: string; stderr: string }> => {
|
|
112
|
-
try {
|
|
113
|
-
return await defaultToolRetryPolicy.execute(
|
|
114
|
-
async () => await execAsync(command as string),
|
|
115
|
-
`bash-${command}`
|
|
116
|
-
)
|
|
117
|
-
} catch (error) {
|
|
118
|
-
const err = error as { stdout?: string; stderr?: string; message?: string; code?: string }
|
|
119
|
-
|
|
120
|
-
// For command execution errors, return output with error in stderr
|
|
121
|
-
// This maintains the existing behavior while adding retry for transient errors
|
|
122
|
-
return {
|
|
123
|
-
stdout: err.stdout || '',
|
|
124
|
-
stderr: err.stderr || err.message || 'Command failed',
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
// Get current timestamp
|
|
131
|
-
toolRegistry.register('GetTimestamp', async (): Promise<string> => {
|
|
132
|
-
return new Date().toISOString()
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
// Get current date
|
|
136
|
-
toolRegistry.register('GetDate', async (): Promise<string> => {
|
|
137
|
-
return new Date().toISOString().split('T')[0]
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
// Get current datetime
|
|
141
|
-
toolRegistry.register('GetDateTime', async (): Promise<string> => {
|
|
142
|
-
return new Date().toISOString()
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
export default toolRegistry
|
|
146
|
-
export { toolRegistry }
|
package/core/agents/index.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agents Module
|
|
3
|
-
*
|
|
4
|
-
* Agent performance tracking and intelligent routing.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```typescript
|
|
8
|
-
* import { agentPerformanceTracker } from './agents'
|
|
9
|
-
*
|
|
10
|
-
* // Record task completion
|
|
11
|
-
* await agentPerformanceTracker.recordTask(projectId, {
|
|
12
|
-
* agentName: 'fe',
|
|
13
|
-
* taskType: 'frontend',
|
|
14
|
-
* success: true,
|
|
15
|
-
* estimatedDuration: '2h',
|
|
16
|
-
* actualDuration: '1h 45m',
|
|
17
|
-
* qualityScore: 4,
|
|
18
|
-
* completedAt: new Date().toISOString()
|
|
19
|
-
* })
|
|
20
|
-
*
|
|
21
|
-
* // Get agent suggestion
|
|
22
|
-
* const suggestion = await agentPerformanceTracker.suggestAgent(projectId, 'frontend')
|
|
23
|
-
* // { agentName: 'fe', confidence: 0.9, reason: 'Best success rate...' }
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
export * from '../types'
|
|
28
|
-
export { AgentPerformanceTracker, default as agentPerformanceTracker } from './performance'
|
|
@@ -1,429 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent Performance Tracker
|
|
3
|
-
*
|
|
4
|
-
* Tracks agent performance for intelligent routing.
|
|
5
|
-
* Enables learning which agent works best for which task type.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import path from 'node:path'
|
|
9
|
-
import pathManager from '../infrastructure/path-manager'
|
|
10
|
-
import type {
|
|
11
|
-
AgentPerformance,
|
|
12
|
-
AgentPerformanceSummary,
|
|
13
|
-
AgentSuggestion,
|
|
14
|
-
AgentTaskRecord,
|
|
15
|
-
TaskType,
|
|
16
|
-
} from '../types'
|
|
17
|
-
import * as fileHelper from '../utils/file-helper'
|
|
18
|
-
|
|
19
|
-
const PERFORMANCE_DIR = 'analysis'
|
|
20
|
-
const PERFORMANCE_FILE = 'agent-performance.json'
|
|
21
|
-
const RECORDS_FILE = 'agent-records.jsonl'
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* AgentPerformanceTracker - Tracks and analyzes agent performance.
|
|
25
|
-
*/
|
|
26
|
-
export class AgentPerformanceTracker {
|
|
27
|
-
/**
|
|
28
|
-
* Get performance directory path for a project.
|
|
29
|
-
*/
|
|
30
|
-
private getPerformanceDir(projectId: string): string {
|
|
31
|
-
const globalPath = pathManager.getGlobalProjectPath(projectId)
|
|
32
|
-
return path.join(globalPath, PERFORMANCE_DIR)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Get performance file path.
|
|
37
|
-
*/
|
|
38
|
-
private getPerformancePath(projectId: string): string {
|
|
39
|
-
return path.join(this.getPerformanceDir(projectId), PERFORMANCE_FILE)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Get records file path.
|
|
44
|
-
*/
|
|
45
|
-
private getRecordsPath(projectId: string): string {
|
|
46
|
-
return path.join(this.getPerformanceDir(projectId), RECORDS_FILE)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Record a task completion for an agent.
|
|
51
|
-
*/
|
|
52
|
-
async recordTask(projectId: string, record: AgentTaskRecord): Promise<void> {
|
|
53
|
-
const recordsPath = this.getRecordsPath(projectId)
|
|
54
|
-
|
|
55
|
-
// Ensure directory exists
|
|
56
|
-
await fileHelper.ensureDir(path.dirname(recordsPath))
|
|
57
|
-
|
|
58
|
-
// Append record
|
|
59
|
-
await fileHelper.appendLine(recordsPath, JSON.stringify(record))
|
|
60
|
-
|
|
61
|
-
// Update performance summary
|
|
62
|
-
await this.updatePerformance(projectId, record)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Get all task records for a project.
|
|
67
|
-
*/
|
|
68
|
-
async getRecords(projectId: string): Promise<AgentTaskRecord[]> {
|
|
69
|
-
const recordsPath = this.getRecordsPath(projectId)
|
|
70
|
-
|
|
71
|
-
if (!(await fileHelper.fileExists(recordsPath))) {
|
|
72
|
-
return []
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const content = await fileHelper.readFile(recordsPath)
|
|
76
|
-
if (!content.trim()) {
|
|
77
|
-
return []
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return content
|
|
81
|
-
.trim()
|
|
82
|
-
.split('\n')
|
|
83
|
-
.filter((line) => line.trim())
|
|
84
|
-
.map((line) => JSON.parse(line) as AgentTaskRecord)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Get all agent performance data.
|
|
89
|
-
*/
|
|
90
|
-
async getAllPerformance(projectId: string): Promise<AgentPerformance[]> {
|
|
91
|
-
const perfPath = this.getPerformancePath(projectId)
|
|
92
|
-
|
|
93
|
-
if (!(await fileHelper.fileExists(perfPath))) {
|
|
94
|
-
return []
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const data = await fileHelper.readJson<{ agents: AgentPerformance[] }>(perfPath, { agents: [] })
|
|
98
|
-
return data?.agents ?? []
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Get performance for a specific agent.
|
|
103
|
-
*/
|
|
104
|
-
async getAgentPerformance(
|
|
105
|
-
projectId: string,
|
|
106
|
-
agentName: string
|
|
107
|
-
): Promise<AgentPerformance | null> {
|
|
108
|
-
const all = await this.getAllPerformance(projectId)
|
|
109
|
-
return all.find((a) => a.agentName === agentName) || null
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Update performance summary after a task completion.
|
|
114
|
-
*/
|
|
115
|
-
private async updatePerformance(projectId: string, record: AgentTaskRecord): Promise<void> {
|
|
116
|
-
const perfPath = this.getPerformancePath(projectId)
|
|
117
|
-
await fileHelper.ensureDir(path.dirname(perfPath))
|
|
118
|
-
|
|
119
|
-
const data = await fileHelper.readJson<{ agents: AgentPerformance[] }>(perfPath, { agents: [] })
|
|
120
|
-
|
|
121
|
-
if (!data) return
|
|
122
|
-
|
|
123
|
-
// Find or create agent performance
|
|
124
|
-
let agentPerf = data.agents.find((a) => a.agentName === record.agentName)
|
|
125
|
-
|
|
126
|
-
if (!agentPerf) {
|
|
127
|
-
agentPerf = {
|
|
128
|
-
agentName: record.agentName,
|
|
129
|
-
taskType: record.taskType,
|
|
130
|
-
tasksCompleted: 0,
|
|
131
|
-
successRate: 0,
|
|
132
|
-
avgDuration: '0m',
|
|
133
|
-
estimateAccuracy: 0,
|
|
134
|
-
improving: false,
|
|
135
|
-
lastUpdated: new Date().toISOString(),
|
|
136
|
-
bestFor: [],
|
|
137
|
-
avoidFor: [],
|
|
138
|
-
}
|
|
139
|
-
data.agents.push(agentPerf)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Get all records for this agent
|
|
143
|
-
const allRecords = await this.getRecords(projectId)
|
|
144
|
-
const agentRecords = allRecords.filter((r) => r.agentName === record.agentName)
|
|
145
|
-
|
|
146
|
-
// Calculate updated stats
|
|
147
|
-
agentPerf.tasksCompleted = agentRecords.length
|
|
148
|
-
agentPerf.successRate = Math.round(
|
|
149
|
-
(agentRecords.filter((r) => r.success).length / agentRecords.length) * 100
|
|
150
|
-
)
|
|
151
|
-
agentPerf.avgDuration = this.calculateAvgDuration(agentRecords)
|
|
152
|
-
agentPerf.estimateAccuracy = this.calculateEstimateAccuracy(agentRecords)
|
|
153
|
-
agentPerf.lastUpdated = new Date().toISOString()
|
|
154
|
-
|
|
155
|
-
// Calculate best/avoid task types
|
|
156
|
-
const taskTypeStats = this.calculateTaskTypeStats(agentRecords)
|
|
157
|
-
agentPerf.bestFor = taskTypeStats.bestFor
|
|
158
|
-
agentPerf.avoidFor = taskTypeStats.avoidFor
|
|
159
|
-
|
|
160
|
-
// Check if improving (compare last 5 vs previous 5)
|
|
161
|
-
agentPerf.improving = this.checkImproving(agentRecords)
|
|
162
|
-
|
|
163
|
-
await fileHelper.writeJson(perfPath, data)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Calculate average duration from records.
|
|
168
|
-
*/
|
|
169
|
-
private calculateAvgDuration(records: AgentTaskRecord[]): string {
|
|
170
|
-
if (records.length === 0) return '0m'
|
|
171
|
-
|
|
172
|
-
const totalMinutes = records.reduce((sum, r) => {
|
|
173
|
-
return sum + this.parseDuration(r.actualDuration)
|
|
174
|
-
}, 0)
|
|
175
|
-
|
|
176
|
-
const avgMinutes = Math.round(totalMinutes / records.length)
|
|
177
|
-
|
|
178
|
-
if (avgMinutes >= 60) {
|
|
179
|
-
const hours = Math.floor(avgMinutes / 60)
|
|
180
|
-
const mins = avgMinutes % 60
|
|
181
|
-
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`
|
|
182
|
-
}
|
|
183
|
-
return `${avgMinutes}m`
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Calculate estimate accuracy from records.
|
|
188
|
-
*/
|
|
189
|
-
private calculateEstimateAccuracy(records: AgentTaskRecord[]): number {
|
|
190
|
-
if (records.length === 0) return 0
|
|
191
|
-
|
|
192
|
-
const accurateCount = records.filter((r) => {
|
|
193
|
-
const estimated = this.parseDuration(r.estimatedDuration)
|
|
194
|
-
const actual = this.parseDuration(r.actualDuration)
|
|
195
|
-
if (estimated === 0) return false
|
|
196
|
-
return Math.abs(actual - estimated) / estimated <= 0.2
|
|
197
|
-
}).length
|
|
198
|
-
|
|
199
|
-
return Math.round((accurateCount / records.length) * 100)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Calculate best and avoid task types for an agent.
|
|
204
|
-
*/
|
|
205
|
-
private calculateTaskTypeStats(records: AgentTaskRecord[]): {
|
|
206
|
-
bestFor: TaskType[]
|
|
207
|
-
avoidFor: TaskType[]
|
|
208
|
-
} {
|
|
209
|
-
const byType = new Map<TaskType, { success: number; total: number }>()
|
|
210
|
-
|
|
211
|
-
for (const record of records) {
|
|
212
|
-
const stats = byType.get(record.taskType) || { success: 0, total: 0 }
|
|
213
|
-
stats.total++
|
|
214
|
-
if (record.success) stats.success++
|
|
215
|
-
byType.set(record.taskType, stats)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const bestFor: TaskType[] = []
|
|
219
|
-
const avoidFor: TaskType[] = []
|
|
220
|
-
|
|
221
|
-
for (const [taskType, stats] of byType) {
|
|
222
|
-
if (stats.total < 2) continue // Need at least 2 tasks
|
|
223
|
-
|
|
224
|
-
const successRate = stats.success / stats.total
|
|
225
|
-
|
|
226
|
-
if (successRate >= 0.8) {
|
|
227
|
-
bestFor.push(taskType)
|
|
228
|
-
} else if (successRate < 0.5) {
|
|
229
|
-
avoidFor.push(taskType)
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return { bestFor, avoidFor }
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Check if agent performance is improving.
|
|
238
|
-
*/
|
|
239
|
-
private checkImproving(records: AgentTaskRecord[]): boolean {
|
|
240
|
-
if (records.length < 10) return false
|
|
241
|
-
|
|
242
|
-
const recent = records.slice(-5)
|
|
243
|
-
const previous = records.slice(-10, -5)
|
|
244
|
-
|
|
245
|
-
const recentSuccess = recent.filter((r) => r.success).length / 5
|
|
246
|
-
const previousSuccess = previous.filter((r) => r.success).length / 5
|
|
247
|
-
|
|
248
|
-
return recentSuccess > previousSuccess
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Parse duration string to minutes.
|
|
253
|
-
*/
|
|
254
|
-
private parseDuration(duration: string): number {
|
|
255
|
-
let minutes = 0
|
|
256
|
-
|
|
257
|
-
const hourMatch = duration.match(/(\d+)h/)
|
|
258
|
-
if (hourMatch) {
|
|
259
|
-
minutes += parseInt(hourMatch[1], 10) * 60
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const minMatch = duration.match(/(\d+)m/)
|
|
263
|
-
if (minMatch) {
|
|
264
|
-
minutes += parseInt(minMatch[1], 10)
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return minutes
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Suggest the best agent for a task type.
|
|
272
|
-
*/
|
|
273
|
-
async suggestAgent(projectId: string, taskType: TaskType): Promise<AgentSuggestion | null> {
|
|
274
|
-
const allPerf = await this.getAllPerformance(projectId)
|
|
275
|
-
|
|
276
|
-
if (allPerf.length === 0) {
|
|
277
|
-
return null
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// Find agents good at this task type
|
|
281
|
-
const suitable = allPerf.filter(
|
|
282
|
-
(a) => a.bestFor.includes(taskType) && !a.avoidFor.includes(taskType)
|
|
283
|
-
)
|
|
284
|
-
|
|
285
|
-
if (suitable.length > 0) {
|
|
286
|
-
// Sort by success rate
|
|
287
|
-
suitable.sort((a, b) => b.successRate - a.successRate)
|
|
288
|
-
const best = suitable[0]
|
|
289
|
-
|
|
290
|
-
return {
|
|
291
|
-
agentName: best.agentName,
|
|
292
|
-
confidence: best.successRate / 100,
|
|
293
|
-
reason: `Best success rate (${best.successRate}%) for ${taskType} tasks`,
|
|
294
|
-
alternatives: suitable.slice(1, 3).map((a) => a.agentName),
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Fallback to most experienced agent
|
|
299
|
-
const byExperience = [...allPerf].sort((a, b) => b.tasksCompleted - a.tasksCompleted)
|
|
300
|
-
const fallback = byExperience[0]
|
|
301
|
-
|
|
302
|
-
return {
|
|
303
|
-
agentName: fallback.agentName,
|
|
304
|
-
confidence: 0.5,
|
|
305
|
-
reason: `Most experienced agent (${fallback.tasksCompleted} tasks)`,
|
|
306
|
-
alternatives: byExperience.slice(1, 3).map((a) => a.agentName),
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Get performance summary for a project.
|
|
312
|
-
*/
|
|
313
|
-
async getSummary(projectId: string): Promise<AgentPerformanceSummary> {
|
|
314
|
-
const allPerf = await this.getAllPerformance(projectId)
|
|
315
|
-
|
|
316
|
-
if (allPerf.length === 0) {
|
|
317
|
-
return {
|
|
318
|
-
totalAgents: 0,
|
|
319
|
-
topPerformer: null,
|
|
320
|
-
mostUsed: null,
|
|
321
|
-
avgSuccessRate: 0,
|
|
322
|
-
byTaskType: {} as Record<TaskType, string | null>,
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Find top performer
|
|
327
|
-
const bySuccess = [...allPerf].sort((a, b) => b.successRate - a.successRate)
|
|
328
|
-
const topPerformer = bySuccess[0].agentName
|
|
329
|
-
|
|
330
|
-
// Find most used
|
|
331
|
-
const byTasks = [...allPerf].sort((a, b) => b.tasksCompleted - a.tasksCompleted)
|
|
332
|
-
const mostUsed = byTasks[0].agentName
|
|
333
|
-
|
|
334
|
-
// Average success rate
|
|
335
|
-
const avgSuccessRate = Math.round(
|
|
336
|
-
allPerf.reduce((sum, a) => sum + a.successRate, 0) / allPerf.length
|
|
337
|
-
)
|
|
338
|
-
|
|
339
|
-
// Best agent by task type
|
|
340
|
-
const taskTypes: TaskType[] = [
|
|
341
|
-
'frontend',
|
|
342
|
-
'backend',
|
|
343
|
-
'devops',
|
|
344
|
-
'database',
|
|
345
|
-
'testing',
|
|
346
|
-
'documentation',
|
|
347
|
-
'refactoring',
|
|
348
|
-
'bugfix',
|
|
349
|
-
'feature',
|
|
350
|
-
'design',
|
|
351
|
-
'other',
|
|
352
|
-
]
|
|
353
|
-
const byTaskType: Record<TaskType, string | null> = {} as Record<TaskType, string | null>
|
|
354
|
-
|
|
355
|
-
for (const taskType of taskTypes) {
|
|
356
|
-
const best = allPerf.find((a) => a.bestFor.includes(taskType))
|
|
357
|
-
byTaskType[taskType] = best?.agentName || null
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return {
|
|
361
|
-
totalAgents: allPerf.length,
|
|
362
|
-
topPerformer,
|
|
363
|
-
mostUsed,
|
|
364
|
-
avgSuccessRate,
|
|
365
|
-
byTaskType,
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Generate markdown report of agent performance.
|
|
371
|
-
*/
|
|
372
|
-
async generateReport(projectId: string): Promise<string> {
|
|
373
|
-
const allPerf = await this.getAllPerformance(projectId)
|
|
374
|
-
const summary = await this.getSummary(projectId)
|
|
375
|
-
|
|
376
|
-
const lines: string[] = []
|
|
377
|
-
|
|
378
|
-
lines.push('# Agent Performance Report')
|
|
379
|
-
lines.push('')
|
|
380
|
-
lines.push(`Generated: ${new Date().toISOString()}`)
|
|
381
|
-
lines.push('')
|
|
382
|
-
|
|
383
|
-
lines.push('## Summary')
|
|
384
|
-
lines.push('')
|
|
385
|
-
lines.push(`- **Total Agents**: ${summary.totalAgents}`)
|
|
386
|
-
lines.push(`- **Top Performer**: ${summary.topPerformer || 'N/A'}`)
|
|
387
|
-
lines.push(`- **Most Used**: ${summary.mostUsed || 'N/A'}`)
|
|
388
|
-
lines.push(`- **Avg Success Rate**: ${summary.avgSuccessRate}%`)
|
|
389
|
-
lines.push('')
|
|
390
|
-
|
|
391
|
-
if (allPerf.length > 0) {
|
|
392
|
-
lines.push('## Agent Details')
|
|
393
|
-
lines.push('')
|
|
394
|
-
|
|
395
|
-
for (const agent of allPerf) {
|
|
396
|
-
lines.push(`### ${agent.agentName}`)
|
|
397
|
-
lines.push('')
|
|
398
|
-
lines.push(`- **Tasks Completed**: ${agent.tasksCompleted}`)
|
|
399
|
-
lines.push(`- **Success Rate**: ${agent.successRate}%`)
|
|
400
|
-
lines.push(`- **Avg Duration**: ${agent.avgDuration}`)
|
|
401
|
-
lines.push(`- **Estimate Accuracy**: ${agent.estimateAccuracy}%`)
|
|
402
|
-
lines.push(`- **Improving**: ${agent.improving ? 'Yes' : 'No'}`)
|
|
403
|
-
|
|
404
|
-
if (agent.bestFor.length > 0) {
|
|
405
|
-
lines.push(`- **Best For**: ${agent.bestFor.join(', ')}`)
|
|
406
|
-
}
|
|
407
|
-
if (agent.avoidFor.length > 0) {
|
|
408
|
-
lines.push(`- **Avoid For**: ${agent.avoidFor.join(', ')}`)
|
|
409
|
-
}
|
|
410
|
-
lines.push('')
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
lines.push('## Task Type Routing')
|
|
415
|
-
lines.push('')
|
|
416
|
-
lines.push('| Task Type | Recommended Agent |')
|
|
417
|
-
lines.push('|-----------|-------------------|')
|
|
418
|
-
|
|
419
|
-
for (const [taskType, agent] of Object.entries(summary.byTaskType)) {
|
|
420
|
-
lines.push(`| ${taskType} | ${agent || 'No data'} |`)
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
return lines.join('\n')
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// Singleton instance
|
|
428
|
-
const agentPerformanceTracker = new AgentPerformanceTracker()
|
|
429
|
-
export default agentPerformanceTracker
|