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,443 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for NestedContextResolver - AGENTS.md discovery and resolution
|
|
3
|
-
* PRJ-101: Hierarchical scope system
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
|
|
7
|
-
import fs from 'node:fs/promises'
|
|
8
|
-
import os from 'node:os'
|
|
9
|
-
import path from 'node:path'
|
|
10
|
-
import NestedContextResolver from '../../services/nested-context-resolver'
|
|
11
|
-
|
|
12
|
-
// Test directory setup
|
|
13
|
-
let testDir: string
|
|
14
|
-
let resolver: NestedContextResolver
|
|
15
|
-
|
|
16
|
-
beforeEach(async () => {
|
|
17
|
-
// Create temp directory for tests
|
|
18
|
-
testDir = path.join(os.tmpdir(), `prjct-test-${Date.now()}`)
|
|
19
|
-
await fs.mkdir(testDir, { recursive: true })
|
|
20
|
-
resolver = new NestedContextResolver(testDir)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
afterEach(async () => {
|
|
24
|
-
// Cleanup temp directory
|
|
25
|
-
try {
|
|
26
|
-
await fs.rm(testDir, { recursive: true, force: true })
|
|
27
|
-
} catch {
|
|
28
|
-
// Ignore cleanup errors
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
// =============================================================================
|
|
33
|
-
// PRJCT.md Discovery Tests (existing functionality)
|
|
34
|
-
// =============================================================================
|
|
35
|
-
|
|
36
|
-
describe('NestedContextResolver - PRJCT.md', () => {
|
|
37
|
-
test('discovers root PRJCT.md', async () => {
|
|
38
|
-
await fs.writeFile(path.join(testDir, 'PRJCT.md'), '## Rules\n\n- Rule 1\n- Rule 2')
|
|
39
|
-
|
|
40
|
-
const contexts = await resolver.discoverContextFiles()
|
|
41
|
-
|
|
42
|
-
expect(contexts).toHaveLength(1)
|
|
43
|
-
expect(contexts[0].depth).toBe(0)
|
|
44
|
-
expect(contexts[0].sections).toHaveLength(1)
|
|
45
|
-
expect(contexts[0].sections[0].name).toBe('Rules')
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
test('parses sections with override marker', async () => {
|
|
49
|
-
await fs.writeFile(path.join(testDir, 'PRJCT.md'), '## Rules @override\n\n- Override rule')
|
|
50
|
-
|
|
51
|
-
const contexts = await resolver.discoverContextFiles()
|
|
52
|
-
|
|
53
|
-
expect(contexts[0].sections[0].override).toBe(true)
|
|
54
|
-
expect(contexts[0].sections[0].name).toBe('Rules')
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
test('handles empty project (no PRJCT.md)', async () => {
|
|
58
|
-
const contexts = await resolver.discoverContextFiles()
|
|
59
|
-
expect(contexts).toHaveLength(0)
|
|
60
|
-
})
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
// =============================================================================
|
|
64
|
-
// AGENTS.md Discovery Tests (new functionality)
|
|
65
|
-
// =============================================================================
|
|
66
|
-
|
|
67
|
-
describe('NestedContextResolver - AGENTS.md Discovery', () => {
|
|
68
|
-
test('discovers root AGENTS.md', async () => {
|
|
69
|
-
await fs.writeFile(
|
|
70
|
-
path.join(testDir, 'AGENTS.md'),
|
|
71
|
-
`## Backend
|
|
72
|
-
|
|
73
|
-
Handles backend development.
|
|
74
|
-
|
|
75
|
-
### Triggers
|
|
76
|
-
- api
|
|
77
|
-
- endpoint
|
|
78
|
-
|
|
79
|
-
### Rules
|
|
80
|
-
- Use async/await
|
|
81
|
-
`
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
85
|
-
|
|
86
|
-
expect(agentFiles).toHaveLength(1)
|
|
87
|
-
expect(agentFiles[0].depth).toBe(0)
|
|
88
|
-
expect(agentFiles[0].agents).toHaveLength(1)
|
|
89
|
-
expect(agentFiles[0].agents[0].name).toBe('Backend')
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
test('parses multiple agents from single file', async () => {
|
|
93
|
-
await fs.writeFile(
|
|
94
|
-
path.join(testDir, 'AGENTS.md'),
|
|
95
|
-
`## Frontend
|
|
96
|
-
|
|
97
|
-
Frontend specialist.
|
|
98
|
-
|
|
99
|
-
### Triggers
|
|
100
|
-
- component
|
|
101
|
-
- ui
|
|
102
|
-
|
|
103
|
-
## Backend
|
|
104
|
-
|
|
105
|
-
Backend specialist.
|
|
106
|
-
|
|
107
|
-
### Triggers
|
|
108
|
-
- api
|
|
109
|
-
- database
|
|
110
|
-
`
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
114
|
-
|
|
115
|
-
expect(agentFiles[0].agents).toHaveLength(2)
|
|
116
|
-
expect(agentFiles[0].agents[0].name).toBe('Frontend')
|
|
117
|
-
expect(agentFiles[0].agents[1].name).toBe('Backend')
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
test('parses agent triggers as array', async () => {
|
|
121
|
-
await fs.writeFile(
|
|
122
|
-
path.join(testDir, 'AGENTS.md'),
|
|
123
|
-
`## Testing
|
|
124
|
-
|
|
125
|
-
Testing specialist.
|
|
126
|
-
|
|
127
|
-
### Triggers
|
|
128
|
-
- write test
|
|
129
|
-
- add test
|
|
130
|
-
- unit test
|
|
131
|
-
`
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
135
|
-
const agent = agentFiles[0].agents[0]
|
|
136
|
-
|
|
137
|
-
expect(agent.triggers).toEqual(['write test', 'add test', 'unit test'])
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
test('parses agent rules as array', async () => {
|
|
141
|
-
await fs.writeFile(
|
|
142
|
-
path.join(testDir, 'AGENTS.md'),
|
|
143
|
-
`## Backend
|
|
144
|
-
|
|
145
|
-
Backend specialist.
|
|
146
|
-
|
|
147
|
-
### Rules
|
|
148
|
-
- Use TypeScript
|
|
149
|
-
- Validate inputs
|
|
150
|
-
- Log errors
|
|
151
|
-
`
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
155
|
-
const agent = agentFiles[0].agents[0]
|
|
156
|
-
|
|
157
|
-
expect(agent.rules).toEqual(['Use TypeScript', 'Validate inputs', 'Log errors'])
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
test('parses code patterns from code blocks', async () => {
|
|
161
|
-
await fs.writeFile(
|
|
162
|
-
path.join(testDir, 'AGENTS.md'),
|
|
163
|
-
`## Backend
|
|
164
|
-
|
|
165
|
-
Backend specialist.
|
|
166
|
-
|
|
167
|
-
### Patterns
|
|
168
|
-
\`\`\`typescript
|
|
169
|
-
async function handler(req: Request) {
|
|
170
|
-
return new Response('ok')
|
|
171
|
-
}
|
|
172
|
-
\`\`\`
|
|
173
|
-
`
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
177
|
-
const agent = agentFiles[0].agents[0]
|
|
178
|
-
|
|
179
|
-
expect(agent.patterns).toHaveLength(1)
|
|
180
|
-
expect(agent.patterns![0]).toContain('async function handler')
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
test('detects @override marker on agent', async () => {
|
|
184
|
-
await fs.writeFile(
|
|
185
|
-
path.join(testDir, 'AGENTS.md'),
|
|
186
|
-
`## Frontend @override
|
|
187
|
-
|
|
188
|
-
Overrides parent frontend agent.
|
|
189
|
-
`
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
193
|
-
const agent = agentFiles[0].agents[0]
|
|
194
|
-
|
|
195
|
-
expect(agent.name).toBe('Frontend')
|
|
196
|
-
expect(agent.override).toBe(true)
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
test('handles empty AGENTS.md', async () => {
|
|
200
|
-
await fs.writeFile(path.join(testDir, 'AGENTS.md'), '# AGENTS.md\n\nNo agents defined.')
|
|
201
|
-
|
|
202
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
203
|
-
|
|
204
|
-
expect(agentFiles).toHaveLength(1)
|
|
205
|
-
expect(agentFiles[0].agents).toHaveLength(0)
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
test('handles missing AGENTS.md', async () => {
|
|
209
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
210
|
-
expect(agentFiles).toHaveLength(0)
|
|
211
|
-
})
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
// =============================================================================
|
|
215
|
-
// AGENTS.md Hierarchy Tests
|
|
216
|
-
// =============================================================================
|
|
217
|
-
|
|
218
|
-
describe('NestedContextResolver - AGENTS.md Hierarchy', () => {
|
|
219
|
-
test('discovers nested AGENTS.md in subdirectories', async () => {
|
|
220
|
-
// Create root AGENTS.md
|
|
221
|
-
await fs.writeFile(
|
|
222
|
-
path.join(testDir, 'AGENTS.md'),
|
|
223
|
-
`## GlobalAgent
|
|
224
|
-
|
|
225
|
-
Global agent for all.
|
|
226
|
-
`
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
// Create subdirectory with AGENTS.md
|
|
230
|
-
const subDir = path.join(testDir, 'packages', 'web')
|
|
231
|
-
await fs.mkdir(subDir, { recursive: true })
|
|
232
|
-
await fs.writeFile(
|
|
233
|
-
path.join(subDir, 'AGENTS.md'),
|
|
234
|
-
`## WebAgent
|
|
235
|
-
|
|
236
|
-
Web-specific agent.
|
|
237
|
-
`
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
241
|
-
|
|
242
|
-
expect(agentFiles).toHaveLength(2)
|
|
243
|
-
expect(agentFiles.find((af) => af.depth === 0)?.agents[0].name).toBe('GlobalAgent')
|
|
244
|
-
})
|
|
245
|
-
|
|
246
|
-
test('builds parent-child relationships', async () => {
|
|
247
|
-
// Create root AGENTS.md
|
|
248
|
-
await fs.writeFile(path.join(testDir, 'AGENTS.md'), '## Root\n\nRoot agent.')
|
|
249
|
-
|
|
250
|
-
// Create child AGENTS.md
|
|
251
|
-
const childDir = path.join(testDir, 'src')
|
|
252
|
-
await fs.mkdir(childDir, { recursive: true })
|
|
253
|
-
await fs.writeFile(path.join(childDir, 'AGENTS.md'), '## Child\n\nChild agent.')
|
|
254
|
-
|
|
255
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
256
|
-
|
|
257
|
-
const root = agentFiles.find((af) => af.depth === 0)
|
|
258
|
-
const child = agentFiles.find((af) => af.depth > 0)
|
|
259
|
-
|
|
260
|
-
expect(root).toBeDefined()
|
|
261
|
-
expect(child).toBeDefined()
|
|
262
|
-
expect(child?.parent).toBe(root)
|
|
263
|
-
expect(root?.children).toContain(child)
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
test('resolves agents for path with inheritance', async () => {
|
|
267
|
-
// Root defines base agents
|
|
268
|
-
await fs.writeFile(
|
|
269
|
-
path.join(testDir, 'AGENTS.md'),
|
|
270
|
-
`## Shared
|
|
271
|
-
|
|
272
|
-
Shared rules for all.
|
|
273
|
-
|
|
274
|
-
### Rules
|
|
275
|
-
- Rule from root
|
|
276
|
-
`
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
// Child adds more rules
|
|
280
|
-
const childDir = path.join(testDir, 'packages', 'api')
|
|
281
|
-
await fs.mkdir(childDir, { recursive: true })
|
|
282
|
-
await fs.writeFile(
|
|
283
|
-
path.join(childDir, 'AGENTS.md'),
|
|
284
|
-
`## Shared
|
|
285
|
-
|
|
286
|
-
Extended in child.
|
|
287
|
-
|
|
288
|
-
### Rules
|
|
289
|
-
- Rule from child
|
|
290
|
-
`
|
|
291
|
-
)
|
|
292
|
-
|
|
293
|
-
const resolved = await resolver.resolveAgentsForPath(childDir)
|
|
294
|
-
|
|
295
|
-
expect(resolved.agents).toHaveLength(1)
|
|
296
|
-
expect(resolved.agents[0].name).toBe('Shared')
|
|
297
|
-
// Rules should be merged
|
|
298
|
-
expect(resolved.agents[0].rules).toContain('Rule from root')
|
|
299
|
-
expect(resolved.agents[0].rules).toContain('Rule from child')
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
test('override replaces parent agent entirely', async () => {
|
|
303
|
-
// Root defines agent
|
|
304
|
-
await fs.writeFile(
|
|
305
|
-
path.join(testDir, 'AGENTS.md'),
|
|
306
|
-
`## Frontend
|
|
307
|
-
|
|
308
|
-
Root frontend agent.
|
|
309
|
-
|
|
310
|
-
### Rules
|
|
311
|
-
- Root rule 1
|
|
312
|
-
- Root rule 2
|
|
313
|
-
`
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
// Child overrides
|
|
317
|
-
const childDir = path.join(testDir, 'web')
|
|
318
|
-
await fs.mkdir(childDir, { recursive: true })
|
|
319
|
-
await fs.writeFile(
|
|
320
|
-
path.join(childDir, 'AGENTS.md'),
|
|
321
|
-
`## Frontend @override
|
|
322
|
-
|
|
323
|
-
Completely new frontend agent.
|
|
324
|
-
|
|
325
|
-
### Rules
|
|
326
|
-
- Child rule only
|
|
327
|
-
`
|
|
328
|
-
)
|
|
329
|
-
|
|
330
|
-
const resolved = await resolver.resolveAgentsForPath(childDir)
|
|
331
|
-
|
|
332
|
-
expect(resolved.agents).toHaveLength(1)
|
|
333
|
-
expect(resolved.agents[0].rules).toHaveLength(1)
|
|
334
|
-
expect(resolved.agents[0].rules).toContain('Child rule only')
|
|
335
|
-
expect(resolved.overrides).toContain(`web/AGENTS.md:Frontend`)
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
test('adds new agents from child without affecting parent agents', async () => {
|
|
339
|
-
// Root has one agent
|
|
340
|
-
await fs.writeFile(path.join(testDir, 'AGENTS.md'), '## Backend\n\nBackend agent.')
|
|
341
|
-
|
|
342
|
-
// Child adds different agent
|
|
343
|
-
const childDir = path.join(testDir, 'mobile')
|
|
344
|
-
await fs.mkdir(childDir, { recursive: true })
|
|
345
|
-
await fs.writeFile(path.join(childDir, 'AGENTS.md'), '## Mobile\n\nMobile agent.')
|
|
346
|
-
|
|
347
|
-
const resolved = await resolver.resolveAgentsForPath(childDir)
|
|
348
|
-
|
|
349
|
-
expect(resolved.agents).toHaveLength(2)
|
|
350
|
-
expect(resolved.agents.map((a) => a.name).sort()).toEqual(['Backend', 'Mobile'])
|
|
351
|
-
})
|
|
352
|
-
|
|
353
|
-
test('tracks sources in resolution', async () => {
|
|
354
|
-
await fs.writeFile(path.join(testDir, 'AGENTS.md'), '## Agent\n\nRoot.')
|
|
355
|
-
|
|
356
|
-
const level1 = path.join(testDir, 'level1')
|
|
357
|
-
await fs.mkdir(level1)
|
|
358
|
-
await fs.writeFile(path.join(level1, 'AGENTS.md'), '## Agent\n\nLevel 1.')
|
|
359
|
-
|
|
360
|
-
const level2 = path.join(level1, 'level2')
|
|
361
|
-
await fs.mkdir(level2)
|
|
362
|
-
await fs.writeFile(path.join(level2, 'AGENTS.md'), '## Agent\n\nLevel 2.')
|
|
363
|
-
|
|
364
|
-
const resolved = await resolver.resolveAgentsForPath(level2)
|
|
365
|
-
|
|
366
|
-
expect(resolved.sources).toHaveLength(3)
|
|
367
|
-
expect(resolved.sources[0]).toBe('AGENTS.md')
|
|
368
|
-
expect(resolved.sources[1]).toBe('level1/AGENTS.md')
|
|
369
|
-
expect(resolved.sources[2]).toBe('level1/level2/AGENTS.md')
|
|
370
|
-
})
|
|
371
|
-
})
|
|
372
|
-
|
|
373
|
-
// =============================================================================
|
|
374
|
-
// Edge Cases
|
|
375
|
-
// =============================================================================
|
|
376
|
-
|
|
377
|
-
describe('NestedContextResolver - Edge Cases', () => {
|
|
378
|
-
test('ignores node_modules directories', async () => {
|
|
379
|
-
await fs.writeFile(path.join(testDir, 'AGENTS.md'), '## Root\n\nRoot.')
|
|
380
|
-
|
|
381
|
-
// Create AGENTS.md in node_modules (should be ignored)
|
|
382
|
-
const nmDir = path.join(testDir, 'node_modules', 'some-package')
|
|
383
|
-
await fs.mkdir(nmDir, { recursive: true })
|
|
384
|
-
await fs.writeFile(path.join(nmDir, 'AGENTS.md'), '## ShouldIgnore\n\nIgnored.')
|
|
385
|
-
|
|
386
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
387
|
-
|
|
388
|
-
expect(agentFiles).toHaveLength(1)
|
|
389
|
-
expect(agentFiles[0].agents[0].name).toBe('Root')
|
|
390
|
-
})
|
|
391
|
-
|
|
392
|
-
test('ignores dot directories', async () => {
|
|
393
|
-
await fs.writeFile(path.join(testDir, 'AGENTS.md'), '## Root\n\nRoot.')
|
|
394
|
-
|
|
395
|
-
// Create AGENTS.md in .git (should be ignored)
|
|
396
|
-
const gitDir = path.join(testDir, '.git', 'hooks')
|
|
397
|
-
await fs.mkdir(gitDir, { recursive: true })
|
|
398
|
-
await fs.writeFile(path.join(gitDir, 'AGENTS.md'), '## ShouldIgnore\n\nIgnored.')
|
|
399
|
-
|
|
400
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
401
|
-
|
|
402
|
-
expect(agentFiles).toHaveLength(1)
|
|
403
|
-
})
|
|
404
|
-
|
|
405
|
-
test('handles malformed AGENTS.md gracefully', async () => {
|
|
406
|
-
await fs.writeFile(
|
|
407
|
-
path.join(testDir, 'AGENTS.md'),
|
|
408
|
-
`# Not a proper agent header
|
|
409
|
-
|
|
410
|
-
Some text here
|
|
411
|
-
|
|
412
|
-
### Rules without agent
|
|
413
|
-
- orphan rule
|
|
414
|
-
|
|
415
|
-
## Proper Agent
|
|
416
|
-
|
|
417
|
-
This one is valid.
|
|
418
|
-
`
|
|
419
|
-
)
|
|
420
|
-
|
|
421
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
422
|
-
|
|
423
|
-
// Should only find the valid agent
|
|
424
|
-
expect(agentFiles[0].agents).toHaveLength(1)
|
|
425
|
-
expect(agentFiles[0].agents[0].name).toBe('Proper Agent')
|
|
426
|
-
})
|
|
427
|
-
|
|
428
|
-
test('limits scanning depth to prevent infinite recursion', async () => {
|
|
429
|
-
// Create deeply nested directory structure
|
|
430
|
-
let currentDir = testDir
|
|
431
|
-
for (let i = 0; i < 10; i++) {
|
|
432
|
-
currentDir = path.join(currentDir, `level${i}`)
|
|
433
|
-
await fs.mkdir(currentDir, { recursive: true })
|
|
434
|
-
await fs.writeFile(path.join(currentDir, 'AGENTS.md'), `## Level${i}\n\nLevel ${i} agent.`)
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// Should complete without hanging (depth limit is 5)
|
|
438
|
-
const agentFiles = await resolver.discoverAgentFiles()
|
|
439
|
-
|
|
440
|
-
// Should find root + up to 5 levels deep
|
|
441
|
-
expect(agentFiles.length).toBeLessThanOrEqual(6)
|
|
442
|
-
})
|
|
443
|
-
})
|