prjct-cli 1.22.0 → 1.24.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 +230 -0
- package/bin/prjct +30 -13
- package/dist/bin/prjct-core.mjs +1748 -0
- package/dist/bin/prjct.mjs +17 -36672
- package/dist/cli/linear.mjs +14 -0
- package/dist/daemon/entry.mjs +1429 -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,293 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GitAnalyzer - Git repository analysis
|
|
3
|
-
*
|
|
4
|
-
* Extracted from sync-service.ts for single responsibility.
|
|
5
|
-
* Analyzes git state: branch, commits, contributors, changes, etc.
|
|
6
|
-
*
|
|
7
|
-
* Uses graceful degradation for git availability (PRJ-114).
|
|
8
|
-
* Avoids shell pipes for better cross-platform compatibility.
|
|
9
|
-
*
|
|
10
|
-
* @version 1.1.0
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { exec } from 'node:child_process'
|
|
14
|
-
import { promisify } from 'node:util'
|
|
15
|
-
import { getTimeout } from '../constants'
|
|
16
|
-
import { dependencyValidator } from './dependency-validator'
|
|
17
|
-
|
|
18
|
-
const execAsync = promisify(exec)
|
|
19
|
-
|
|
20
|
-
// ============================================================================
|
|
21
|
-
// TYPES
|
|
22
|
-
// ============================================================================
|
|
23
|
-
|
|
24
|
-
export interface GitData {
|
|
25
|
-
branch: string
|
|
26
|
-
commits: number
|
|
27
|
-
contributors: number
|
|
28
|
-
hasChanges: boolean
|
|
29
|
-
stagedFiles: string[]
|
|
30
|
-
modifiedFiles: string[]
|
|
31
|
-
untrackedFiles: string[]
|
|
32
|
-
recentCommits: { hash: string; message: string; date: string }[]
|
|
33
|
-
weeklyCommits: number
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// ============================================================================
|
|
37
|
-
// GIT ANALYZER CLASS
|
|
38
|
-
// ============================================================================
|
|
39
|
-
|
|
40
|
-
export class GitAnalyzer {
|
|
41
|
-
private projectPath: string
|
|
42
|
-
|
|
43
|
-
constructor(projectPath: string) {
|
|
44
|
-
this.projectPath = projectPath
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Analyze git repository state
|
|
49
|
-
* Returns defaults if git is not available (graceful degradation)
|
|
50
|
-
*/
|
|
51
|
-
async analyze(): Promise<GitData> {
|
|
52
|
-
const data: GitData = {
|
|
53
|
-
branch: 'main',
|
|
54
|
-
commits: 0,
|
|
55
|
-
contributors: 0,
|
|
56
|
-
hasChanges: false,
|
|
57
|
-
stagedFiles: [],
|
|
58
|
-
modifiedFiles: [],
|
|
59
|
-
untrackedFiles: [],
|
|
60
|
-
recentCommits: [],
|
|
61
|
-
weeklyCommits: 0,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// PRJ-114: Check git availability first (graceful degradation)
|
|
65
|
-
if (!dependencyValidator.isAvailable('git')) {
|
|
66
|
-
return data
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
try {
|
|
70
|
-
// Run independent git commands in parallel for speed
|
|
71
|
-
const [branch, commits, contributors, status, log, weekly] = await Promise.all([
|
|
72
|
-
this.getBranch(),
|
|
73
|
-
this.getCommitCount(),
|
|
74
|
-
this.getContributorCount(),
|
|
75
|
-
this.getStatus(),
|
|
76
|
-
this.getRecentCommits(),
|
|
77
|
-
this.getWeeklyCommitCount(),
|
|
78
|
-
])
|
|
79
|
-
|
|
80
|
-
data.branch = branch
|
|
81
|
-
data.commits = commits
|
|
82
|
-
data.contributors = contributors
|
|
83
|
-
data.hasChanges = status.hasChanges
|
|
84
|
-
data.stagedFiles = status.stagedFiles
|
|
85
|
-
data.modifiedFiles = status.modifiedFiles
|
|
86
|
-
data.untrackedFiles = status.untrackedFiles
|
|
87
|
-
data.recentCommits = log
|
|
88
|
-
data.weeklyCommits = weekly
|
|
89
|
-
} catch {
|
|
90
|
-
// Not a git repo - use defaults
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return data
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Get current branch name
|
|
98
|
-
*/
|
|
99
|
-
async getBranch(): Promise<string> {
|
|
100
|
-
try {
|
|
101
|
-
const { stdout } = await execAsync('git branch --show-current', {
|
|
102
|
-
cwd: this.projectPath,
|
|
103
|
-
timeout: getTimeout('GIT_OPERATION'),
|
|
104
|
-
})
|
|
105
|
-
return stdout.trim() || 'main'
|
|
106
|
-
} catch {
|
|
107
|
-
return 'main'
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Get total commit count
|
|
113
|
-
*/
|
|
114
|
-
async getCommitCount(): Promise<number> {
|
|
115
|
-
try {
|
|
116
|
-
const { stdout } = await execAsync('git rev-list --count HEAD', {
|
|
117
|
-
cwd: this.projectPath,
|
|
118
|
-
timeout: getTimeout('GIT_OPERATION'),
|
|
119
|
-
})
|
|
120
|
-
return parseInt(stdout.trim(), 10) || 0
|
|
121
|
-
} catch {
|
|
122
|
-
return 0
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Get contributor count
|
|
128
|
-
* PRJ-114: Avoids shell pipe by counting lines in JS
|
|
129
|
-
*/
|
|
130
|
-
async getContributorCount(): Promise<number> {
|
|
131
|
-
try {
|
|
132
|
-
const { stdout } = await execAsync('git shortlog -sn --all', {
|
|
133
|
-
cwd: this.projectPath,
|
|
134
|
-
timeout: getTimeout('GIT_OPERATION'),
|
|
135
|
-
})
|
|
136
|
-
// Count non-empty lines instead of piping to wc -l
|
|
137
|
-
const lines = stdout.trim().split('\n').filter(Boolean)
|
|
138
|
-
return lines.length
|
|
139
|
-
} catch {
|
|
140
|
-
return 0
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Get working tree status
|
|
146
|
-
*/
|
|
147
|
-
async getStatus(): Promise<{
|
|
148
|
-
hasChanges: boolean
|
|
149
|
-
stagedFiles: string[]
|
|
150
|
-
modifiedFiles: string[]
|
|
151
|
-
untrackedFiles: string[]
|
|
152
|
-
}> {
|
|
153
|
-
const result = {
|
|
154
|
-
hasChanges: false,
|
|
155
|
-
stagedFiles: [] as string[],
|
|
156
|
-
modifiedFiles: [] as string[],
|
|
157
|
-
untrackedFiles: [] as string[],
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
try {
|
|
161
|
-
const { stdout } = await execAsync('git status --porcelain', {
|
|
162
|
-
cwd: this.projectPath,
|
|
163
|
-
timeout: getTimeout('GIT_OPERATION'),
|
|
164
|
-
})
|
|
165
|
-
const lines = stdout.trim().split('\n').filter(Boolean)
|
|
166
|
-
result.hasChanges = lines.length > 0
|
|
167
|
-
|
|
168
|
-
for (const line of lines) {
|
|
169
|
-
const code = line.substring(0, 2)
|
|
170
|
-
const file = line.substring(3)
|
|
171
|
-
|
|
172
|
-
if (code.startsWith('A') || code.startsWith('M ')) {
|
|
173
|
-
result.stagedFiles.push(file)
|
|
174
|
-
} else if (code.includes('M')) {
|
|
175
|
-
result.modifiedFiles.push(file)
|
|
176
|
-
} else if (code.startsWith('??')) {
|
|
177
|
-
result.untrackedFiles.push(file)
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
} catch {
|
|
181
|
-
// Not a git repo
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return result
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Get recent commits
|
|
189
|
-
*/
|
|
190
|
-
async getRecentCommits(
|
|
191
|
-
count: number = 20
|
|
192
|
-
): Promise<{ hash: string; message: string; date: string }[]> {
|
|
193
|
-
try {
|
|
194
|
-
const { stdout } = await execAsync(
|
|
195
|
-
`git log --oneline -${count} --pretty=format:"%h|%s|%ad" --date=short`,
|
|
196
|
-
{ cwd: this.projectPath, timeout: getTimeout('GIT_OPERATION') }
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
return stdout
|
|
200
|
-
.split('\n')
|
|
201
|
-
.filter(Boolean)
|
|
202
|
-
.map((line) => {
|
|
203
|
-
const [hash, message, date] = line.split('|')
|
|
204
|
-
return { hash, message, date }
|
|
205
|
-
})
|
|
206
|
-
} catch {
|
|
207
|
-
return []
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Get commit count in the last week
|
|
213
|
-
* PRJ-114: Avoids shell pipe by counting lines in JS
|
|
214
|
-
*/
|
|
215
|
-
async getWeeklyCommitCount(): Promise<number> {
|
|
216
|
-
try {
|
|
217
|
-
const { stdout } = await execAsync('git log --oneline --since="1 week ago"', {
|
|
218
|
-
cwd: this.projectPath,
|
|
219
|
-
timeout: getTimeout('GIT_OPERATION'),
|
|
220
|
-
})
|
|
221
|
-
// Count non-empty lines instead of piping to wc -l
|
|
222
|
-
const lines = stdout.trim().split('\n').filter(Boolean)
|
|
223
|
-
return lines.length
|
|
224
|
-
} catch {
|
|
225
|
-
return 0
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Check if directory is a git repository
|
|
231
|
-
*/
|
|
232
|
-
async isGitRepo(): Promise<boolean> {
|
|
233
|
-
try {
|
|
234
|
-
await execAsync('git rev-parse --is-inside-work-tree', {
|
|
235
|
-
cwd: this.projectPath,
|
|
236
|
-
timeout: getTimeout('GIT_OPERATION'),
|
|
237
|
-
})
|
|
238
|
-
return true
|
|
239
|
-
} catch {
|
|
240
|
-
return false
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Get default main branch name (main or master)
|
|
246
|
-
* PRJ-114: Avoids shell pipe by using JS string replace
|
|
247
|
-
*/
|
|
248
|
-
async getDefaultBranch(): Promise<string> {
|
|
249
|
-
try {
|
|
250
|
-
// Try to get from remote
|
|
251
|
-
const { stdout } = await execAsync('git symbolic-ref refs/remotes/origin/HEAD', {
|
|
252
|
-
cwd: this.projectPath,
|
|
253
|
-
timeout: getTimeout('GIT_OPERATION'),
|
|
254
|
-
})
|
|
255
|
-
// Use JS replace instead of piping to sed
|
|
256
|
-
const branch = stdout.trim().replace(/^refs\/remotes\/origin\//, '')
|
|
257
|
-
if (branch) return branch
|
|
258
|
-
} catch {
|
|
259
|
-
// Ignore - remote may not exist
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Fallback: check if main or master exists
|
|
263
|
-
try {
|
|
264
|
-
await execAsync('git show-ref --verify --quiet refs/heads/main', {
|
|
265
|
-
cwd: this.projectPath,
|
|
266
|
-
timeout: getTimeout('GIT_OPERATION'),
|
|
267
|
-
})
|
|
268
|
-
return 'main'
|
|
269
|
-
} catch {
|
|
270
|
-
return 'master'
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Get empty GitData for non-git repos or errors
|
|
277
|
-
*/
|
|
278
|
-
export function getEmptyGitData(): GitData {
|
|
279
|
-
return {
|
|
280
|
-
branch: 'main',
|
|
281
|
-
commits: 0,
|
|
282
|
-
contributors: 0,
|
|
283
|
-
hasChanges: false,
|
|
284
|
-
stagedFiles: [],
|
|
285
|
-
modifiedFiles: [],
|
|
286
|
-
untrackedFiles: [],
|
|
287
|
-
recentCommits: [],
|
|
288
|
-
weeklyCommits: 0,
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
export const gitAnalyzer = (projectPath: string) => new GitAnalyzer(projectPath)
|
|
293
|
-
export default GitAnalyzer
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HierarchicalAgentResolver - Resolves agents from hierarchical AGENTS.md files
|
|
3
|
-
*
|
|
4
|
-
* This service bridges:
|
|
5
|
-
* - NestedContextResolver (discovers AGENTS.md files in directory tree)
|
|
6
|
-
* - AgentLoader (loads generated agent files from global storage)
|
|
7
|
-
*
|
|
8
|
-
* Pattern: "Scope = directory tree. Deeper files take precedence."
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import path from 'node:path'
|
|
12
|
-
import NestedContextResolver, {
|
|
13
|
-
type AgentDefinition,
|
|
14
|
-
type NestedAgents,
|
|
15
|
-
type ResolvedAgents,
|
|
16
|
-
} from './nested-context-resolver'
|
|
17
|
-
|
|
18
|
-
// ============================================================================
|
|
19
|
-
// TYPES
|
|
20
|
-
// ============================================================================
|
|
21
|
-
|
|
22
|
-
export interface HierarchicalAgent {
|
|
23
|
-
/** Agent name (e.g., "frontend", "backend") */
|
|
24
|
-
name: string
|
|
25
|
-
/** Resolved description from hierarchy */
|
|
26
|
-
description: string
|
|
27
|
-
/** Domain specialization */
|
|
28
|
-
domain: string | null
|
|
29
|
-
/** Merged triggers from all levels */
|
|
30
|
-
triggers: string[]
|
|
31
|
-
/** Merged rules from all levels */
|
|
32
|
-
rules: string[]
|
|
33
|
-
/** Merged patterns from all levels */
|
|
34
|
-
patterns: string[]
|
|
35
|
-
/** Sources that contributed to this agent (paths) */
|
|
36
|
-
sources: string[]
|
|
37
|
-
/** Whether this agent was overridden at some level */
|
|
38
|
-
wasOverridden: boolean
|
|
39
|
-
/** Effort level hint for Claude's adaptive reasoning depth */
|
|
40
|
-
effort?: 'low' | 'medium' | 'high' | 'max'
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface AgentResolutionResult {
|
|
44
|
-
/** Resolved agents for the target path */
|
|
45
|
-
agents: HierarchicalAgent[]
|
|
46
|
-
/** Root path of the resolution */
|
|
47
|
-
rootPath: string
|
|
48
|
-
/** Target path that was resolved */
|
|
49
|
-
targetPath: string
|
|
50
|
-
/** All AGENTS.md files discovered */
|
|
51
|
-
discoveredFiles: string[]
|
|
52
|
-
/** Agents that were overridden during resolution */
|
|
53
|
-
overriddenAgents: string[]
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// ============================================================================
|
|
57
|
-
// HIERARCHICAL AGENT RESOLVER
|
|
58
|
-
// ============================================================================
|
|
59
|
-
|
|
60
|
-
export class HierarchicalAgentResolver {
|
|
61
|
-
private resolver: NestedContextResolver
|
|
62
|
-
private rootPath: string
|
|
63
|
-
private initialized = false
|
|
64
|
-
|
|
65
|
-
constructor(rootPath: string) {
|
|
66
|
-
this.rootPath = path.resolve(rootPath)
|
|
67
|
-
this.resolver = new NestedContextResolver(this.rootPath)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Initialize the resolver (detects monorepo structure)
|
|
72
|
-
*/
|
|
73
|
-
async initialize(): Promise<void> {
|
|
74
|
-
if (!this.initialized) {
|
|
75
|
-
await this.resolver.initialize()
|
|
76
|
-
this.initialized = true
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Resolve agents for a specific directory path
|
|
82
|
-
* Returns merged agents following hierarchical inheritance
|
|
83
|
-
*/
|
|
84
|
-
async resolveAgentsForPath(targetPath: string): Promise<AgentResolutionResult> {
|
|
85
|
-
await this.initialize()
|
|
86
|
-
|
|
87
|
-
const resolved = await this.resolver.resolveAgentsForPath(targetPath)
|
|
88
|
-
const allAgentFiles = await this.resolver.discoverAgentFiles()
|
|
89
|
-
|
|
90
|
-
return {
|
|
91
|
-
agents: resolved.agents.map((agent) => this.toHierarchicalAgent(agent, resolved)),
|
|
92
|
-
rootPath: this.rootPath,
|
|
93
|
-
targetPath: path.resolve(targetPath),
|
|
94
|
-
discoveredFiles: allAgentFiles.map((af) => af.path),
|
|
95
|
-
overriddenAgents: resolved.overrides.map((o) => o.split(':')[1]),
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Resolve agents for the root project
|
|
101
|
-
*/
|
|
102
|
-
async resolveRootAgents(): Promise<AgentResolutionResult> {
|
|
103
|
-
return this.resolveAgentsForPath(this.rootPath)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Get a specific agent by name for a path
|
|
108
|
-
*/
|
|
109
|
-
async getAgentByName(agentName: string, targetPath?: string): Promise<HierarchicalAgent | null> {
|
|
110
|
-
const result = await this.resolveAgentsForPath(targetPath || this.rootPath)
|
|
111
|
-
return result.agents.find((a) => a.name.toLowerCase() === agentName.toLowerCase()) || null
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Get all available agent names across the hierarchy
|
|
116
|
-
*/
|
|
117
|
-
async getAllAgentNames(): Promise<string[]> {
|
|
118
|
-
await this.initialize()
|
|
119
|
-
|
|
120
|
-
const agentFiles = await this.resolver.discoverAgentFiles()
|
|
121
|
-
const names = new Set<string>()
|
|
122
|
-
|
|
123
|
-
for (const file of agentFiles) {
|
|
124
|
-
for (const agent of file.agents) {
|
|
125
|
-
names.add(agent.name)
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return Array.from(names).sort()
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Check if a specific agent exists anywhere in the hierarchy
|
|
134
|
-
*/
|
|
135
|
-
async agentExists(agentName: string): Promise<boolean> {
|
|
136
|
-
const names = await this.getAllAgentNames()
|
|
137
|
-
return names.some((n) => n.toLowerCase() === agentName.toLowerCase())
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Get the raw AGENTS.md file tree structure
|
|
142
|
-
*/
|
|
143
|
-
async getAgentFileTree(): Promise<NestedAgents[]> {
|
|
144
|
-
await this.initialize()
|
|
145
|
-
return this.resolver.discoverAgentFiles()
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Convert AgentDefinition to HierarchicalAgent
|
|
150
|
-
*/
|
|
151
|
-
private toHierarchicalAgent(agent: AgentDefinition, resolved: ResolvedAgents): HierarchicalAgent {
|
|
152
|
-
const wasOverridden = resolved.overrides.some((o) => o.split(':')[1] === agent.name)
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
name: agent.name,
|
|
156
|
-
description: agent.description,
|
|
157
|
-
domain: agent.domain || null,
|
|
158
|
-
triggers: agent.triggers || [],
|
|
159
|
-
rules: agent.rules || [],
|
|
160
|
-
patterns: agent.patterns || [],
|
|
161
|
-
sources: resolved.sources,
|
|
162
|
-
wasOverridden,
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Generate markdown content for an agent (for use with AgentLoader)
|
|
168
|
-
*/
|
|
169
|
-
generateAgentMarkdown(agent: HierarchicalAgent): string {
|
|
170
|
-
const parts: string[] = []
|
|
171
|
-
|
|
172
|
-
// Header
|
|
173
|
-
parts.push(`# ${agent.name} Agent`)
|
|
174
|
-
parts.push('')
|
|
175
|
-
|
|
176
|
-
// Description
|
|
177
|
-
if (agent.description) {
|
|
178
|
-
parts.push(agent.description)
|
|
179
|
-
parts.push('')
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Domain
|
|
183
|
-
if (agent.domain) {
|
|
184
|
-
parts.push(`## DOMAIN AUTHORITY`)
|
|
185
|
-
parts.push('')
|
|
186
|
-
parts.push(`This agent specializes in the ${agent.domain} domain.`)
|
|
187
|
-
parts.push('')
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Triggers
|
|
191
|
-
if (agent.triggers.length > 0) {
|
|
192
|
-
parts.push(`## Triggers`)
|
|
193
|
-
parts.push('')
|
|
194
|
-
for (const trigger of agent.triggers) {
|
|
195
|
-
parts.push(`- ${trigger}`)
|
|
196
|
-
}
|
|
197
|
-
parts.push('')
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Rules
|
|
201
|
-
if (agent.rules.length > 0) {
|
|
202
|
-
parts.push(`## Rules`)
|
|
203
|
-
parts.push('')
|
|
204
|
-
for (const rule of agent.rules) {
|
|
205
|
-
parts.push(`- ${rule}`)
|
|
206
|
-
}
|
|
207
|
-
parts.push('')
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Patterns
|
|
211
|
-
if (agent.patterns.length > 0) {
|
|
212
|
-
parts.push(`## Patterns`)
|
|
213
|
-
parts.push('')
|
|
214
|
-
for (const pattern of agent.patterns) {
|
|
215
|
-
parts.push('```')
|
|
216
|
-
parts.push(pattern)
|
|
217
|
-
parts.push('```')
|
|
218
|
-
parts.push('')
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Source attribution
|
|
223
|
-
if (agent.sources.length > 0) {
|
|
224
|
-
parts.push(`---`)
|
|
225
|
-
parts.push(`*Resolved from: ${agent.sources.join(' → ')}*`)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return parts.join('\n')
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// ============================================================================
|
|
233
|
-
// EXPORTS
|
|
234
|
-
// ============================================================================
|
|
235
|
-
|
|
236
|
-
export default HierarchicalAgentResolver
|