specforge-mcp 0.11.1 → 0.12.1
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/dist/engine/context-budget/checkpoint.d.ts +8 -0
- package/dist/engine/context-budget/checkpoint.d.ts.map +1 -0
- package/dist/engine/context-budget/checkpoint.js +79 -0
- package/dist/engine/context-budget/checkpoint.js.map +1 -0
- package/dist/engine/context-budget/compressor.d.ts +20 -0
- package/dist/engine/context-budget/compressor.d.ts.map +1 -0
- package/dist/engine/context-budget/compressor.js +122 -0
- package/dist/engine/context-budget/compressor.js.map +1 -0
- package/dist/engine/context-budget/index.d.ts +5 -0
- package/dist/engine/context-budget/index.d.ts.map +1 -0
- package/dist/engine/context-budget/index.js +6 -0
- package/dist/engine/context-budget/index.js.map +1 -0
- package/dist/engine/context-budget/optimizer.d.ts +8 -0
- package/dist/engine/context-budget/optimizer.d.ts.map +1 -0
- package/dist/engine/context-budget/optimizer.js +87 -0
- package/dist/engine/context-budget/optimizer.js.map +1 -0
- package/dist/engine/context-budget/tracker.d.ts +19 -0
- package/dist/engine/context-budget/tracker.d.ts.map +1 -0
- package/dist/engine/context-budget/tracker.js +113 -0
- package/dist/engine/context-budget/tracker.js.map +1 -0
- package/dist/index.js +0 -0
- package/dist/storage/checkpoint-store.d.ts +12 -0
- package/dist/storage/checkpoint-store.d.ts.map +1 -0
- package/dist/storage/checkpoint-store.js +85 -0
- package/dist/storage/checkpoint-store.js.map +1 -0
- package/dist/tools/context-budget.d.ts +3 -0
- package/dist/tools/context-budget.d.ts.map +1 -0
- package/dist/tools/context-budget.js +131 -0
- package/dist/tools/context-budget.js.map +1 -0
- package/dist/tools/register-platform-tools/lifecycle-infra-tools.d.ts.map +1 -1
- package/dist/tools/register-platform-tools/lifecycle-infra-tools.js +36 -1
- package/dist/tools/register-platform-tools/lifecycle-infra-tools.js.map +1 -1
- package/dist/tools/schemas/index.d.ts +1 -1
- package/dist/tools/schemas/index.d.ts.map +1 -1
- package/dist/tools/schemas/index.js +1 -1
- package/dist/tools/schemas/index.js.map +1 -1
- package/dist/tools/schemas/infra.d.ts +8 -0
- package/dist/tools/schemas/infra.d.ts.map +1 -1
- package/dist/tools/schemas/infra.js +3 -0
- package/dist/tools/schemas/infra.js.map +1 -1
- package/dist/types/context-budget.d.ts +90 -0
- package/dist/types/context-budget.d.ts.map +1 -0
- package/dist/types/context-budget.js +3 -0
- package/dist/types/context-budget.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +1 -1
- package/src/i18n/messages/en.json +6 -0
- package/src/i18n/messages/es.json +6 -0
- package/src/i18n/messages/pt.json +6 -0
- package/dist/engine/agent-generator.test.d.ts +0 -2
- package/dist/engine/agent-generator.test.d.ts.map +0 -1
- package/dist/engine/agent-generator.test.js +0 -556
- package/dist/engine/agent-generator.test.js.map +0 -1
- package/dist/engine/analyzer.test.d.ts +0 -2
- package/dist/engine/analyzer.test.d.ts.map +0 -1
- package/dist/engine/analyzer.test.js +0 -1461
- package/dist/engine/analyzer.test.js.map +0 -1
- package/dist/engine/auditor.test.d.ts +0 -2
- package/dist/engine/auditor.test.d.ts.map +0 -1
- package/dist/engine/auditor.test.js +0 -2075
- package/dist/engine/auditor.test.js.map +0 -1
- package/dist/engine/doc-generator.test.d.ts +0 -2
- package/dist/engine/doc-generator.test.d.ts.map +0 -1
- package/dist/engine/doc-generator.test.js +0 -961
- package/dist/engine/doc-generator.test.js.map +0 -1
- package/dist/engine/estimator.test.d.ts +0 -2
- package/dist/engine/estimator.test.d.ts.map +0 -1
- package/dist/engine/estimator.test.js +0 -334
- package/dist/engine/estimator.test.js.map +0 -1
- package/dist/engine/skill-generator.test.d.ts +0 -2
- package/dist/engine/skill-generator.test.d.ts.map +0 -1
- package/dist/engine/skill-generator.test.js +0 -742
- package/dist/engine/skill-generator.test.js.map +0 -1
- package/dist/engine/validator.test.d.ts +0 -2
- package/dist/engine/validator.test.d.ts.map +0 -1
- package/dist/engine/validator.test.js +0 -2371
- package/dist/engine/validator.test.js.map +0 -1
- package/dist/engine/web-fetcher.test.d.ts +0 -2
- package/dist/engine/web-fetcher.test.d.ts.map +0 -1
- package/dist/engine/web-fetcher.test.js +0 -360
- package/dist/engine/web-fetcher.test.js.map +0 -1
- package/dist/i18n/index.test.d.ts +0 -2
- package/dist/i18n/index.test.d.ts.map +0 -1
- package/dist/i18n/index.test.js +0 -375
- package/dist/i18n/index.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -124
- package/dist/index.test.js.map +0 -1
- package/dist/resources/patterns.test.d.ts +0 -2
- package/dist/resources/patterns.test.d.ts.map +0 -1
- package/dist/resources/patterns.test.js +0 -142
- package/dist/resources/patterns.test.js.map +0 -1
- package/dist/resources/process.test.d.ts +0 -2
- package/dist/resources/process.test.d.ts.map +0 -1
- package/dist/resources/process.test.js +0 -48
- package/dist/resources/process.test.js.map +0 -1
- package/dist/resources/registry.test.d.ts +0 -2
- package/dist/resources/registry.test.d.ts.map +0 -1
- package/dist/resources/registry.test.js +0 -138
- package/dist/resources/registry.test.js.map +0 -1
- package/dist/resources/specs.test.d.ts +0 -2
- package/dist/resources/specs.test.d.ts.map +0 -1
- package/dist/resources/specs.test.js +0 -130
- package/dist/resources/specs.test.js.map +0 -1
- package/dist/resources/templates.test.d.ts +0 -2
- package/dist/resources/templates.test.d.ts.map +0 -1
- package/dist/resources/templates.test.js +0 -119
- package/dist/resources/templates.test.js.map +0 -1
- package/dist/smoke.test.d.ts +0 -2
- package/dist/smoke.test.d.ts.map +0 -1
- package/dist/smoke.test.js +0 -229
- package/dist/smoke.test.js.map +0 -1
- package/dist/storage/base-store.test.d.ts +0 -2
- package/dist/storage/base-store.test.d.ts.map +0 -1
- package/dist/storage/base-store.test.js +0 -180
- package/dist/storage/base-store.test.js.map +0 -1
- package/dist/storage/global-store.test.d.ts +0 -2
- package/dist/storage/global-store.test.d.ts.map +0 -1
- package/dist/storage/global-store.test.js +0 -327
- package/dist/storage/global-store.test.js.map +0 -1
- package/dist/storage/index.test.d.ts +0 -2
- package/dist/storage/index.test.d.ts.map +0 -1
- package/dist/storage/index.test.js +0 -56
- package/dist/storage/index.test.js.map +0 -1
- package/dist/storage/knowledge-store.test.d.ts +0 -2
- package/dist/storage/knowledge-store.test.d.ts.map +0 -1
- package/dist/storage/knowledge-store.test.js +0 -368
- package/dist/storage/knowledge-store.test.js.map +0 -1
- package/dist/storage/metrics-store.test.d.ts +0 -2
- package/dist/storage/metrics-store.test.d.ts.map +0 -1
- package/dist/storage/metrics-store.test.js +0 -212
- package/dist/storage/metrics-store.test.js.map +0 -1
- package/dist/storage/pattern-store.test.d.ts +0 -2
- package/dist/storage/pattern-store.test.d.ts.map +0 -1
- package/dist/storage/pattern-store.test.js +0 -224
- package/dist/storage/pattern-store.test.js.map +0 -1
- package/dist/storage/spec-store.test.d.ts +0 -2
- package/dist/storage/spec-store.test.d.ts.map +0 -1
- package/dist/storage/spec-store.test.js +0 -227
- package/dist/storage/spec-store.test.js.map +0 -1
- package/dist/tools/audit.test.d.ts +0 -2
- package/dist/tools/audit.test.d.ts.map +0 -1
- package/dist/tools/audit.test.js +0 -169
- package/dist/tools/audit.test.js.map +0 -1
- package/dist/tools/challenge-spec.test.d.ts +0 -2
- package/dist/tools/challenge-spec.test.d.ts.map +0 -1
- package/dist/tools/challenge-spec.test.js +0 -782
- package/dist/tools/challenge-spec.test.js.map +0 -1
- package/dist/tools/check-versions.test.d.ts +0 -2
- package/dist/tools/check-versions.test.d.ts.map +0 -1
- package/dist/tools/check-versions.test.js +0 -214
- package/dist/tools/check-versions.test.js.map +0 -1
- package/dist/tools/clarify-requirements.test.d.ts +0 -2
- package/dist/tools/clarify-requirements.test.d.ts.map +0 -1
- package/dist/tools/clarify-requirements.test.js +0 -161
- package/dist/tools/clarify-requirements.test.js.map +0 -1
- package/dist/tools/consult-docs.test.d.ts +0 -2
- package/dist/tools/consult-docs.test.d.ts.map +0 -1
- package/dist/tools/consult-docs.test.js +0 -140
- package/dist/tools/consult-docs.test.js.map +0 -1
- package/dist/tools/create-spec.test.d.ts +0 -2
- package/dist/tools/create-spec.test.d.ts.map +0 -1
- package/dist/tools/create-spec.test.js +0 -233
- package/dist/tools/create-spec.test.js.map +0 -1
- package/dist/tools/define-ui-contract.test.d.ts +0 -2
- package/dist/tools/define-ui-contract.test.d.ts.map +0 -1
- package/dist/tools/define-ui-contract.test.js +0 -479
- package/dist/tools/define-ui-contract.test.js.map +0 -1
- package/dist/tools/design-schema.test.d.ts +0 -2
- package/dist/tools/design-schema.test.d.ts.map +0 -1
- package/dist/tools/design-schema.test.js +0 -301
- package/dist/tools/design-schema.test.js.map +0 -1
- package/dist/tools/detect-agent.test.d.ts +0 -2
- package/dist/tools/detect-agent.test.d.ts.map +0 -1
- package/dist/tools/detect-agent.test.js +0 -133
- package/dist/tools/detect-agent.test.js.map +0 -1
- package/dist/tools/detect-drift.test.d.ts +0 -2
- package/dist/tools/detect-drift.test.d.ts.map +0 -1
- package/dist/tools/detect-drift.test.js +0 -312
- package/dist/tools/detect-drift.test.js.map +0 -1
- package/dist/tools/discover-mcps.test.d.ts +0 -2
- package/dist/tools/discover-mcps.test.d.ts.map +0 -1
- package/dist/tools/discover-mcps.test.js +0 -345
- package/dist/tools/discover-mcps.test.js.map +0 -1
- package/dist/tools/estimate.test.d.ts +0 -2
- package/dist/tools/estimate.test.d.ts.map +0 -1
- package/dist/tools/estimate.test.js +0 -137
- package/dist/tools/estimate.test.js.map +0 -1
- package/dist/tools/generate-adr.test.d.ts +0 -2
- package/dist/tools/generate-adr.test.d.ts.map +0 -1
- package/dist/tools/generate-adr.test.js +0 -206
- package/dist/tools/generate-adr.test.js.map +0 -1
- package/dist/tools/generate-checklist.test.d.ts +0 -2
- package/dist/tools/generate-checklist.test.d.ts.map +0 -1
- package/dist/tools/generate-checklist.test.js +0 -201
- package/dist/tools/generate-checklist.test.js.map +0 -1
- package/dist/tools/generate-docs.test.d.ts +0 -2
- package/dist/tools/generate-docs.test.d.ts.map +0 -1
- package/dist/tools/generate-docs.test.js +0 -183
- package/dist/tools/generate-docs.test.js.map +0 -1
- package/dist/tools/generate-execution-plan.test.d.ts +0 -2
- package/dist/tools/generate-execution-plan.test.d.ts.map +0 -1
- package/dist/tools/generate-execution-plan.test.js +0 -643
- package/dist/tools/generate-execution-plan.test.js.map +0 -1
- package/dist/tools/generate-rules.test.d.ts +0 -2
- package/dist/tools/generate-rules.test.d.ts.map +0 -1
- package/dist/tools/generate-rules.test.js +0 -148
- package/dist/tools/generate-rules.test.js.map +0 -1
- package/dist/tools/generate-skill.test.d.ts +0 -2
- package/dist/tools/generate-skill.test.d.ts.map +0 -1
- package/dist/tools/generate-skill.test.js +0 -138
- package/dist/tools/generate-skill.test.js.map +0 -1
- package/dist/tools/generate-sub-agent.test.d.ts +0 -2
- package/dist/tools/generate-sub-agent.test.d.ts.map +0 -1
- package/dist/tools/generate-sub-agent.test.js +0 -162
- package/dist/tools/generate-sub-agent.test.js.map +0 -1
- package/dist/tools/generate-tests.test.d.ts +0 -2
- package/dist/tools/generate-tests.test.d.ts.map +0 -1
- package/dist/tools/generate-tests.test.js +0 -222
- package/dist/tools/generate-tests.test.js.map +0 -1
- package/dist/tools/init-constitution.test.d.ts +0 -2
- package/dist/tools/init-constitution.test.d.ts.map +0 -1
- package/dist/tools/init-constitution.test.js +0 -398
- package/dist/tools/init-constitution.test.js.map +0 -1
- package/dist/tools/init-project.test.d.ts +0 -2
- package/dist/tools/init-project.test.d.ts.map +0 -1
- package/dist/tools/init-project.test.js +0 -158
- package/dist/tools/init-project.test.js.map +0 -1
- package/dist/tools/integrate-pm.test.d.ts +0 -2
- package/dist/tools/integrate-pm.test.d.ts.map +0 -1
- package/dist/tools/integrate-pm.test.js +0 -558
- package/dist/tools/integrate-pm.test.js.map +0 -1
- package/dist/tools/learn.test.d.ts +0 -2
- package/dist/tools/learn.test.d.ts.map +0 -1
- package/dist/tools/learn.test.js +0 -123
- package/dist/tools/learn.test.js.map +0 -1
- package/dist/tools/list-specs.test.d.ts +0 -2
- package/dist/tools/list-specs.test.d.ts.map +0 -1
- package/dist/tools/list-specs.test.js +0 -110
- package/dist/tools/list-specs.test.js.map +0 -1
- package/dist/tools/manage-context.test.d.ts +0 -2
- package/dist/tools/manage-context.test.d.ts.map +0 -1
- package/dist/tools/manage-context.test.js +0 -359
- package/dist/tools/manage-context.test.js.map +0 -1
- package/dist/tools/manage-git.test.d.ts +0 -2
- package/dist/tools/manage-git.test.d.ts.map +0 -1
- package/dist/tools/manage-git.test.js +0 -882
- package/dist/tools/manage-git.test.js.map +0 -1
- package/dist/tools/orchestrate.test.d.ts +0 -2
- package/dist/tools/orchestrate.test.d.ts.map +0 -1
- package/dist/tools/orchestrate.test.js +0 -1117
- package/dist/tools/orchestrate.test.js.map +0 -1
- package/dist/tools/reconcile-spec.test.d.ts +0 -2
- package/dist/tools/reconcile-spec.test.d.ts.map +0 -1
- package/dist/tools/reconcile-spec.test.js +0 -259
- package/dist/tools/reconcile-spec.test.js.map +0 -1
- package/dist/tools/register-platform-tools.test.d.ts +0 -2
- package/dist/tools/register-platform-tools.test.d.ts.map +0 -1
- package/dist/tools/register-platform-tools.test.js +0 -404
- package/dist/tools/register-platform-tools.test.js.map +0 -1
- package/dist/tools/register-spec-tools.test.d.ts +0 -2
- package/dist/tools/register-spec-tools.test.d.ts.map +0 -1
- package/dist/tools/register-spec-tools.test.js +0 -407
- package/dist/tools/register-spec-tools.test.js.map +0 -1
- package/dist/tools/reverse-engineer.test.d.ts +0 -2
- package/dist/tools/reverse-engineer.test.d.ts.map +0 -1
- package/dist/tools/reverse-engineer.test.js +0 -206
- package/dist/tools/reverse-engineer.test.js.map +0 -1
- package/dist/tools/schemas.d.ts +0 -20
- package/dist/tools/schemas.d.ts.map +0 -1
- package/dist/tools/schemas.js +0 -133
- package/dist/tools/schemas.js.map +0 -1
- package/dist/tools/schemas.test.d.ts +0 -2
- package/dist/tools/schemas.test.d.ts.map +0 -1
- package/dist/tools/schemas.test.js +0 -245
- package/dist/tools/schemas.test.js.map +0 -1
- package/dist/tools/set-locale.test.d.ts +0 -2
- package/dist/tools/set-locale.test.d.ts.map +0 -1
- package/dist/tools/set-locale.test.js +0 -74
- package/dist/tools/set-locale.test.js.map +0 -1
- package/dist/tools/suggest-mcps.test.d.ts +0 -2
- package/dist/tools/suggest-mcps.test.d.ts.map +0 -1
- package/dist/tools/suggest-mcps.test.js +0 -198
- package/dist/tools/suggest-mcps.test.js.map +0 -1
- package/dist/tools/suggest-stack.test.d.ts +0 -2
- package/dist/tools/suggest-stack.test.d.ts.map +0 -1
- package/dist/tools/suggest-stack.test.js +0 -181
- package/dist/tools/suggest-stack.test.js.map +0 -1
- package/dist/tools/suggest-tooling.test.d.ts +0 -2
- package/dist/tools/suggest-tooling.test.d.ts.map +0 -1
- package/dist/tools/suggest-tooling.test.js +0 -213
- package/dist/tools/suggest-tooling.test.js.map +0 -1
- package/dist/tools/summarize-spec.test.d.ts +0 -2
- package/dist/tools/summarize-spec.test.d.ts.map +0 -1
- package/dist/tools/summarize-spec.test.js +0 -180
- package/dist/tools/summarize-spec.test.js.map +0 -1
- package/dist/tools/update-status.test.d.ts +0 -2
- package/dist/tools/update-status.test.d.ts.map +0 -1
- package/dist/tools/update-status.test.js +0 -142
- package/dist/tools/update-status.test.js.map +0 -1
- package/dist/tools/validate.test.d.ts +0 -2
- package/dist/tools/validate.test.d.ts.map +0 -1
- package/dist/tools/validate.test.js +0 -137
- package/dist/tools/validate.test.js.map +0 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContextBudgetStatus, SessionCheckpoint } from '../../types/index.js';
|
|
2
|
+
/** Build a session checkpoint from available data. */
|
|
3
|
+
export declare function generateCheckpoint(projectId: string, contextUsage: ContextBudgetStatus, options?: Partial<Omit<SessionCheckpoint, 'timestamp' | 'projectId' | 'contextUsage'>>): SessionCheckpoint;
|
|
4
|
+
/** Format a checkpoint as human-readable Markdown. */
|
|
5
|
+
export declare function formatCheckpoint(cp: SessionCheckpoint): string;
|
|
6
|
+
/** Extract a one-line summary from a checkpoint. */
|
|
7
|
+
export declare function parseCheckpointSummary(cp: SessionCheckpoint): string;
|
|
8
|
+
//# sourceMappingURL=checkpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../../src/engine/context-budget/checkpoint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EAGlB,MAAM,sBAAsB,CAAC;AAa9B,sDAAsD;AACtD,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,mBAAmB,EACjC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,WAAW,GAAG,WAAW,GAAG,cAAc,CAAC,CAAC,GACrF,iBAAiB,CAcnB;AAED,sDAAsD;AACtD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM,CA0D9D;AAED,oDAAoD;AACpD,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM,CAYpE"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Defaults
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
const EMPTY_GIT = { staged: [], unstaged: [], branch: 'unknown' };
|
|
5
|
+
const EMPTY_PIPELINE = { typecheck: false, lint: false, tests: false };
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Public API
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
/** Build a session checkpoint from available data. */
|
|
10
|
+
export function generateCheckpoint(projectId, contextUsage, options) {
|
|
11
|
+
return {
|
|
12
|
+
timestamp: new Date().toISOString(),
|
|
13
|
+
projectId,
|
|
14
|
+
summary: options?.summary ?? buildAutoSummary(contextUsage),
|
|
15
|
+
decisions: options?.decisions ?? [],
|
|
16
|
+
filesModified: options?.filesModified ?? [],
|
|
17
|
+
filesRead: options?.filesRead ?? [],
|
|
18
|
+
specsInProgress: options?.specsInProgress ?? [],
|
|
19
|
+
pendingWork: options?.pendingWork ?? [],
|
|
20
|
+
gitStatus: options?.gitStatus ?? EMPTY_GIT,
|
|
21
|
+
pipelineStatus: options?.pipelineStatus ?? EMPTY_PIPELINE,
|
|
22
|
+
contextUsage,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/** Format a checkpoint as human-readable Markdown. */
|
|
26
|
+
export function formatCheckpoint(cp) {
|
|
27
|
+
const lines = [
|
|
28
|
+
`# Session Checkpoint`,
|
|
29
|
+
'',
|
|
30
|
+
`**Project:** ${cp.projectId}`,
|
|
31
|
+
`**Timestamp:** ${cp.timestamp}`,
|
|
32
|
+
`**Context usage:** ${String(cp.contextUsage.percentUsed)}% (${cp.contextUsage.alertLevel})`,
|
|
33
|
+
'',
|
|
34
|
+
`## Summary`,
|
|
35
|
+
cp.summary,
|
|
36
|
+
'',
|
|
37
|
+
];
|
|
38
|
+
if (cp.decisions.length > 0) {
|
|
39
|
+
lines.push('## Decisions', ...cp.decisions.map((d) => `- ${d}`), '');
|
|
40
|
+
}
|
|
41
|
+
if (cp.filesModified.length > 0) {
|
|
42
|
+
lines.push('## Files Modified', ...cp.filesModified.map((f) => `- ${f}`), '');
|
|
43
|
+
}
|
|
44
|
+
if (cp.filesRead.length > 0) {
|
|
45
|
+
lines.push('## Files Read', ...cp.filesRead.map((f) => `- ${f}`), '');
|
|
46
|
+
}
|
|
47
|
+
if (cp.specsInProgress.length > 0) {
|
|
48
|
+
lines.push('## Specs In Progress', ...cp.specsInProgress.map((s) => `- ${s}`), '');
|
|
49
|
+
}
|
|
50
|
+
if (cp.pendingWork.length > 0) {
|
|
51
|
+
lines.push('## Pending Work', ...cp.pendingWork.map((w) => `- ${w}`), '');
|
|
52
|
+
}
|
|
53
|
+
lines.push('## Git Status', `Branch: ${cp.gitStatus.branch}`, `Staged: ${cp.gitStatus.staged.length > 0 ? cp.gitStatus.staged.join(', ') : 'none'}`, `Unstaged: ${cp.gitStatus.unstaged.length > 0 ? cp.gitStatus.unstaged.join(', ') : 'none'}`, '', '## Pipeline', `- Typecheck: ${cp.pipelineStatus.typecheck ? 'PASS' : 'PENDING'}`, `- Lint: ${cp.pipelineStatus.lint ? 'PASS' : 'PENDING'}`, `- Tests: ${cp.pipelineStatus.tests ? 'PASS' : 'PENDING'}`, '', '## Context Usage', `- Tokens used: ${String(cp.contextUsage.tokensEstimatedUsed)}`, `- Tokens available: ${String(cp.contextUsage.tokensEstimatedAvailable)}`, `- Operations: ${String(cp.contextUsage.operationCount)}`);
|
|
54
|
+
if (cp.contextUsage.topConsumers.length > 0) {
|
|
55
|
+
lines.push('- Top consumers:', ...cp.contextUsage.topConsumers.map((c) => ` - ${c.tool}: ${String(c.tokens)} tokens`));
|
|
56
|
+
}
|
|
57
|
+
return lines.join('\n');
|
|
58
|
+
}
|
|
59
|
+
/** Extract a one-line summary from a checkpoint. */
|
|
60
|
+
export function parseCheckpointSummary(cp) {
|
|
61
|
+
const parts = [
|
|
62
|
+
`${String(cp.contextUsage.percentUsed)}% context`,
|
|
63
|
+
`${String(cp.contextUsage.operationCount)} ops`,
|
|
64
|
+
];
|
|
65
|
+
if (cp.filesModified.length > 0) {
|
|
66
|
+
parts.push(`${String(cp.filesModified.length)} files modified`);
|
|
67
|
+
}
|
|
68
|
+
if (cp.specsInProgress.length > 0) {
|
|
69
|
+
parts.push(`specs: ${cp.specsInProgress.join(', ')}`);
|
|
70
|
+
}
|
|
71
|
+
return parts.join(' | ');
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Internal helpers
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
function buildAutoSummary(usage) {
|
|
77
|
+
return `Auto-checkpoint at ${String(usage.percentUsed)}% context usage (${String(usage.operationCount)} operations, ${String(usage.tokensEstimatedUsed)} tokens estimated).`;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=checkpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../../src/engine/context-budget/checkpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ResponseVerbosity } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Determine the effective verbosity level, auto-degrading when context
|
|
4
|
+
* pressure exceeds the configured threshold.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getEffectiveVerbosity(requested: ResponseVerbosity, percentUsed: number, autoCompressThreshold: number): {
|
|
7
|
+
verbosity: ResponseVerbosity;
|
|
8
|
+
autoCompressed: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Check whether the current context usage warrants auto-compression.
|
|
12
|
+
*/
|
|
13
|
+
export declare function shouldAutoCompress(percentUsed: number, threshold: number): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Compress a tool response text based on the target verbosity level.
|
|
16
|
+
* - compact: strip code blocks, collapse bullet lists, shorten sections
|
|
17
|
+
* - minimal: return only first paragraph + structured summary
|
|
18
|
+
*/
|
|
19
|
+
export declare function compressResponse(text: string, targetVerbosity: ResponseVerbosity): string;
|
|
20
|
+
//# sourceMappingURL=compressor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressor.d.ts","sourceRoot":"","sources":["../../../src/engine/context-budget/compressor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAM9D;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,iBAAiB,EAC5B,WAAW,EAAE,MAAM,EACnB,qBAAqB,EAAE,MAAM,GAC5B;IAAE,SAAS,EAAE,iBAAiB,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,CAY3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAElF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,iBAAiB,GAAG,MAAM,CAUzF"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Public API
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/**
|
|
5
|
+
* Determine the effective verbosity level, auto-degrading when context
|
|
6
|
+
* pressure exceeds the configured threshold.
|
|
7
|
+
*/
|
|
8
|
+
export function getEffectiveVerbosity(requested, percentUsed, autoCompressThreshold) {
|
|
9
|
+
const fraction = percentUsed / 100;
|
|
10
|
+
if (fraction < autoCompressThreshold) {
|
|
11
|
+
return { verbosity: requested, autoCompressed: false };
|
|
12
|
+
}
|
|
13
|
+
const degraded = degradeVerbosity(requested);
|
|
14
|
+
return {
|
|
15
|
+
verbosity: degraded,
|
|
16
|
+
autoCompressed: degraded !== requested,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Check whether the current context usage warrants auto-compression.
|
|
21
|
+
*/
|
|
22
|
+
export function shouldAutoCompress(percentUsed, threshold) {
|
|
23
|
+
return percentUsed / 100 >= threshold;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Compress a tool response text based on the target verbosity level.
|
|
27
|
+
* - compact: strip code blocks, collapse bullet lists, shorten sections
|
|
28
|
+
* - minimal: return only first paragraph + structured summary
|
|
29
|
+
*/
|
|
30
|
+
export function compressResponse(text, targetVerbosity) {
|
|
31
|
+
if (targetVerbosity === 'full') {
|
|
32
|
+
return text;
|
|
33
|
+
}
|
|
34
|
+
if (targetVerbosity === 'compact') {
|
|
35
|
+
return compactCompress(text);
|
|
36
|
+
}
|
|
37
|
+
return minimalCompress(text);
|
|
38
|
+
}
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Internal helpers
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
function degradeVerbosity(current) {
|
|
43
|
+
if (current === 'full') {
|
|
44
|
+
return 'compact';
|
|
45
|
+
}
|
|
46
|
+
if (current === 'compact') {
|
|
47
|
+
return 'minimal';
|
|
48
|
+
}
|
|
49
|
+
return 'minimal';
|
|
50
|
+
}
|
|
51
|
+
/** Compact: remove code blocks, trim long lists, keep structure. */
|
|
52
|
+
function compactCompress(text) {
|
|
53
|
+
let result = text;
|
|
54
|
+
// Remove fenced code blocks
|
|
55
|
+
result = result.replace(/```[\s\S]*?```/g, '[code block omitted for brevity]');
|
|
56
|
+
// Collapse long bullet lists (>5 items) to first 3 + count
|
|
57
|
+
result = collapseListItems(result);
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
/** Minimal: extract first meaningful paragraph only. */
|
|
61
|
+
function minimalCompress(text) {
|
|
62
|
+
const lines = text.split('\n');
|
|
63
|
+
const meaningful = [];
|
|
64
|
+
for (const line of lines) {
|
|
65
|
+
const trimmed = line.trim();
|
|
66
|
+
// Skip empty lines and code blocks
|
|
67
|
+
if (trimmed === '' && meaningful.length > 0) {
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
if (trimmed.startsWith('```')) {
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
if (trimmed !== '') {
|
|
74
|
+
meaningful.push(trimmed);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return meaningful.length > 0 ? meaningful.join('\n') : text.slice(0, 200);
|
|
78
|
+
}
|
|
79
|
+
/** Collapse bullet lists with more than 5 items. */
|
|
80
|
+
function collapseListItems(text) {
|
|
81
|
+
const lines = text.split('\n');
|
|
82
|
+
const result = [];
|
|
83
|
+
let bulletCount = 0;
|
|
84
|
+
let inBulletList = false;
|
|
85
|
+
let totalBullets = 0;
|
|
86
|
+
for (const line of lines) {
|
|
87
|
+
const isBullet = /^\s*[-*]\s/.test(line);
|
|
88
|
+
if (isBullet) {
|
|
89
|
+
if (!inBulletList) {
|
|
90
|
+
inBulletList = true;
|
|
91
|
+
bulletCount = 0;
|
|
92
|
+
totalBullets = countConsecutiveBullets(lines, lines.indexOf(line));
|
|
93
|
+
}
|
|
94
|
+
bulletCount++;
|
|
95
|
+
if (bulletCount <= 3) {
|
|
96
|
+
result.push(line);
|
|
97
|
+
}
|
|
98
|
+
else if (bulletCount === 4 && totalBullets > 5) {
|
|
99
|
+
result.push(` ... and ${String(totalBullets - 3)} more items`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
inBulletList = false;
|
|
104
|
+
bulletCount = 0;
|
|
105
|
+
result.push(line);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return result.join('\n');
|
|
109
|
+
}
|
|
110
|
+
function countConsecutiveBullets(lines, startIndex) {
|
|
111
|
+
let count = 0;
|
|
112
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
113
|
+
if (/^\s*[-*]\s/.test(lines[i] ?? '')) {
|
|
114
|
+
count++;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return count;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=compressor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressor.js","sourceRoot":"","sources":["../../../src/engine/context-budget/compressor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { recordToolCall, getStatus, getWarning, setConfig, getConfig, getSessionOps, resetSession, estimateTokensFromText, DEFAULT_CONFIG, } from './tracker.js';
|
|
2
|
+
export { generateCheckpoint, formatCheckpoint, parseCheckpointSummary } from './checkpoint.js';
|
|
3
|
+
export { analyzeSession, generateDelegationHints, suggestExplorePrompt } from './optimizer.js';
|
|
4
|
+
export { getEffectiveVerbosity, shouldAutoCompress, compressResponse } from './compressor.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/context-budget/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,aAAa,EACb,YAAY,EACZ,sBAAsB,EACtB,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAE/F,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE/F,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// engine/context-budget/index.ts — Barrel re-exports (SPEC-063)
|
|
2
|
+
export { recordToolCall, getStatus, getWarning, setConfig, getConfig, getSessionOps, resetSession, estimateTokensFromText, DEFAULT_CONFIG, } from './tracker.js';
|
|
3
|
+
export { generateCheckpoint, formatCheckpoint, parseCheckpointSummary } from './checkpoint.js';
|
|
4
|
+
export { analyzeSession, generateDelegationHints, suggestExplorePrompt } from './optimizer.js';
|
|
5
|
+
export { getEffectiveVerbosity, shouldAutoCompress, compressResponse } from './compressor.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/context-budget/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,OAAO,EACL,cAAc,EACd,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,aAAa,EACb,YAAY,EACZ,sBAAsB,EACtB,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAE/F,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE/F,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContextBudgetStatus, ContextOptimizationResult, DelegationHint, SessionOperation } from '../../types/index.js';
|
|
2
|
+
/** Analyze session operations and produce optimization recommendations. */
|
|
3
|
+
export declare function analyzeSession(ops: SessionOperation[], status: ContextBudgetStatus): ContextOptimizationResult;
|
|
4
|
+
/** Generate delegation hints based on session operation patterns. */
|
|
5
|
+
export declare function generateDelegationHints(ops: SessionOperation[]): DelegationHint[];
|
|
6
|
+
/** Build a ready-to-use Explore subagent prompt for batch file reading. */
|
|
7
|
+
export declare function suggestExplorePrompt(files: string[]): string;
|
|
8
|
+
//# sourceMappingURL=optimizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimizer.d.ts","sourceRoot":"","sources":["../../../src/engine/context-budget/optimizer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,yBAAyB,EACzB,cAAc,EACd,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAO9B,2EAA2E;AAC3E,wBAAgB,cAAc,CAC5B,GAAG,EAAE,gBAAgB,EAAE,EACvB,MAAM,EAAE,mBAAmB,GAC1B,yBAAyB,CAO3B;AAED,qEAAqE;AACrE,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,CA6CjF;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAc5D"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { recommendModel } from '../token-tracker.js';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Public API
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
/** Analyze session operations and produce optimization recommendations. */
|
|
6
|
+
export function analyzeSession(ops, status) {
|
|
7
|
+
return {
|
|
8
|
+
currentUsage: status,
|
|
9
|
+
delegationHints: generateDelegationHints(ops),
|
|
10
|
+
filesAlreadyRead: extractFilesRead(ops),
|
|
11
|
+
topTokenConsumers: status.topConsumers,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Generate delegation hints based on session operation patterns. */
|
|
15
|
+
export function generateDelegationHints(ops) {
|
|
16
|
+
const hints = [];
|
|
17
|
+
const toolCounts = countByTool(ops);
|
|
18
|
+
// Repeated reads → suggest Explore subagent
|
|
19
|
+
const readOps = toolCounts.consult_docs ?? 0;
|
|
20
|
+
if (readOps >= 3) {
|
|
21
|
+
hints.push({
|
|
22
|
+
operation: 'consult_docs',
|
|
23
|
+
reason: `Called ${String(readOps)} times — delegate batch lookups to an Explore subagent`,
|
|
24
|
+
suggestedModel: 'haiku',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// Heavy audit → suggest delegation
|
|
28
|
+
const auditOps = toolCounts.audit ?? 0;
|
|
29
|
+
if (auditOps >= 2) {
|
|
30
|
+
hints.push({
|
|
31
|
+
operation: 'audit',
|
|
32
|
+
reason: `${String(auditOps)} audit calls consume significant context — delegate to a dedicated subagent`,
|
|
33
|
+
suggestedModel: recommendModel('audit'),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// Many generate_tests calls
|
|
37
|
+
const testOps = toolCounts.generate_tests ?? 0;
|
|
38
|
+
if (testOps >= 2) {
|
|
39
|
+
hints.push({
|
|
40
|
+
operation: 'generate_tests',
|
|
41
|
+
reason: `${String(testOps)} test generation calls — consider batching in a subagent`,
|
|
42
|
+
suggestedModel: 'sonnet',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// Full-llm operations consuming too much
|
|
46
|
+
const fullLlmOps = ops.filter((op) => op.tokens >= 8000);
|
|
47
|
+
if (fullLlmOps.length >= 3) {
|
|
48
|
+
hints.push({
|
|
49
|
+
operation: 'full-llm-operations',
|
|
50
|
+
reason: `${String(fullLlmOps.length)} heavy operations detected — reduce by delegating to subagents with appropriate models`,
|
|
51
|
+
suggestedModel: 'sonnet',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return hints;
|
|
55
|
+
}
|
|
56
|
+
/** Build a ready-to-use Explore subagent prompt for batch file reading. */
|
|
57
|
+
export function suggestExplorePrompt(files) {
|
|
58
|
+
if (files.length === 0) {
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
const fileList = files.map((f) => `- ${f}`).join('\n');
|
|
62
|
+
return [
|
|
63
|
+
'Read and summarize the following files. For each file, provide:',
|
|
64
|
+
'1. Purpose (one sentence)',
|
|
65
|
+
'2. Key exports (functions, types, constants)',
|
|
66
|
+
'3. Dependencies (imports from other project modules)',
|
|
67
|
+
'',
|
|
68
|
+
'Files:',
|
|
69
|
+
fileList,
|
|
70
|
+
].join('\n');
|
|
71
|
+
}
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// Internal helpers
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
function countByTool(ops) {
|
|
76
|
+
const counts = {};
|
|
77
|
+
for (const op of ops) {
|
|
78
|
+
counts[op.tool] = (counts[op.tool] ?? 0) + 1;
|
|
79
|
+
}
|
|
80
|
+
return counts;
|
|
81
|
+
}
|
|
82
|
+
function extractFilesRead(ops) {
|
|
83
|
+
// Tools that typically involve reading files
|
|
84
|
+
const readTools = new Set(['consult_docs', 'audit', 'reverse_engineer', 'detect_drift']);
|
|
85
|
+
return ops.filter((op) => readTools.has(op.tool)).map((op) => op.tool);
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=optimizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimizer.js","sourceRoot":"","sources":["../../../src/engine/context-budget/optimizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ContextBudgetConfig, ContextBudgetStatus, ContextWarning, SessionOperation } from '../../types/index.js';
|
|
2
|
+
export declare const DEFAULT_CONFIG: ContextBudgetConfig;
|
|
3
|
+
/** Record a tool invocation with estimated token consumption. */
|
|
4
|
+
export declare function recordToolCall(tool: string, responseLength?: number): void;
|
|
5
|
+
/** Get the current context budget status. */
|
|
6
|
+
export declare function getStatus(config?: ContextBudgetConfig): ContextBudgetStatus;
|
|
7
|
+
/** Build a context warning if usage exceeds the warning threshold. */
|
|
8
|
+
export declare function getWarning(config?: ContextBudgetConfig): ContextWarning | null;
|
|
9
|
+
/** Update the active configuration. */
|
|
10
|
+
export declare function setConfig(config: Partial<ContextBudgetConfig>): ContextBudgetConfig;
|
|
11
|
+
/** Get the active configuration. */
|
|
12
|
+
export declare function getConfig(): ContextBudgetConfig;
|
|
13
|
+
/** Get the raw session operations list. */
|
|
14
|
+
export declare function getSessionOps(): SessionOperation[];
|
|
15
|
+
/** Reset all session state (for testing or new sessions). */
|
|
16
|
+
export declare function resetSession(): void;
|
|
17
|
+
/** Estimate tokens from text character length (chars × 0.25). */
|
|
18
|
+
export declare function estimateTokensFromText(charCount: number): number;
|
|
19
|
+
//# sourceMappingURL=tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../../src/engine/context-budget/tracker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,mBAAmB,EACnB,mBAAmB,EAEnB,cAAc,EACd,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAO9B,eAAO,MAAM,cAAc,EAAE,mBAM5B,CAAC;AAaF,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAK1E;AAED,6CAA6C;AAC7C,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,CAc3E;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,cAAc,GAAG,IAAI,CAe9E;AAED,uCAAuC;AACvC,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAGnF;AAED,oCAAoC;AACpC,wBAAgB,SAAS,IAAI,mBAAmB,CAE/C;AAED,2CAA2C;AAC3C,wBAAgB,aAAa,IAAI,gBAAgB,EAAE,CAElD;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,IAAI,IAAI,CAGnC;AAMD,iEAAiE;AACjE,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEhE"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { estimateTokensForOperation } from '../token-tracker.js';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Default configuration
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
export const DEFAULT_CONFIG = {
|
|
6
|
+
contextWindowSize: 200_000,
|
|
7
|
+
warningThreshold: 0.75,
|
|
8
|
+
criticalThreshold: 0.9,
|
|
9
|
+
autoCompressAbove: 0.75,
|
|
10
|
+
autoCheckpointAbove: 0.9,
|
|
11
|
+
};
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// In-memory session state (resets each server restart)
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
let sessionOps = [];
|
|
16
|
+
let activeConfig = { ...DEFAULT_CONFIG };
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Public API
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
/** Record a tool invocation with estimated token consumption. */
|
|
21
|
+
export function recordToolCall(tool, responseLength) {
|
|
22
|
+
const estimated = responseLength
|
|
23
|
+
? estimateTokensFromText(responseLength)
|
|
24
|
+
: estimateTokensForOperation(tool);
|
|
25
|
+
sessionOps.push({ tool, tokens: estimated, timestamp: new Date().toISOString() });
|
|
26
|
+
}
|
|
27
|
+
/** Get the current context budget status. */
|
|
28
|
+
export function getStatus(config) {
|
|
29
|
+
const cfg = config ?? activeConfig;
|
|
30
|
+
const totalUsed = sessionOps.reduce((sum, op) => sum + op.tokens, 0);
|
|
31
|
+
const available = Math.max(0, cfg.contextWindowSize - totalUsed);
|
|
32
|
+
const percent = cfg.contextWindowSize > 0 ? totalUsed / cfg.contextWindowSize : 0;
|
|
33
|
+
return {
|
|
34
|
+
tokensEstimatedUsed: totalUsed,
|
|
35
|
+
tokensEstimatedAvailable: available,
|
|
36
|
+
percentUsed: Math.round(percent * 100),
|
|
37
|
+
alertLevel: getAlertLevel(percent, cfg),
|
|
38
|
+
operationCount: sessionOps.length,
|
|
39
|
+
topConsumers: getTopConsumers(5),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Build a context warning if usage exceeds the warning threshold. */
|
|
43
|
+
export function getWarning(config) {
|
|
44
|
+
const cfg = config ?? activeConfig;
|
|
45
|
+
const status = getStatus(cfg);
|
|
46
|
+
const percent = status.percentUsed / 100;
|
|
47
|
+
if (percent < cfg.warningThreshold) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
const recommendation = getRecommendation(percent, cfg);
|
|
51
|
+
return {
|
|
52
|
+
percentUsed: status.percentUsed,
|
|
53
|
+
tokensRemaining: status.tokensEstimatedAvailable,
|
|
54
|
+
recommendation,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** Update the active configuration. */
|
|
58
|
+
export function setConfig(config) {
|
|
59
|
+
activeConfig = { ...activeConfig, ...config };
|
|
60
|
+
return activeConfig;
|
|
61
|
+
}
|
|
62
|
+
/** Get the active configuration. */
|
|
63
|
+
export function getConfig() {
|
|
64
|
+
return { ...activeConfig };
|
|
65
|
+
}
|
|
66
|
+
/** Get the raw session operations list. */
|
|
67
|
+
export function getSessionOps() {
|
|
68
|
+
return [...sessionOps];
|
|
69
|
+
}
|
|
70
|
+
/** Reset all session state (for testing or new sessions). */
|
|
71
|
+
export function resetSession() {
|
|
72
|
+
sessionOps = [];
|
|
73
|
+
activeConfig = { ...DEFAULT_CONFIG };
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Internal helpers
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
/** Estimate tokens from text character length (chars × 0.25). */
|
|
79
|
+
export function estimateTokensFromText(charCount) {
|
|
80
|
+
return Math.ceil(charCount * 0.25);
|
|
81
|
+
}
|
|
82
|
+
function getAlertLevel(percent, cfg) {
|
|
83
|
+
if (percent >= cfg.criticalThreshold) {
|
|
84
|
+
return 'red';
|
|
85
|
+
}
|
|
86
|
+
if (percent >= cfg.warningThreshold) {
|
|
87
|
+
return 'orange';
|
|
88
|
+
}
|
|
89
|
+
if (percent >= 0.5) {
|
|
90
|
+
return 'yellow';
|
|
91
|
+
}
|
|
92
|
+
return 'green';
|
|
93
|
+
}
|
|
94
|
+
function getTopConsumers(limit) {
|
|
95
|
+
const byTool = {};
|
|
96
|
+
for (const op of sessionOps) {
|
|
97
|
+
byTool[op.tool] = (byTool[op.tool] ?? 0) + op.tokens;
|
|
98
|
+
}
|
|
99
|
+
return Object.entries(byTool)
|
|
100
|
+
.map(([tool, tokens]) => ({ tool, tokens }))
|
|
101
|
+
.sort((a, b) => b.tokens - a.tokens)
|
|
102
|
+
.slice(0, limit);
|
|
103
|
+
}
|
|
104
|
+
function getRecommendation(percent, cfg) {
|
|
105
|
+
if (percent >= cfg.criticalThreshold) {
|
|
106
|
+
return 'Context nearly exhausted. Generate a checkpoint immediately and start a new session.';
|
|
107
|
+
}
|
|
108
|
+
if (percent >= cfg.warningThreshold) {
|
|
109
|
+
return 'Context pressure high. Delegate remaining work to subagents or reduce response verbosity.';
|
|
110
|
+
}
|
|
111
|
+
return 'Context usage moderate. Consider delegating large reads to subagents.';
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../../src/engine/context-budget/tracker.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SessionCheckpoint, ContextBudgetConfig, CheckpointSummary } from '../types/index.js';
|
|
2
|
+
/** Save a checkpoint to disk. Returns the checkpoint filename (ID). */
|
|
3
|
+
export declare function saveCheckpoint(projectId: string, checkpoint: SessionCheckpoint): Promise<string>;
|
|
4
|
+
/** Load a specific checkpoint or the most recent one. */
|
|
5
|
+
export declare function loadCheckpoint(projectId: string, checkpointId?: string): Promise<SessionCheckpoint | null>;
|
|
6
|
+
/** List available checkpoints with summaries. */
|
|
7
|
+
export declare function listCheckpoints(projectId: string, limit?: number): Promise<CheckpointSummary[]>;
|
|
8
|
+
/** Load the context budget config for a project. */
|
|
9
|
+
export declare function loadConfig(projectId: string): Promise<ContextBudgetConfig | null>;
|
|
10
|
+
/** Save the context budget config for a project. */
|
|
11
|
+
export declare function saveConfig(projectId: string, config: ContextBudgetConfig): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=checkpoint-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-store.d.ts","sourceRoot":"","sources":["../../src/storage/checkpoint-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAmBnG,uEAAuE;AACvE,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,yDAAyD;AACzD,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAkBnC;AAED,iDAAiD;AACjD,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAkBjG;AAMD,oDAAoD;AACpD,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAEvF;AAED,oDAAoD;AACpD,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9F"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// storage/checkpoint-store.ts — Checkpoint persistence (SPEC-063)
|
|
2
|
+
import { readdir, writeFile, mkdir } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { readJson, writeJson, projectDataDir } from './base-store.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Paths
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
function checkpointsDir(projectId) {
|
|
9
|
+
return join(projectDataDir(projectId), 'checkpoints');
|
|
10
|
+
}
|
|
11
|
+
function configPath(projectId) {
|
|
12
|
+
return join(projectDataDir(projectId), 'context-budget.json');
|
|
13
|
+
}
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Checkpoint CRUD
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/** Save a checkpoint to disk. Returns the checkpoint filename (ID). */
|
|
18
|
+
export async function saveCheckpoint(projectId, checkpoint) {
|
|
19
|
+
const dir = checkpointsDir(projectId);
|
|
20
|
+
await mkdir(dir, { recursive: true });
|
|
21
|
+
const id = checkpoint.timestamp.replace(/[:.]/g, '-');
|
|
22
|
+
const filePath = join(dir, `${id}.json`);
|
|
23
|
+
await writeFile(filePath, JSON.stringify(checkpoint, null, 2), 'utf-8');
|
|
24
|
+
return id;
|
|
25
|
+
}
|
|
26
|
+
/** Load a specific checkpoint or the most recent one. */
|
|
27
|
+
export async function loadCheckpoint(projectId, checkpointId) {
|
|
28
|
+
const dir = checkpointsDir(projectId);
|
|
29
|
+
if (checkpointId) {
|
|
30
|
+
return readJson(join(dir, `${checkpointId}.json`), null);
|
|
31
|
+
}
|
|
32
|
+
// Load most recent
|
|
33
|
+
const files = await listCheckpointFiles(dir);
|
|
34
|
+
if (files.length === 0) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const latest = files[files.length - 1];
|
|
38
|
+
/* c8 ignore next 3 */
|
|
39
|
+
if (!latest) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return readJson(join(dir, latest), null);
|
|
43
|
+
}
|
|
44
|
+
/** List available checkpoints with summaries. */
|
|
45
|
+
export async function listCheckpoints(projectId, limit = 10) {
|
|
46
|
+
const dir = checkpointsDir(projectId);
|
|
47
|
+
const files = await listCheckpointFiles(dir);
|
|
48
|
+
const recent = files.slice(-limit);
|
|
49
|
+
const summaries = [];
|
|
50
|
+
for (const file of recent) {
|
|
51
|
+
const cp = await readJson(join(dir, file), null);
|
|
52
|
+
if (cp) {
|
|
53
|
+
summaries.push({
|
|
54
|
+
id: file.replace('.json', ''),
|
|
55
|
+
timestamp: cp.timestamp,
|
|
56
|
+
summary: cp.summary.slice(0, 120),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return summaries;
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Config persistence
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
/** Load the context budget config for a project. */
|
|
66
|
+
export async function loadConfig(projectId) {
|
|
67
|
+
return readJson(configPath(projectId), null);
|
|
68
|
+
}
|
|
69
|
+
/** Save the context budget config for a project. */
|
|
70
|
+
export async function saveConfig(projectId, config) {
|
|
71
|
+
await writeJson(configPath(projectId), config);
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Internal helpers
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
async function listCheckpointFiles(dir) {
|
|
77
|
+
try {
|
|
78
|
+
const entries = await readdir(dir);
|
|
79
|
+
return entries.filter((f) => f.endsWith('.json')).sort();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=checkpoint-store.js.map
|