@compaction/cli 0.1.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.
Files changed (143) hide show
  1. package/LICENSE +663 -0
  2. package/README.md +319 -0
  3. package/dist/cli/commands/adapter.d.ts +2 -0
  4. package/dist/cli/commands/adapter.js +49 -0
  5. package/dist/cli/commands/aggregate.d.ts +2 -0
  6. package/dist/cli/commands/aggregate.js +60 -0
  7. package/dist/cli/commands/analyze.d.ts +2 -0
  8. package/dist/cli/commands/analyze.js +55 -0
  9. package/dist/cli/commands/apply-context.d.ts +12 -0
  10. package/dist/cli/commands/apply-context.js +80 -0
  11. package/dist/cli/commands/apply.d.ts +2 -0
  12. package/dist/cli/commands/apply.js +65 -0
  13. package/dist/cli/commands/approve.d.ts +2 -0
  14. package/dist/cli/commands/approve.js +55 -0
  15. package/dist/cli/commands/audit.d.ts +2 -0
  16. package/dist/cli/commands/audit.js +63 -0
  17. package/dist/cli/commands/billing-delta.d.ts +2 -0
  18. package/dist/cli/commands/billing-delta.js +246 -0
  19. package/dist/cli/commands/capture-claude-code.d.ts +19 -0
  20. package/dist/cli/commands/capture-claude-code.js +198 -0
  21. package/dist/cli/commands/capture-provider-usage.d.ts +35 -0
  22. package/dist/cli/commands/capture-provider-usage.js +113 -0
  23. package/dist/cli/commands/capture.d.ts +2 -0
  24. package/dist/cli/commands/capture.js +76 -0
  25. package/dist/cli/commands/compact.d.ts +2 -0
  26. package/dist/cli/commands/compact.js +206 -0
  27. package/dist/cli/commands/eval.d.ts +2 -0
  28. package/dist/cli/commands/eval.js +66 -0
  29. package/dist/cli/commands/export-session-seed.d.ts +11 -0
  30. package/dist/cli/commands/export-session-seed.js +42 -0
  31. package/dist/cli/commands/feedback.d.ts +2 -0
  32. package/dist/cli/commands/feedback.js +233 -0
  33. package/dist/cli/commands/import.d.ts +2 -0
  34. package/dist/cli/commands/import.js +60 -0
  35. package/dist/cli/commands/init.d.ts +2 -0
  36. package/dist/cli/commands/init.js +216 -0
  37. package/dist/cli/commands/integrations.d.ts +2 -0
  38. package/dist/cli/commands/integrations.js +29 -0
  39. package/dist/cli/commands/launch-treatment-session.d.ts +14 -0
  40. package/dist/cli/commands/launch-treatment-session.js +50 -0
  41. package/dist/cli/commands/optimize.d.ts +2 -0
  42. package/dist/cli/commands/optimize.js +33 -0
  43. package/dist/cli/commands/recommend.d.ts +4 -0
  44. package/dist/cli/commands/recommend.js +66 -0
  45. package/dist/cli/commands/review.d.ts +2 -0
  46. package/dist/cli/commands/review.js +60 -0
  47. package/dist/cli/commands/run.d.ts +2 -0
  48. package/dist/cli/commands/run.js +49 -0
  49. package/dist/cli/commands/spend.d.ts +2 -0
  50. package/dist/cli/commands/spend.js +24 -0
  51. package/dist/cli/commands/summary.d.ts +2 -0
  52. package/dist/cli/commands/summary.js +19 -0
  53. package/dist/cli/engine-degrade.d.ts +40 -0
  54. package/dist/cli/engine-degrade.js +59 -0
  55. package/dist/cli/index.d.ts +2 -0
  56. package/dist/cli/index.js +59 -0
  57. package/dist/core/adapter-validation.d.ts +32 -0
  58. package/dist/core/adapter-validation.js +185 -0
  59. package/dist/core/adapters/claude-code-adapter.d.ts +51 -0
  60. package/dist/core/adapters/claude-code-adapter.js +539 -0
  61. package/dist/core/adapters/claude-code-discovery.d.ts +40 -0
  62. package/dist/core/adapters/claude-code-discovery.js +100 -0
  63. package/dist/core/aggregate-format.d.ts +62 -0
  64. package/dist/core/aggregate-format.js +349 -0
  65. package/dist/core/api-client/client.d.ts +43 -0
  66. package/dist/core/api-client/client.js +143 -0
  67. package/dist/core/api-client/config.d.ts +36 -0
  68. package/dist/core/api-client/config.js +44 -0
  69. package/dist/core/api-client/index.d.ts +13 -0
  70. package/dist/core/api-client/index.js +14 -0
  71. package/dist/core/api-client/payload.d.ts +93 -0
  72. package/dist/core/api-client/payload.js +180 -0
  73. package/dist/core/api-client/types.d.ts +95 -0
  74. package/dist/core/api-client/types.js +21 -0
  75. package/dist/core/artifact-writer.d.ts +2 -0
  76. package/dist/core/artifact-writer.js +14 -0
  77. package/dist/core/audit-report.d.ts +91 -0
  78. package/dist/core/audit-report.js +422 -0
  79. package/dist/core/billing-delta/billing-delta-record.d.ts +290 -0
  80. package/dist/core/billing-delta/billing-delta-record.js +394 -0
  81. package/dist/core/capture-adapter.d.ts +74 -0
  82. package/dist/core/capture-adapter.js +2 -0
  83. package/dist/core/command-runner.d.ts +29 -0
  84. package/dist/core/command-runner.js +96 -0
  85. package/dist/core/content-hash.d.ts +1 -0
  86. package/dist/core/content-hash.js +5 -0
  87. package/dist/core/cost-calculator.d.ts +6 -0
  88. package/dist/core/cost-calculator.js +20 -0
  89. package/dist/core/feedback-bundle.d.ts +159 -0
  90. package/dist/core/feedback-bundle.js +406 -0
  91. package/dist/core/openai-agents-capture.d.ts +66 -0
  92. package/dist/core/openai-agents-capture.js +475 -0
  93. package/dist/core/policy-types.d.ts +85 -0
  94. package/dist/core/policy-types.js +29 -0
  95. package/dist/core/pricing.d.ts +23 -0
  96. package/dist/core/pricing.js +55 -0
  97. package/dist/core/provider-usage/credential-redaction.d.ts +23 -0
  98. package/dist/core/provider-usage/credential-redaction.js +60 -0
  99. package/dist/core/provider-usage/provider-usage-adapter.d.ts +65 -0
  100. package/dist/core/provider-usage/provider-usage-adapter.js +147 -0
  101. package/dist/core/provider-usage/provider-usage-client.d.ts +89 -0
  102. package/dist/core/provider-usage/provider-usage-client.js +96 -0
  103. package/dist/core/report-generator.d.ts +7 -0
  104. package/dist/core/report-generator.js +275 -0
  105. package/dist/core/run-aggregator.d.ts +50 -0
  106. package/dist/core/run-aggregator.js +251 -0
  107. package/dist/core/run-labels.d.ts +52 -0
  108. package/dist/core/run-labels.js +80 -0
  109. package/dist/core/run-trace-converter.d.ts +3 -0
  110. package/dist/core/run-trace-converter.js +94 -0
  111. package/dist/core/safety-report.d.ts +52 -0
  112. package/dist/core/safety-report.js +440 -0
  113. package/dist/core/savings.d.ts +22 -0
  114. package/dist/core/savings.js +36 -0
  115. package/dist/core/session-aggregate.d.ts +211 -0
  116. package/dist/core/session-aggregate.js +490 -0
  117. package/dist/core/skill-injection-detector.d.ts +51 -0
  118. package/dist/core/skill-injection-detector.js +146 -0
  119. package/dist/core/spend-attribution.d.ts +169 -0
  120. package/dist/core/spend-attribution.js +611 -0
  121. package/dist/core/standalone-capsule-provenance.d.ts +4 -0
  122. package/dist/core/standalone-capsule-provenance.js +62 -0
  123. package/dist/core/state-capsule.d.ts +3 -0
  124. package/dist/core/state-capsule.js +147 -0
  125. package/dist/core/token-accounting.d.ts +62 -0
  126. package/dist/core/token-accounting.js +81 -0
  127. package/dist/core/token-estimator.d.ts +3 -0
  128. package/dist/core/token-estimator.js +18 -0
  129. package/dist/core/trace-adapters.d.ts +53 -0
  130. package/dist/core/trace-adapters.js +714 -0
  131. package/dist/core/trace-fingerprint.d.ts +79 -0
  132. package/dist/core/trace-fingerprint.js +102 -0
  133. package/dist/core/trace-intake.d.ts +41 -0
  134. package/dist/core/trace-intake.js +164 -0
  135. package/dist/core/trace-parser.d.ts +203 -0
  136. package/dist/core/trace-parser.js +143 -0
  137. package/dist/core/types.d.ts +238 -0
  138. package/dist/core/types.js +2 -0
  139. package/dist/core/usage-metadata.d.ts +51 -0
  140. package/dist/core/usage-metadata.js +122 -0
  141. package/dist/core/waste-detector.d.ts +8 -0
  142. package/dist/core/waste-detector.js +58 -0
  143. package/package.json +90 -0
