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,272 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Template Executor
|
|
3
|
-
*
|
|
4
|
-
* Executes templates as the entry point for agentic command execution.
|
|
5
|
-
* TypeScript provides infrastructure (paths, reads/writes).
|
|
6
|
-
* Claude takes all agentic decisions via templates.
|
|
7
|
-
*
|
|
8
|
-
* @module agentic/template-executor
|
|
9
|
-
* @version 1.0.0
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import fs from 'node:fs/promises'
|
|
13
|
-
import path from 'node:path'
|
|
14
|
-
import configManager from '../infrastructure/config-manager'
|
|
15
|
-
import pathManager from '../infrastructure/path-manager'
|
|
16
|
-
import { isNotFoundError } from '../types/fs'
|
|
17
|
-
|
|
18
|
-
// =============================================================================
|
|
19
|
-
// Types
|
|
20
|
-
// =============================================================================
|
|
21
|
-
|
|
22
|
-
export interface TemplateExecutionContext {
|
|
23
|
-
projectPath: string
|
|
24
|
-
projectId: string
|
|
25
|
-
globalPath: string
|
|
26
|
-
command: string
|
|
27
|
-
args: string
|
|
28
|
-
|
|
29
|
-
// Agent information
|
|
30
|
-
agentName: string
|
|
31
|
-
agentSettingsPath: string
|
|
32
|
-
|
|
33
|
-
// Paths for agent (not content)
|
|
34
|
-
paths: {
|
|
35
|
-
orchestrator: string
|
|
36
|
-
agentRouting: string
|
|
37
|
-
taskFragmentation: string
|
|
38
|
-
commandTemplate: string
|
|
39
|
-
repoAnalysis: string
|
|
40
|
-
agentsDir: string
|
|
41
|
-
skillsDir: string
|
|
42
|
-
stateJson: string
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface AgenticPromptInfo {
|
|
47
|
-
prompt: string
|
|
48
|
-
context: TemplateExecutionContext
|
|
49
|
-
requiresOrchestration: boolean
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Commands that require orchestration (task routing, fragmentation)
|
|
53
|
-
const ORCHESTRATED_COMMANDS = ['task', 'done', 'ship', 'resume', 'bug', 'enrich']
|
|
54
|
-
|
|
55
|
-
// Commands that do NOT need orchestration
|
|
56
|
-
const SIMPLE_COMMANDS = ['init', 'sync', 'pause', 'next', 'dash', 'history', 'undo', 'redo']
|
|
57
|
-
|
|
58
|
-
// =============================================================================
|
|
59
|
-
// Template Executor Class
|
|
60
|
-
// =============================================================================
|
|
61
|
-
|
|
62
|
-
export class TemplateExecutor {
|
|
63
|
-
/**
|
|
64
|
-
* Get npm root for templates path
|
|
65
|
-
*/
|
|
66
|
-
private async getNpmRoot(): Promise<string> {
|
|
67
|
-
// Get the templates path relative to this module
|
|
68
|
-
// In production, templates are in the npm package
|
|
69
|
-
const moduleDir = path.dirname(require.resolve('prjct-cli/package.json'))
|
|
70
|
-
return moduleDir
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Get project ID from local config
|
|
75
|
-
*/
|
|
76
|
-
private async getProjectId(projectPath: string): Promise<string> {
|
|
77
|
-
return configManager.getProjectId(projectPath)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Build execution context with paths only
|
|
82
|
-
* Claude reads files agentically - we don't inject content
|
|
83
|
-
*/
|
|
84
|
-
async buildContext(
|
|
85
|
-
command: string,
|
|
86
|
-
args: string,
|
|
87
|
-
projectPath: string
|
|
88
|
-
): Promise<TemplateExecutionContext> {
|
|
89
|
-
const projectId = await this.getProjectId(projectPath)
|
|
90
|
-
const globalPath = pathManager.getGlobalProjectPath(projectId)
|
|
91
|
-
const aiProvider = require('../infrastructure/ai-provider')
|
|
92
|
-
const activeProvider = await aiProvider.getActiveProvider()
|
|
93
|
-
|
|
94
|
-
// Get templates directory - use local path during development
|
|
95
|
-
let templatesDir: string
|
|
96
|
-
try {
|
|
97
|
-
const npmRoot = await this.getNpmRoot()
|
|
98
|
-
templatesDir = path.join(npmRoot, 'templates')
|
|
99
|
-
} catch {
|
|
100
|
-
// Fallback to local templates during development
|
|
101
|
-
templatesDir = path.join(__dirname, '..', '..', 'templates')
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
projectPath,
|
|
106
|
-
projectId,
|
|
107
|
-
globalPath,
|
|
108
|
-
command,
|
|
109
|
-
args,
|
|
110
|
-
agentName: activeProvider.displayName,
|
|
111
|
-
agentSettingsPath: await pathManager.getAgentSettingsPath(),
|
|
112
|
-
paths: {
|
|
113
|
-
orchestrator: path.join(templatesDir, 'agentic', 'orchestrator.md'),
|
|
114
|
-
agentRouting: path.join(templatesDir, 'agentic', 'agent-routing.md'),
|
|
115
|
-
taskFragmentation: path.join(templatesDir, 'agentic', 'task-fragmentation.md'),
|
|
116
|
-
commandTemplate: path.join(templatesDir, 'commands', `${command}.md`),
|
|
117
|
-
repoAnalysis: path.join(globalPath, 'analysis', 'repo-analysis.json'),
|
|
118
|
-
agentsDir: path.join(globalPath, 'agents'),
|
|
119
|
-
skillsDir: activeProvider.skillsDir,
|
|
120
|
-
stateJson: path.join(globalPath, 'storage', 'state.json'),
|
|
121
|
-
},
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Check if a command requires orchestration
|
|
127
|
-
*/
|
|
128
|
-
requiresOrchestration(command: string): boolean {
|
|
129
|
-
if (ORCHESTRATED_COMMANDS.includes(command)) return true
|
|
130
|
-
if (SIMPLE_COMMANDS.includes(command)) return false
|
|
131
|
-
// Default: assume orchestration needed for unknown commands
|
|
132
|
-
return true
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Check if agents exist for the project
|
|
137
|
-
*/
|
|
138
|
-
async hasAgents(projectPath: string): Promise<boolean> {
|
|
139
|
-
try {
|
|
140
|
-
const projectId = await this.getProjectId(projectPath)
|
|
141
|
-
const agentsDir = path.join(pathManager.getGlobalProjectPath(projectId), 'agents')
|
|
142
|
-
const files = await fs.readdir(agentsDir)
|
|
143
|
-
return files.some((f) => f.endsWith('.md'))
|
|
144
|
-
} catch (error) {
|
|
145
|
-
if (isNotFoundError(error)) return false
|
|
146
|
-
return false
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Get list of available agent names
|
|
152
|
-
*/
|
|
153
|
-
async getAvailableAgents(projectPath: string): Promise<string[]> {
|
|
154
|
-
try {
|
|
155
|
-
const projectId = await this.getProjectId(projectPath)
|
|
156
|
-
const agentsDir = path.join(pathManager.getGlobalProjectPath(projectId), 'agents')
|
|
157
|
-
const files = await fs.readdir(agentsDir)
|
|
158
|
-
return files.filter((f) => f.endsWith('.md')).map((f) => f.replace('.md', ''))
|
|
159
|
-
} catch {
|
|
160
|
-
return []
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Build prompt that tells agent to execute templates agentically
|
|
166
|
-
*/
|
|
167
|
-
buildAgenticPrompt(context: TemplateExecutionContext): AgenticPromptInfo {
|
|
168
|
-
const requiresOrchestration = this.requiresOrchestration(context.command)
|
|
169
|
-
|
|
170
|
-
const prompt = `
|
|
171
|
-
## Agentic Execution Mode
|
|
172
|
-
|
|
173
|
-
You are executing a prjct command as ${context.agentName}. Follow the template-first approach.
|
|
174
|
-
|
|
175
|
-
### Context
|
|
176
|
-
- Agent: ${context.agentName}
|
|
177
|
-
- Settings: ${context.agentSettingsPath}
|
|
178
|
-
- Command: ${context.command}
|
|
179
|
-
- Args: ${context.args}
|
|
180
|
-
- Project: ${context.projectPath}
|
|
181
|
-
- Project ID: ${context.projectId}
|
|
182
|
-
|
|
183
|
-
### Paths (Read as needed)
|
|
184
|
-
- Orchestrator: ${context.paths.orchestrator}
|
|
185
|
-
- Agent Routing: ${context.paths.agentRouting}
|
|
186
|
-
- Task Fragmentation: ${context.paths.taskFragmentation}
|
|
187
|
-
- Command Template: ${context.paths.commandTemplate}
|
|
188
|
-
- Repo Analysis: ${context.paths.repoAnalysis}
|
|
189
|
-
- Agents Directory: ${context.paths.agentsDir}
|
|
190
|
-
- Skills Directory: ${context.paths.skillsDir}
|
|
191
|
-
- State JSON: ${context.paths.stateJson}
|
|
192
|
-
|
|
193
|
-
### Instructions
|
|
194
|
-
|
|
195
|
-
1. **Read the command template** (${context.paths.commandTemplate})
|
|
196
|
-
|
|
197
|
-
2. **Check if orchestration is needed**
|
|
198
|
-
- This command ${requiresOrchestration ? 'REQUIRES' : 'does NOT require'} orchestration
|
|
199
|
-
${
|
|
200
|
-
requiresOrchestration
|
|
201
|
-
? `
|
|
202
|
-
3. **Orchestration steps:**
|
|
203
|
-
- Read: ${context.paths.orchestrator}
|
|
204
|
-
- Read: ${context.paths.repoAnalysis} to understand project technologies
|
|
205
|
-
- Analyze the task: "${context.args}"
|
|
206
|
-
- Determine which domains are ACTUALLY relevant based on:
|
|
207
|
-
a) What the task requires
|
|
208
|
-
b) What technologies exist in this project
|
|
209
|
-
c) What agents are available in ${context.paths.agentsDir}
|
|
210
|
-
|
|
211
|
-
- **IMPORTANT**: The agents in ${context.paths.agentsDir} are already project-specific
|
|
212
|
-
(they were generated during p. sync with the actual project technologies)
|
|
213
|
-
|
|
214
|
-
- ALWAYS use the specialist if one exists for the domain
|
|
215
|
-
- Only use the generalist if there is NO agent for that domain
|
|
216
|
-
|
|
217
|
-
- Check if task should be fragmented (read: ${context.paths.taskFragmentation})
|
|
218
|
-
- If agents loaded, check their skills and load from ${context.paths.skillsDir}
|
|
219
|
-
`
|
|
220
|
-
: `
|
|
221
|
-
3. **Simple execution:**
|
|
222
|
-
- Execute the command template directly
|
|
223
|
-
- No agent routing needed
|
|
224
|
-
`
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
4. **Execute the command template** with full context
|
|
228
|
-
|
|
229
|
-
5. **Return results**
|
|
230
|
-
|
|
231
|
-
### Agentic Decision Making
|
|
232
|
-
|
|
233
|
-
YOU decide:
|
|
234
|
-
- Whether to run orchestration (based on command type)
|
|
235
|
-
- Which domains the task involves (frontend, backend, database, etc.)
|
|
236
|
-
- Whether to fragment the task into subtasks
|
|
237
|
-
- Which specialist agents to delegate to
|
|
238
|
-
|
|
239
|
-
ALWAYS:
|
|
240
|
-
- Use specialist agents when they exist (they're already project-specific)
|
|
241
|
-
- Delegate subtasks to the appropriate specialist via Task tool
|
|
242
|
-
- Let specialists handle their domain (they have the project patterns)
|
|
243
|
-
- Generate and store summaries when subtasks complete
|
|
244
|
-
|
|
245
|
-
ONLY use generalist when:
|
|
246
|
-
- No specialist agent exists for that domain
|
|
247
|
-
- Task is completely outside project scope
|
|
248
|
-
- Extreme edge case
|
|
249
|
-
|
|
250
|
-
### Subtask Management
|
|
251
|
-
|
|
252
|
-
When fragmenting tasks:
|
|
253
|
-
1. Store subtasks in state.json under currentTask.subtasks
|
|
254
|
-
2. Track progress: currentSubtaskIndex, subtaskProgress
|
|
255
|
-
3. Each completed subtask generates a summary
|
|
256
|
-
4. Pass summary to next agent for context handoff
|
|
257
|
-
`
|
|
258
|
-
|
|
259
|
-
return {
|
|
260
|
-
prompt,
|
|
261
|
-
context,
|
|
262
|
-
requiresOrchestration,
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// =============================================================================
|
|
268
|
-
// Singleton Export
|
|
269
|
-
// =============================================================================
|
|
270
|
-
|
|
271
|
-
export const templateExecutor = new TemplateExecutor()
|
|
272
|
-
export default templateExecutor
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Template Loader
|
|
3
|
-
* Loads and parses command templates with frontmatter.
|
|
4
|
-
*
|
|
5
|
-
* @module agentic/template-loader
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import fs from 'node:fs/promises'
|
|
9
|
-
import path from 'node:path'
|
|
10
|
-
import { TemplateError } from '../errors'
|
|
11
|
-
import type { Frontmatter, ParsedTemplate } from '../types'
|
|
12
|
-
|
|
13
|
-
// ============ Module State (LRU Cache) ============
|
|
14
|
-
|
|
15
|
-
const TEMPLATES_DIR = path.join(__dirname, '..', '..', 'templates', 'commands')
|
|
16
|
-
const MAX_CACHE_SIZE = 50
|
|
17
|
-
|
|
18
|
-
const cache = new Map<string, ParsedTemplate>()
|
|
19
|
-
const cacheOrder: string[] = []
|
|
20
|
-
|
|
21
|
-
// ============ Cache Helpers ============
|
|
22
|
-
|
|
23
|
-
function updateLruOrder(key: string): void {
|
|
24
|
-
const index = cacheOrder.indexOf(key)
|
|
25
|
-
if (index > -1) cacheOrder.splice(index, 1)
|
|
26
|
-
cacheOrder.push(key)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function evictLru(): void {
|
|
30
|
-
while (cache.size >= MAX_CACHE_SIZE && cacheOrder.length > 0) {
|
|
31
|
-
const oldest = cacheOrder.shift()
|
|
32
|
-
if (oldest) cache.delete(oldest)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// ============ Parsing Functions ============
|
|
37
|
-
|
|
38
|
-
export function parseFrontmatter(content: string): ParsedTemplate {
|
|
39
|
-
const frontmatterRegex = /^---\n([\s\S]+?)\n---\n([\s\S]*)$/
|
|
40
|
-
const match = content.match(frontmatterRegex)
|
|
41
|
-
|
|
42
|
-
if (!match) {
|
|
43
|
-
return { frontmatter: {}, content: content.trim() }
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const [, frontmatterText, mainContent] = match
|
|
47
|
-
const frontmatter: Frontmatter = {}
|
|
48
|
-
|
|
49
|
-
frontmatterText.split('\n').forEach((line) => {
|
|
50
|
-
const [key, ...valueParts] = line.split(':')
|
|
51
|
-
if (key && valueParts.length > 0) {
|
|
52
|
-
const value = valueParts.join(':').trim()
|
|
53
|
-
|
|
54
|
-
// Parse arrays
|
|
55
|
-
if (value.startsWith('[') && value.endsWith(']')) {
|
|
56
|
-
frontmatter[key.trim()] = value
|
|
57
|
-
.slice(1, -1)
|
|
58
|
-
.split(',')
|
|
59
|
-
.map((v) => v.trim())
|
|
60
|
-
} else {
|
|
61
|
-
// Remove quotes if present
|
|
62
|
-
frontmatter[key.trim()] = value.replace(/^["']|["']$/g, '')
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
return { frontmatter, content: mainContent.trim() }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// ============ Main Functions ============
|
|
71
|
-
|
|
72
|
-
export async function load(commandName: string): Promise<ParsedTemplate> {
|
|
73
|
-
// Check cache first
|
|
74
|
-
if (cache.has(commandName)) {
|
|
75
|
-
updateLruOrder(commandName)
|
|
76
|
-
return cache.get(commandName)!
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const templatePath = path.join(TEMPLATES_DIR, `${commandName}.md`)
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
const rawContent = await fs.readFile(templatePath, 'utf-8')
|
|
83
|
-
const parsed = parseFrontmatter(rawContent)
|
|
84
|
-
|
|
85
|
-
// Evict LRU if needed before adding
|
|
86
|
-
evictLru()
|
|
87
|
-
|
|
88
|
-
// Cache result
|
|
89
|
-
cache.set(commandName, parsed)
|
|
90
|
-
cacheOrder.push(commandName)
|
|
91
|
-
|
|
92
|
-
return parsed
|
|
93
|
-
} catch (_error) {
|
|
94
|
-
throw TemplateError.notFound(commandName)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export async function getAllowedTools(commandName: string): Promise<string[]> {
|
|
99
|
-
const template = await load(commandName)
|
|
100
|
-
return template.frontmatter['allowed-tools'] || []
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function clearCache(): void {
|
|
104
|
-
cache.clear()
|
|
105
|
-
cacheOrder.length = 0
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const templateLoader = { load, parseFrontmatter, getAllowedTools, clearCache }
|
|
109
|
-
export default templateLoader
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Token Budget Coordinator
|
|
3
|
-
*
|
|
4
|
-
* Centrally manages the global token budget across all context-loading components.
|
|
5
|
-
* Ensures the combined prompt stays within the model's context window
|
|
6
|
-
* and reserves space for the output.
|
|
7
|
-
*
|
|
8
|
-
* Budget formula: inputBudget = modelContextWindow * 0.65
|
|
9
|
-
* Priority: state (P1) > injection context (P2) > file content (P3)
|
|
10
|
-
*
|
|
11
|
-
* @see PRJ-266
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
// =============================================================================
|
|
15
|
-
// Model Context Windows
|
|
16
|
-
// =============================================================================
|
|
17
|
-
|
|
18
|
-
/** Context window sizes by model identifier (in tokens) */
|
|
19
|
-
export const MODEL_CONTEXT_WINDOWS: Record<string, number> = {
|
|
20
|
-
// Claude models (short names from model.ts)
|
|
21
|
-
opus: 200_000,
|
|
22
|
-
sonnet: 200_000,
|
|
23
|
-
haiku: 200_000,
|
|
24
|
-
// Gemini models
|
|
25
|
-
'2.5-pro': 1_000_000,
|
|
26
|
-
'2.5-flash': 1_000_000,
|
|
27
|
-
'2.0-flash': 1_000_000,
|
|
28
|
-
// Full model IDs (for direct API usage)
|
|
29
|
-
'claude-opus-4.5': 200_000,
|
|
30
|
-
'claude-sonnet-4.5': 200_000,
|
|
31
|
-
'claude-haiku-4.5': 200_000,
|
|
32
|
-
'claude-opus-4-6': 200_000,
|
|
33
|
-
// Default fallback
|
|
34
|
-
default: 200_000,
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Ratio of context window reserved for input (rest for output) */
|
|
38
|
-
export const INPUT_RATIO = 0.65
|
|
39
|
-
|
|
40
|
-
// =============================================================================
|
|
41
|
-
// Budget Categories
|
|
42
|
-
// =============================================================================
|
|
43
|
-
|
|
44
|
-
/** Budget category identifiers ordered by priority */
|
|
45
|
-
export type BudgetCategory = 'state' | 'injection' | 'files'
|
|
46
|
-
|
|
47
|
-
/** Budget allocation result for each category */
|
|
48
|
-
export interface BudgetAllocation {
|
|
49
|
-
state: number
|
|
50
|
-
injection: number
|
|
51
|
-
files: number
|
|
52
|
-
inputBudget: number
|
|
53
|
-
outputReserve: number
|
|
54
|
-
contextWindow: number
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** Usage tracking per category */
|
|
58
|
-
export interface BudgetUsage {
|
|
59
|
-
category: BudgetCategory
|
|
60
|
-
allocated: number
|
|
61
|
-
used: number
|
|
62
|
-
remaining: number
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// =============================================================================
|
|
66
|
-
// Default Allocation Ratios (within input budget)
|
|
67
|
-
// =============================================================================
|
|
68
|
-
|
|
69
|
-
interface AllocationConfig {
|
|
70
|
-
ratio: number
|
|
71
|
-
minimum: number
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const ALLOCATION_CONFIG: Record<BudgetCategory, AllocationConfig> = {
|
|
75
|
-
/** P1: State — current task, queue, patterns (highest priority) */
|
|
76
|
-
state: { ratio: 0.02, minimum: 1_500 },
|
|
77
|
-
/** P2: Injection — agents, skills, modules, checklists */
|
|
78
|
-
injection: { ratio: 0.08, minimum: 8_000 },
|
|
79
|
-
/** P3: Files — codebase file content (lowest priority, gets remainder) */
|
|
80
|
-
files: { ratio: 0.9, minimum: 20_000 },
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** Priority order for budget distribution */
|
|
84
|
-
const PRIORITY_ORDER: BudgetCategory[] = ['state', 'injection', 'files']
|
|
85
|
-
|
|
86
|
-
// =============================================================================
|
|
87
|
-
// TokenBudgetCoordinator
|
|
88
|
-
// =============================================================================
|
|
89
|
-
|
|
90
|
-
export class TokenBudgetCoordinator {
|
|
91
|
-
private readonly _contextWindow: number
|
|
92
|
-
private readonly _inputBudget: number
|
|
93
|
-
private readonly _outputReserve: number
|
|
94
|
-
private readonly _allocations: Map<BudgetCategory, number> = new Map()
|
|
95
|
-
private readonly _used: Map<BudgetCategory, number> = new Map()
|
|
96
|
-
|
|
97
|
-
constructor(model?: string) {
|
|
98
|
-
this._contextWindow = getContextWindow(model)
|
|
99
|
-
this._inputBudget = Math.floor(this._contextWindow * INPUT_RATIO)
|
|
100
|
-
this._outputReserve = this._contextWindow - this._inputBudget
|
|
101
|
-
this.distributeBudget()
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/** Distribute input budget across categories by priority */
|
|
105
|
-
private distributeBudget(): void {
|
|
106
|
-
let remaining = this._inputBudget
|
|
107
|
-
|
|
108
|
-
for (const category of PRIORITY_ORDER) {
|
|
109
|
-
const config = ALLOCATION_CONFIG[category]
|
|
110
|
-
|
|
111
|
-
if (category === 'files') {
|
|
112
|
-
// Lowest priority gets whatever remains
|
|
113
|
-
this._allocations.set(category, Math.max(remaining, 0))
|
|
114
|
-
} else {
|
|
115
|
-
const allocation = Math.max(config.minimum, Math.floor(this._inputBudget * config.ratio))
|
|
116
|
-
const granted = Math.min(allocation, remaining)
|
|
117
|
-
this._allocations.set(category, granted)
|
|
118
|
-
remaining -= granted
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
this._used.set(category, 0)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** Get the full budget allocation */
|
|
126
|
-
getAllocation(): BudgetAllocation {
|
|
127
|
-
return {
|
|
128
|
-
state: this._allocations.get('state') ?? 0,
|
|
129
|
-
injection: this._allocations.get('injection') ?? 0,
|
|
130
|
-
files: this._allocations.get('files') ?? 0,
|
|
131
|
-
inputBudget: this._inputBudget,
|
|
132
|
-
outputReserve: this._outputReserve,
|
|
133
|
-
contextWindow: this._contextWindow,
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Request tokens from a category.
|
|
139
|
-
* Returns actual tokens granted (may be less than requested if budget is exhausted).
|
|
140
|
-
*/
|
|
141
|
-
request(category: BudgetCategory, requestedTokens: number): number {
|
|
142
|
-
const allocated = this._allocations.get(category) ?? 0
|
|
143
|
-
const currentUsed = this._used.get(category) ?? 0
|
|
144
|
-
const available = Math.max(0, allocated - currentUsed)
|
|
145
|
-
const granted = Math.min(requestedTokens, available)
|
|
146
|
-
this._used.set(category, currentUsed + granted)
|
|
147
|
-
return granted
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/** Record token usage for a category */
|
|
151
|
-
record(category: BudgetCategory, tokensUsed: number): void {
|
|
152
|
-
const current = this._used.get(category) ?? 0
|
|
153
|
-
this._used.set(category, current + tokensUsed)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/** Get usage details for a category */
|
|
157
|
-
getUsage(category: BudgetCategory): BudgetUsage {
|
|
158
|
-
const allocated = this._allocations.get(category) ?? 0
|
|
159
|
-
const used = this._used.get(category) ?? 0
|
|
160
|
-
return {
|
|
161
|
-
category,
|
|
162
|
-
allocated,
|
|
163
|
-
used,
|
|
164
|
-
remaining: Math.max(0, allocated - used),
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/** Get allocation for a specific category */
|
|
169
|
-
getAllocationFor(category: BudgetCategory): number {
|
|
170
|
-
return this._allocations.get(category) ?? 0
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/** Get total remaining input budget across all categories */
|
|
174
|
-
get totalRemaining(): number {
|
|
175
|
-
let totalUsed = 0
|
|
176
|
-
for (const v of this._used.values()) {
|
|
177
|
-
totalUsed += v
|
|
178
|
-
}
|
|
179
|
-
return Math.max(0, this._inputBudget - totalUsed)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/** Check if total usage exceeds input budget */
|
|
183
|
-
get isOverBudget(): boolean {
|
|
184
|
-
let totalUsed = 0
|
|
185
|
-
for (const v of this._used.values()) {
|
|
186
|
-
totalUsed += v
|
|
187
|
-
}
|
|
188
|
-
return totalUsed > this._inputBudget
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/** Context window size */
|
|
192
|
-
get contextWindow(): number {
|
|
193
|
-
return this._contextWindow
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/** Total input budget */
|
|
197
|
-
get inputBudget(): number {
|
|
198
|
-
return this._inputBudget
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/** Output token reserve */
|
|
202
|
-
get outputReserve(): number {
|
|
203
|
-
return this._outputReserve
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// =============================================================================
|
|
208
|
-
// Helpers
|
|
209
|
-
// =============================================================================
|
|
210
|
-
|
|
211
|
-
/** Get context window size for a model identifier */
|
|
212
|
-
export function getContextWindow(model?: string): number {
|
|
213
|
-
if (!model) return MODEL_CONTEXT_WINDOWS.default
|
|
214
|
-
return MODEL_CONTEXT_WINDOWS[model] ?? MODEL_CONTEXT_WINDOWS.default
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/** Calculate input budget for a model */
|
|
218
|
-
export function calculateInputBudget(model?: string): number {
|
|
219
|
-
return Math.floor(getContextWindow(model) * INPUT_RATIO)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/** Calculate output reserve for a model */
|
|
223
|
-
export function calculateOutputReserve(model?: string): number {
|
|
224
|
-
const contextWindow = getContextWindow(model)
|
|
225
|
-
return contextWindow - Math.floor(contextWindow * INPUT_RATIO)
|
|
226
|
-
}
|