@@ -0,0 +1,146 @@
1
+ import { estimateTextTokens } from "./token-estimator.js";
2
+ /**
3
+ * Report-only skill-injection repetition detector.
4
+ *
5
+ * SCOPE (per docs/design/skill-injection-compaction-policy.md, report-only rung):
6
+ * This module DETECTS and REPORTS repeated byte-identical, same-skill `role:user`
7
+ * skill injections. It compacts NOTHING. The `repeated_skill_injection` finding
8
+ * category it produces is intentionally excluded from `getCompactedMessageIds`
9
+ * (see waste-detector.ts) and from the apply path (policy-middleware.ts), so the
10
+ * policy is report-only by construction. No message is ever removed, replaced, or
11
+ * capsuled by this detector.
12
+ *
13
+ * The dedup map here is SEPARATE from the tool-output dedup map in `detectWaste`.
14
+ * An ordinary `role:user`/orchestrator message can never enter this candidate set
15
+ * because the identification gate requires the literal skill-injection prefix and a
16
+ * parseable skill name.
17
+ *
18
+ * Open questions resolved against a real --include-subagents capture
19
+ * (ae4dce14-e4ef-4d50-a852-f531fc53b490, 131 injection messages):
20
+ * - Q5 (threshold reuse): the smallest captured injection body is 1,267 chars / 317 est
21
+ * tokens — every body is well above the existing 800-char / 200-token tool-output
22
+ * thresholds, so those thresholds are effectively moot for this policy. This detector
23
+ * therefore applies no size threshold (full exact-key dedup is the rule).
24
+ * - Q2 (owning-agent-id recoverability): capture prefixes SUBAGENT message ids
25
+ * `agent-<agentId>-<uuid>`, so for the 108 subagent injections the owning agent id IS
26
+ * recoverable from `messageId` alone. The 23 ROOT-agent injections (start-cycle,
27
+ * complete-cycle, next-cycles) carry a bare UUID with NO agent prefix, so root-agent
28
+ * identity is NOT encoded in `messageId`. Report-only does not act on this; at the later
29
+ * apply rung a small additive provenance field would be needed to record root-agent
30
+ * identity + replaced-position for the bare-UUID copies.
31
+ */
32
+ const SKILL_INJECTION_PREFIX = "Base directory for this skill:";
33
+ // Matches the skill name in the `.../.claude/skills/<NAME>` path on the first line.
34
+ const SKILL_PATH_PATTERN = /\.claude\/skills\/([A-Za-z0-9._-]+)/;
35
+ const ESTIMATE_LABEL = "estimated (chars/4) trace-token reduction — NOT billing-confirmed, NOT realized savings, NOT yet applied";
36
+ const RECOMMENDATION = "Report-only: no message was compacted. The byte-identical, same-skill skill-injection " +
37
+ "repetition above is the addressable volume a future approval-required rung could compact. " +
38
+ "Near-identical (ARGUMENTS-divergent) injections are excluded by construction and are never addressable.";
39
+ export function parseSkillName(content) {
40
+ const firstLine = content.split("\n", 1)[0] ?? "";
41
+ const match = firstLine.match(SKILL_PATH_PATTERN);
42
+ return match ? match[1] : null;
43
+ }
44
+ export function isSkillInjection(message) {
45
+ return (message.role === "user" &&
46
+ typeof message.content === "string" &&
47
+ message.content.startsWith(SKILL_INJECTION_PREFIX) &&
48
+ parseSkillName(message.content) !== null);
49
+ }
50
+ /**
51
+ * Normalize for the EXACT (byte-identical) dedup key. Trailing whitespace only is
52
+ * trimmed (per the design's `normalizeTrailingWhitespace`). Internal whitespace is
53
+ * preserved so near-identical bodies (divergent trailing `ARGUMENTS:` blocks)
54
+ * produce DIFFERENT keys and can never be grouped. This is the hard safety boundary.
55
+ */
56
+ function normalizeExactContent(content) {
57
+ return content.replace(/\s+$/, "");
58
+ }
59
+ /**
60
+ * Detect repeated byte-identical, same-skill skill injections.
61
+ *
62
+ * Key = `${skillName}:${normalizeExactContent(content)}` — exact, NOT a prefix, NOT fuzzy.
63
+ * First occurrence of each key is retained; each later exact-key copy is a redundant
64
+ * byte-identical candidate (the reportable volume). Different normalized content (e.g.
65
+ * divergent ARGUMENTS) ⇒ different key ⇒ never grouped (near-identical excluded by
66
+ * construction). Two different skills can never share a key because the key is prefixed
67
+ * with the parsed skill name.
68
+ *
69
+ * REPORT-ONLY: returns findings; never mutates the trace.
70
+ */
71
+ export function detectSkillInjectionRepetition(trace) {
72
+ const findings = [];
73
+ const firstBySkillExactContent = new Map();
74
+ for (const message of trace.messages) {
75
+ if (!isSkillInjection(message)) {
76
+ continue;
77
+ }
78
+ const skillName = parseSkillName(message.content);
79
+ if (skillName === null) {
80
+ continue;
81
+ }
82
+ const key = `${skillName}:${normalizeExactContent(message.content)}`;
83
+ const firstCopy = firstBySkillExactContent.get(key);
84
+ if (!firstCopy) {
85
+ firstBySkillExactContent.set(key, message);
86
+ continue;
87
+ }
88
+ findings.push({
89
+ category: "repeated_skill_injection",
90
+ messageIds: [firstCopy.id, message.id],
91
+ summary: `Repeated byte-identical ${skillName} skill injection. Retain ${firstCopy.id}; ${message.id} is a redundant byte-identical copy (report-only, not compacted).`,
92
+ estimatedTokens: estimateTextTokens(message.content),
93
+ skillName,
94
+ firstCopyMessageId: firstCopy.id,
95
+ redundantCopyMessageId: message.id
96
+ });
97
+ }
98
+ return findings;
99
+ }
100
+ function countUniqueFirstCopies(trace) {
101
+ const keys = new Set();
102
+ for (const message of trace.messages) {
103
+ if (!isSkillInjection(message)) {
104
+ continue;
105
+ }
106
+ const skillName = parseSkillName(message.content);
107
+ if (skillName === null) {
108
+ continue;
109
+ }
110
+ keys.add(`${skillName}:${normalizeExactContent(message.content)}`);
111
+ }
112
+ return keys.size;
113
+ }
114
+ /**
115
+ * Build the report-only advisory (per-skill spend attribution + total addressable est).
116
+ * Pure: derived from the detector findings; nothing is compacted.
117
+ */
118
+ export function buildSkillInjectionAdvisory(trace) {
119
+ const findings = detectSkillInjectionRepetition(trace);
120
+ const bySkill = new Map();
121
+ let totalTokens = 0;
122
+ for (const finding of findings) {
123
+ const bucket = bySkill.get(finding.skillName) ?? {
124
+ skill_name: finding.skillName,
125
+ redundant_byte_identical_copies: 0,
126
+ estimated_tokens: 0,
127
+ redundant_copy_message_ids: []
128
+ };
129
+ bucket.redundant_byte_identical_copies += 1;
130
+ bucket.estimated_tokens += finding.estimatedTokens;
131
+ bucket.redundant_copy_message_ids.push(finding.redundantCopyMessageId);
132
+ bySkill.set(finding.skillName, bucket);
133
+ totalTokens += finding.estimatedTokens;
134
+ }
135
+ const skills = [...bySkill.values()].sort((a, b) => b.estimated_tokens - a.estimated_tokens);
136
+ return {
137
+ report_only: true,
138
+ skills,
139
+ total_redundant_byte_identical_copies: findings.length,
140
+ total_addressable_estimated_tokens: totalTokens,
141
+ first_copy_count: countUniqueFirstCopies(trace),
142
+ estimate_label: ESTIMATE_LABEL,
143
+ recommendation: RECOMMENDATION
144
+ };
145
+ }
146
+ //# sourceMappingURL=skill-injection-detector.js.map
@@ -0,0 +1,169 @@
1
+ import type { MetadataStatus } from "./openai-agents-capture.js";
2
+ import type { RecommendationMode, RecommendationRiskLevel, RecommendationSafetyStatus } from "../engine/recommendation.js";
3
+ import type { IntegrationWorkflowMetadata } from "../engine/openai-agents-optimization.js";
4
+ import { type UsageMetadata } from "./usage-metadata.js";
5
+ import type { AgentTrace, WasteFinding } from "./types.js";
6
+ /**
7
+ * Engine-derived optimization-delta inputs for a trace. The PROPRIETARY part of a spend summary:
8
+ * what a compaction policy would do (policy candidate, post-compaction tokens/cost, the recommendation
9
+ * verdict, and safety/risk). The FREE local attribution (where spend comes from — by role, tool output,
10
+ * waste pattern, skill-injection) does NOT depend on any of this and is always computed.
11
+ *
12
+ * In the in-repo / API build an engine-backed provider supplies this (see `engineOptimizationDeltaProvider`).
13
+ * In a public install with the engine excluded, no provider is available and the optimization-delta fields
14
+ * degrade honestly: `available: false`, no policy candidate, `safety_status: "missing"`, and ZERO synthetic
15
+ * saving is shown — the formatters print the boundary clause instead of a misleading `$0.000000` saving.
16
+ */
17
+ export interface TraceOptimizationDelta {
18
+ available: boolean;
19
+ policy_candidate: string | null;
20
+ tokens_after: number;
21
+ cost_after: number;
22
+ tokens_saved: number;
23
+ saving_per_run: number;
24
+ safety_status: RecommendationSafetyStatus;
25
+ risk_level: RecommendationRiskLevel;
26
+ recommendation_mode: RecommendationMode;
27
+ next_step: string;
28
+ }
29
+ /**
30
+ * Optional provider that computes the engine-derived {@link TraceOptimizationDelta} for a trace.
31
+ * Supplied by engine/API callers via lazy import; absent on the free path.
32
+ */
33
+ export type OptimizationDeltaProvider = (trace: AgentTrace, before: {
34
+ inputTokens: number;
35
+ outputTokens: number;
36
+ }, costBefore: number, generatedAt: string) => Promise<TraceOptimizationDelta> | TraceOptimizationDelta;
37
+ /**
38
+ * Lazily load the proprietary engine and build an OptimizationDeltaProvider from it. Used by the
39
+ * `spend` CLI command so a real engine build produces the full optimization delta, while a public
40
+ * install (engine excluded) falls back to {@link unavailableOptimizationDelta} WITHOUT crashing.
41
+ * Returns `null` when the engine build is absent.
42
+ */
43
+ export declare function loadEngineOptimizationDeltaProvider(): Promise<OptimizationDeltaProvider | null>;
44
+ export declare const SPEND_ARTIFACT_ROOT = ".compaction/spend";
45
+ export declare const SPEND_LIMITATIONS: readonly ["local estimates only when billing data is unavailable", "token/cost metadata may be partial", "not provider billing data unless explicitly captured", "no auto mode", "no model routing", "no hosted dashboard"];
46
+ type InputKind = "trace" | "optimization_summary" | "recommendation";
47
+ export interface SpendBucket {
48
+ name: string;
49
+ input_tokens: number;
50
+ output_tokens: number;
51
+ total_tokens: number;
52
+ estimated_cost: number;
53
+ message_count?: number;
54
+ }
55
+ export interface ToolSpendBucket extends SpendBucket {
56
+ tool_name: string;
57
+ repeated_count: number;
58
+ message_ids: string[];
59
+ }
60
+ export interface WastePatternSpendBucket {
61
+ pattern: WasteFinding["category"];
62
+ estimated_tokens: number;
63
+ estimated_cost: number;
64
+ finding_count: number;
65
+ message_ids: string[];
66
+ summaries: string[];
67
+ }
68
+ export interface PolicyCandidateSpendBucket {
69
+ policy_name: string;
70
+ estimated_tokens_saved: number;
71
+ estimated_saving_per_run: number;
72
+ percent_reduction: number;
73
+ safety_status: RecommendationSafetyStatus;
74
+ risk_level: RecommendationRiskLevel;
75
+ recommendation_mode: RecommendationMode;
76
+ }
77
+ /**
78
+ * Per-skill skill-injection spend bucket (report-only). Attributes redundant
79
+ * byte-identical role:user skill-injection volume by skill. Detection/reporting only —
80
+ * nothing is compacted. `estimated_tokens` is chars/4, NOT realized savings.
81
+ */
82
+ export interface SkillInjectionSpendBucket extends SpendBucket {
83
+ skill_name: string;
84
+ redundant_byte_identical_copies: number;
85
+ redundant_copy_message_ids: string[];
86
+ }
87
+ export interface RepeatedContextSegmentSpend {
88
+ segment_id: string;
89
+ category: WasteFinding["category"];
90
+ estimated_tokens: number;
91
+ estimated_cost: number;
92
+ message_ids: string[];
93
+ summary: string;
94
+ }
95
+ export interface SpendSummary {
96
+ trace_id: string;
97
+ generated_at: string;
98
+ integration: string | null;
99
+ integration_workflow?: IntegrationWorkflowMetadata;
100
+ token_metadata_status: MetadataStatus;
101
+ cost_metadata_status: MetadataStatus;
102
+ usage_metadata: UsageMetadata;
103
+ spend_confidence: UsageMetadata["cost_confidence"];
104
+ pricing_assumptions: string[];
105
+ input_tokens_before: number;
106
+ input_tokens_after: number;
107
+ output_tokens_before?: number;
108
+ output_tokens_after?: number;
109
+ tokens_saved: number;
110
+ percent_reduction: number;
111
+ savings_scope: "policy_level";
112
+ estimated_cost_before: number;
113
+ estimated_cost_after: number;
114
+ estimated_saving_per_run: number;
115
+ spend_by_role: SpendBucket[];
116
+ spend_by_tool_output: ToolSpendBucket[];
117
+ spend_by_repeated_context_segment: RepeatedContextSegmentSpend[];
118
+ spend_by_waste_pattern: WastePatternSpendBucket[];
119
+ spend_by_policy_candidate: PolicyCandidateSpendBucket[];
120
+ /** Report-only: per-skill redundant byte-identical skill-injection spend. Nothing compacted. */
121
+ spend_by_skill_injection: SkillInjectionSpendBucket[];
122
+ /** Report-only: total addressable est trace-token volume across skill injections (chars/4). */
123
+ skill_injection_addressable_estimated_tokens: number;
124
+ top_waste_patterns: WastePatternSpendBucket[];
125
+ top_role_category: SpendBucket | null;
126
+ top_repeated_tool_output: ToolSpendBucket | null;
127
+ top_waste_pattern: WastePatternSpendBucket | null;
128
+ top_policy_candidate: PolicyCandidateSpendBucket | null;
129
+ policy_candidate: string | null;
130
+ /**
131
+ * Whether the proprietary optimization-delta engine was available for this summary. When false
132
+ * (public install, engine excluded) the optimization-delta fields below are NOT engine-computed:
133
+ * `policy_candidate` is null, `tokens_saved`/`estimated_saving_per_run` are 0 (NOT a real $0 saving
134
+ * — the formatters print the boundary clause instead), and `safety_status` is `missing`. The FREE
135
+ * local attribution (spend_by_role / _tool_output / _waste_pattern / _skill_injection) is unaffected.
136
+ */
137
+ optimization_delta_available: boolean;
138
+ safety_status: RecommendationSafetyStatus;
139
+ risk_level: RecommendationRiskLevel;
140
+ recommendation_mode: RecommendationMode;
141
+ approval_status?: string;
142
+ next_step: string;
143
+ limitations: string[];
144
+ source_path: string;
145
+ input_kind: InputKind;
146
+ }
147
+ export interface SpendArtifacts {
148
+ summary: SpendSummary;
149
+ outputDirectory: string;
150
+ terminalSummary: string;
151
+ paths: {
152
+ spendSummaryJsonPath: string;
153
+ spendSummaryMarkdownPath: string;
154
+ };
155
+ }
156
+ /**
157
+ * Build a SpendSummary directly from an in-memory trace, reusing the exact same
158
+ * attribution computation used by the `spend` CLI command (buildTraceSpendSummary).
159
+ * Exposed so the compaction report can surface a concise spend-by-source summary
160
+ * WITHOUT reimplementing attribution logic. Numbers are local estimates (chars/4 /
161
+ * price-table), NOT billing-confirmed and NOT realized savings.
162
+ */
163
+ export declare function buildSpendSummaryFromTrace(trace: AgentTrace, generatedAt?: string, integration?: string | null, optimizationDeltaProvider?: OptimizationDeltaProvider): Promise<SpendSummary>;
164
+ export declare function createSpendSummaryFromPath(sourcePath: string, generatedAt?: string, optimizationDeltaProvider?: OptimizationDeltaProvider): Promise<SpendSummary>;
165
+ export declare function formatSpendConsoleSummary(summary: SpendSummary): string;
166
+ export declare function formatSpendMarkdown(summary: SpendSummary): string;
167
+ export declare function writeSpendArtifacts(inputPath: string, outRoot?: string, generatedAt?: string, optimizationDeltaProvider?: OptimizationDeltaProvider): Promise<SpendArtifacts>;
168
+ export declare function defaultSpendPolicyName(): string;
169
+ export {};