@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,29 @@
1
+ import chalk from "chalk";
2
+ import { runEngineCommand } from "../engine-degrade.js";
3
+ export function registerIntegrationsCommand(program) {
4
+ const integrations = program.command("integrations").description("Run real local integration capture workflows.");
5
+ integrations
6
+ .command("run")
7
+ .description("Run a supported integration capture and feed it through optimize/spend/review evidence generation.")
8
+ .argument("<integration-id>", "Integration id to run, for example openai-agents")
9
+ .requiredOption("--out <dir>", "Output root directory for integration artifacts")
10
+ .argument("[commandParts...]", "Command and arguments to execute after --")
11
+ .allowUnknownOption(true)
12
+ .action(async (integrationId, commandParts, options) => {
13
+ await runEngineCommand(async () => {
14
+ // The integration workflow drives the proprietary optimize/review engine. Lazy-load the core
15
+ // integrations module (which statically imports the engine); when the engine build is excluded
16
+ // this dynamic import fails and runEngineCommand prints the boundary message and exits cleanly.
17
+ const { runIntegration } = await import("../../core/integrations.js");
18
+ console.log(chalk.cyan(`compaction integrations run ${integrationId}`));
19
+ console.log("Running a local integration capture. No scraping, hosted service, auth, billing workflow, model routing, provider switching, or auto mode is used.");
20
+ const artifacts = await runIntegration({ integrationId, outRoot: options.out, commandParts });
21
+ console.log(artifacts.terminalSummary);
22
+ console.log(chalk.green(`Wrote ${artifacts.paths.normalizedTracePath}`));
23
+ console.log(chalk.green(`Wrote ${artifacts.paths.reportJsonPath}`));
24
+ console.log(chalk.green(`Wrote ${artifacts.paths.reportMarkdownPath}`));
25
+ console.log(chalk.green(`Evidence directory: ${artifacts.outputDirectory}`));
26
+ });
27
+ });
28
+ }
29
+ //# sourceMappingURL=integrations.js.map
@@ -0,0 +1,14 @@
1
+ import { Command } from "commander";
2
+ /**
3
+ * `compaction launch-treatment-session --apply-dir <dir> [--out <script>] [--seed <file>] [--project-dir <dir>]`
4
+ *
5
+ * Prepares (WRITES) an executable launch script for a FRESH seeded Claude Code session — the Lane B
6
+ * treatment arm. It NEVER starts the session itself and NEVER spawns `claude`; YOU run the script.
7
+ *
8
+ * Reuses the EXACT approval gates of `export-session-seed` (valid `approved_for_in_workflow_use` record,
9
+ * approved-context present + hash-matched, retained original present + hash-matched). Refuses otherwise —
10
+ * no script written, exit non-zero. If `session-seed.md` is absent it is generated by REUSING
11
+ * `exportSessionSeed`; if present it is reused unchanged. Read-only over apply artifacts except for the
12
+ * new script (and the seed only when generated). No provider call, no network, no global config changes.
13
+ */
14
+ export declare function registerLaunchTreatmentSessionCommand(program: Command): void;
@@ -0,0 +1,50 @@
1
+ import chalk from "chalk";
2
+ import { runEngineCommand } from "../engine-degrade.js";
3
+ /**
4
+ * `compaction launch-treatment-session --apply-dir <dir> [--out <script>] [--seed <file>] [--project-dir <dir>]`
5
+ *
6
+ * Prepares (WRITES) an executable launch script for a FRESH seeded Claude Code session — the Lane B
7
+ * treatment arm. It NEVER starts the session itself and NEVER spawns `claude`; YOU run the script.
8
+ *
9
+ * Reuses the EXACT approval gates of `export-session-seed` (valid `approved_for_in_workflow_use` record,
10
+ * approved-context present + hash-matched, retained original present + hash-matched). Refuses otherwise —
11
+ * no script written, exit non-zero. If `session-seed.md` is absent it is generated by REUSING
12
+ * `exportSessionSeed`; if present it is reused unchanged. Read-only over apply artifacts except for the
13
+ * new script (and the seed only when generated). No provider call, no network, no global config changes.
14
+ */
15
+ export function registerLaunchTreatmentSessionCommand(program) {
16
+ program
17
+ .command("launch-treatment-session")
18
+ .description("Prepare (WRITE, never run) an executable launch script for a FRESH seeded Claude Code session — Lane B treatment arm (TREATMENT SETUP, NOT billing-confirmed savings; operator-invoked, NOT auto-apply). Refuses unless approved + hashes match. Never spawns claude; never touches global config.")
19
+ .requiredOption("--apply-dir <dir>", "The apply-context artifacts directory (must contain an approval record)")
20
+ .option("--out <script>", "Where to write the launch script (default: <apply-dir>/launch-treatment-session.sh)")
21
+ .option("--seed <file>", "Path to the session seed to read/generate (default: <apply-dir>/session-seed.md)")
22
+ .option("--project-dir <dir>", "Project directory the launched session runs in (default: current directory)")
23
+ .action(async (options) => {
24
+ await runEngineCommand(async () => {
25
+ // The treatment-session launcher is internal methodology (engine). Lazy-load it; degrades
26
+ // honestly when the engine build is excluded from the package.
27
+ const { prepareTreatmentSessionLauncher } = await import("../../engine/treatment-session-launcher.js");
28
+ console.log(chalk.cyan("compaction launch-treatment-session (Lane B treatment setup)"));
29
+ console.log("Operator-invoked, NOT auto-apply. This command only WRITES a launch script; it starts no session and spawns no process. No provider call, no network.");
30
+ const result = await prepareTreatmentSessionLauncher({
31
+ applyDir: options.applyDir,
32
+ outScript: options.out,
33
+ seedFile: options.seed,
34
+ projectDir: options.projectDir
35
+ });
36
+ if (result.refused) {
37
+ console.error(chalk.red("Refused — no launch script written:"));
38
+ for (const reason of result.reasons) {
39
+ console.error(chalk.red(`- ${reason}`));
40
+ }
41
+ process.exitCode = 1;
42
+ return;
43
+ }
44
+ console.log(result.consoleSummary);
45
+ console.log(chalk.green(`Wrote ${result.scriptPath}`));
46
+ console.log(chalk.yellow(`Run it yourself when ready: bash ${result.scriptPath}`));
47
+ });
48
+ });
49
+ }
50
+ //# sourceMappingURL=launch-treatment-session.js.map
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerOptimizeCommand(program: Command): void;
@@ -0,0 +1,33 @@
1
+ import chalk from "chalk";
2
+ import { runEngineCommand } from "../engine-degrade.js";
3
+ export function registerOptimizeCommand(program) {
4
+ const optimize = program.command("optimize").description("Run local trace optimization loops for supported integrations.");
5
+ optimize
6
+ .command("openai-agents")
7
+ .description("Capture and optimize a local OpenAI Agents SDK trace without applying changes.")
8
+ .requiredOption("--out <dir>", "Output root directory for optimization artifacts")
9
+ .argument("[commandParts...]", "Command and arguments to execute after --")
10
+ .allowUnknownOption(true)
11
+ .action(async (commandParts, options) => {
12
+ await runEngineCommand(async () => {
13
+ // Lazy-load the proprietary engine: present in-repo/API, excluded from the public package.
14
+ // When absent, runEngineCommand prints the boundary message and exits cleanly (no stack trace).
15
+ const { optimizeOpenAIAgents } = await import("../../engine/openai-agents-optimization.js");
16
+ console.log(chalk.cyan("compaction optimize openai-agents"));
17
+ console.log("Running a local OpenAI Agents SDK optimization loop. No auto-apply, ChatGPT scraping, production proxying, or hosted upload is performed.");
18
+ const artifacts = await optimizeOpenAIAgents({ outRoot: options.out, commandParts });
19
+ if (artifacts.usedLocalFixture) {
20
+ console.log("Using local fixture because provider credentials are not configured.");
21
+ }
22
+ console.log(artifacts.terminalSummary);
23
+ console.log(chalk.green(`Wrote ${artifacts.paths.capturedTracePath}`));
24
+ console.log(chalk.green(`Wrote ${artifacts.paths.optimizationSummaryJsonPath}`));
25
+ console.log(chalk.green(`Wrote ${artifacts.paths.optimizationSummaryMarkdownPath}`));
26
+ console.log(chalk.green(`Evidence directory: ${artifacts.outputDirectory}`));
27
+ if (artifacts.summary.status === "fail") {
28
+ process.exitCode = 1;
29
+ }
30
+ });
31
+ });
32
+ }
33
+ //# sourceMappingURL=optimize.js.map
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ import type { RecommendationReport } from "../../engine/recommendation.js";
3
+ export declare function formatRecommendationConsoleSummary(recommendation: RecommendationReport, futureModesNotice: string): string;
4
+ export declare function registerRecommendCommand(program: Command): void;
@@ -0,0 +1,66 @@
1
+ import chalk from "chalk";
2
+ import { createSafetyReport } from "../../core/safety-report.js";
3
+ import { parseTraceFile } from "../../core/trace-parser.js";
4
+ import { detectWaste } from "../../core/waste-detector.js";
5
+ import { runEngineCommand } from "../engine-degrade.js";
6
+ function formatNullable(value) {
7
+ return value ?? "None";
8
+ }
9
+ export function formatRecommendationConsoleSummary(recommendation, futureModesNotice) {
10
+ return [
11
+ `Trace id: ${recommendation.trace_id}`,
12
+ `Recommended mode: ${recommendation.recommended_mode}`,
13
+ `Policy name: ${formatNullable(recommendation.policy_name)}`,
14
+ `Policy-level tokens saved: ${recommendation.tokens_saved} (${recommendation.percent_reduction}% reduction), $${recommendation.saving_per_run} per run.`,
15
+ `Safety status: ${recommendation.safety_status}`,
16
+ `Risk level: ${recommendation.risk_level}`,
17
+ `Required next step: ${recommendation.required_next_step}`,
18
+ "Future modes notice:",
19
+ futureModesNotice
20
+ ].join("\n");
21
+ }
22
+ export function registerRecommendCommand(program) {
23
+ program
24
+ .command("recommend")
25
+ .argument("<trace-file>", "Path to a local agent trace JSON file")
26
+ .description("Recommend an advisory local compaction mode and write recommendation artifacts.")
27
+ .action(async (traceFile) => {
28
+ await runEngineCommand(async () => {
29
+ // Lazy-load the proprietary engine: present in-repo/API, excluded from the public package.
30
+ // When absent, runEngineCommand prints the boundary message and exits cleanly (no stack trace).
31
+ const { applyCompactionPolicy } = await import("../../engine/policy-middleware.js");
32
+ const { createRecommendation } = await import("../../engine/recommendation.js");
33
+ const { formatFutureModesNotice, writeRecommendationArtifacts } = await import("../../engine/recommendation-artifacts.js");
34
+ const trace = await parseTraceFile(traceFile);
35
+ const findings = detectWaste(trace);
36
+ const policyResult = applyCompactionPolicy({ trace });
37
+ const safetyReport = createSafetyReport({
38
+ runId: trace.id,
39
+ generatedAt: trace.generatedAt,
40
+ originalTrace: trace,
41
+ compactedMessages: policyResult.compactedMessages,
42
+ stateCapsules: policyResult.stateCapsules,
43
+ compactedMessageIds: policyResult.compactedMessageIds,
44
+ tokensSaved: policyResult.tokensSaved,
45
+ policyName: policyResult.appliedPolicyName
46
+ });
47
+ const recommendation = createRecommendation({
48
+ trace,
49
+ policyResult,
50
+ generatedAt: trace.generatedAt,
51
+ safetyReport,
52
+ findings
53
+ });
54
+ const artifacts = await writeRecommendationArtifacts(recommendation);
55
+ console.log(chalk.cyan("compaction recommend"));
56
+ console.log(formatRecommendationConsoleSummary(recommendation, formatFutureModesNotice()));
57
+ console.log(chalk.green(`Wrote ${artifacts.paths.recommendationJsonPath}`));
58
+ console.log(chalk.green(`Wrote ${artifacts.paths.recommendationMarkdownPath}`));
59
+ // Exact next command to continue the loop (chaining), with the trace path the user passed.
60
+ console.log("");
61
+ console.log(chalk.bold("Next: produce the before/after delta + named policy + safety report:"));
62
+ console.log(` compaction compact ${traceFile} --out <dir>`);
63
+ });
64
+ });
65
+ }
66
+ //# sourceMappingURL=recommend.js.map
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerReviewCommand(program: Command): void;
@@ -0,0 +1,60 @@
1
+ import readline from "node:readline/promises";
2
+ import { stdin as input, stdout as output } from "node:process";
3
+ import chalk from "chalk";
4
+ import { runEngineCommand } from "../engine-degrade.js";
5
+ async function confirmApproval() {
6
+ const rl = readline.createInterface({ input, output });
7
+ try {
8
+ const answer = await rl.question("Approve this optimization? Type yes to approve: ");
9
+ return answer.trim().toLowerCase() === "yes";
10
+ }
11
+ finally {
12
+ rl.close();
13
+ }
14
+ }
15
+ export function registerReviewCommand(program) {
16
+ program
17
+ .command("review")
18
+ .description("Run a guided local optimization review with spend, safety, recommendation, and explicit approval decision.")
19
+ .argument("<optimization-or-spend-path>", "Path to an optimization summary, spend summary, recommendation, or approval-ready artifact")
20
+ .option("--require-safety-pass", "Refuse approval unless safety status is pass")
21
+ .option("--approve", "Request explicit local approval from the guided review")
22
+ .option("--yes", "Approve without an interactive confirmation prompt when all guardrails pass")
23
+ .action(async (sourcePath, options) => {
24
+ await runEngineCommand(async () => {
25
+ // Lazy-load the proprietary engine BEFORE any interactive prompt: present in-repo/API, excluded
26
+ // from the public package. When absent, runEngineCommand prints the boundary message and exits
27
+ // cleanly (no stack trace) without ever prompting for approval.
28
+ const { createOptimizationReview } = await import("../../engine/optimization-review.js");
29
+ console.log(chalk.cyan("compaction review"));
30
+ console.log("Guided local review only. No provider APIs, live provider mutation, production proxying, auto mode, model routing, hosted dashboard, auth, database, or billing workflow is used.");
31
+ const approvalRequested = Boolean(options.approve);
32
+ const approvalConfirmed = approvalRequested && (Boolean(options.yes) || (await confirmApproval()));
33
+ const artifacts = await createOptimizationReview({
34
+ sourceArtifactPath: sourcePath,
35
+ requireSafetyPass: Boolean(options.requireSafetyPass),
36
+ approvalRequested,
37
+ approvalConfirmed
38
+ });
39
+ console.log(artifacts.terminalSummary);
40
+ if (artifacts.paths.reviewSummaryJsonPath) {
41
+ console.log(chalk.green(`Wrote ${artifacts.paths.reviewSummaryJsonPath}`));
42
+ }
43
+ if (artifacts.paths.reviewSummaryMarkdownPath) {
44
+ console.log(chalk.green(`Wrote ${artifacts.paths.reviewSummaryMarkdownPath}`));
45
+ }
46
+ if (artifacts.approvalArtifacts) {
47
+ console.log(chalk.green(`Wrote ${artifacts.approvalArtifacts.paths.approvalReportJsonPath}`));
48
+ console.log(chalk.green(`Wrote ${artifacts.approvalArtifacts.paths.approvalReportMarkdownPath}`));
49
+ if (artifacts.approvalArtifacts.paths.approvedTracePath) {
50
+ console.log(chalk.green(`Wrote ${artifacts.approvalArtifacts.paths.approvedTracePath}`));
51
+ }
52
+ }
53
+ console.log(chalk.green(`Evidence directory: ${artifacts.outputDirectory}`));
54
+ if (approvalRequested && artifacts.summary.approval_decision !== "approved") {
55
+ process.exitCode = 1;
56
+ }
57
+ });
58
+ });
59
+ }
60
+ //# sourceMappingURL=review.js.map
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerRunCommand(program: Command): void;
@@ -0,0 +1,49 @@
1
+ import chalk from "chalk";
2
+ import { parseRunCommand, executeLocalCommand, persistLocalCommandRun } from "../../core/command-runner.js";
3
+ import { writeJsonArtifact } from "../../core/artifact-writer.js";
4
+ import { localCommandRunToAgentTrace } from "../../core/run-trace-converter.js";
5
+ import { runEngineCommand } from "../engine-degrade.js";
6
+ export function registerRunCommand(program) {
7
+ program
8
+ .command("run")
9
+ .description("Run a local command, capture output locally, convert it to a trace, and write compaction artifacts.")
10
+ .argument("[commandParts...]", "Command and arguments to execute after --")
11
+ .allowUnknownOption(true)
12
+ .action(async (commandParts) => {
13
+ await runEngineCommand(async () => {
14
+ // `run`'s value IS the compaction report it produces, which needs the proprietary engine.
15
+ // Lazy-load it FIRST so a public install degrades immediately — before spawning the child
16
+ // command — rather than running the command and then failing to compact.
17
+ const { writeCompactionArtifacts } = await import("../../engine/compaction-artifacts.js");
18
+ const command = parseRunCommand(commandParts);
19
+ console.log(chalk.cyan("compaction run"));
20
+ console.log("Running local command and capturing stdout/stderr locally. Child output is not printed by compaction.");
21
+ const run = await executeLocalCommand(command);
22
+ const persistedRun = await persistLocalCommandRun(run);
23
+ const trace = localCommandRunToAgentTrace(run);
24
+ const tracePath = await writeJsonArtifact(persistedRun.outputDirectory, "trace.json", trace);
25
+ const artifacts = await writeCompactionArtifacts(trace, persistedRun.outputDirectory, run.runId);
26
+ console.log(`Exit code: ${run.exitCode ?? "none"}`);
27
+ console.log(`Signal: ${run.signal ?? "none"}`);
28
+ console.log(`Duration: ${run.durationMs} ms`);
29
+ console.log(chalk.green(`Wrote ${persistedRun.stdoutPath}`));
30
+ console.log(chalk.green(`Wrote ${persistedRun.stderrPath}`));
31
+ console.log(chalk.green(`Wrote ${persistedRun.rawOutputPath}`));
32
+ console.log(chalk.green(`Wrote ${persistedRun.metadataPath}`));
33
+ console.log(chalk.green(`Wrote ${tracePath}`));
34
+ console.log(artifacts.consoleReport);
35
+ console.log(chalk.green(`Wrote ${artifacts.paths.reportPath}`));
36
+ console.log(chalk.green(`Wrote ${artifacts.paths.markdownReportPath}`));
37
+ console.log(chalk.green(`Wrote ${artifacts.paths.policyPath}`));
38
+ console.log(chalk.green(`Wrote ${artifacts.paths.capsulePath}`));
39
+ console.log(chalk.green(`Wrote ${artifacts.paths.compactedTracePath}`));
40
+ console.log(chalk.green(`Wrote ${artifacts.paths.safetyReportPath}`));
41
+ console.log(chalk.green(`Wrote ${artifacts.paths.safetyMarkdownReportPath}`));
42
+ console.log(chalk.green(`Wrote ${artifacts.paths.prCommentReportPath}`));
43
+ if (run.exitCode !== 0 && run.exitCode !== null) {
44
+ process.exitCode = run.exitCode;
45
+ }
46
+ });
47
+ });
48
+ }
49
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerSpendCommand(program: Command): void;
@@ -0,0 +1,24 @@
1
+ import chalk from "chalk";
2
+ import { writeSpendArtifacts, loadEngineOptimizationDeltaProvider } from "../../core/spend-attribution.js";
3
+ export function registerSpendCommand(program) {
4
+ program
5
+ .command("spend")
6
+ .description("Summarize local context spend attribution and optimization delta for a trace or optimization summary.")
7
+ .argument("<trace-or-optimization-path>", "Path to a local agent trace JSON or optimization-summary.json")
8
+ .option("--out <dir>", "Output root directory for spend artifacts", ".compaction/spend")
9
+ .action(async (inputPath, options) => {
10
+ // `spend` is a FREE command: local token/cost attribution + waste/skill-injection always work
11
+ // WITHOUT the engine. The engine optimization-delta provider is loaded only if a private engine
12
+ // build is present; in a public install it resolves to null and the optimization-delta section
13
+ // degrades honestly (no policy candidate, no synthetic saving). The command never crashes here.
14
+ console.log(chalk.cyan("compaction spend"));
15
+ console.log("Summarizing local context spend attribution. No provider APIs, billing lookup, auto mode, model routing, or hosted dashboard is used.");
16
+ const optimizationDeltaProvider = (await loadEngineOptimizationDeltaProvider()) ?? undefined;
17
+ const artifacts = await writeSpendArtifacts(inputPath, options.out, undefined, optimizationDeltaProvider);
18
+ console.log(artifacts.terminalSummary);
19
+ console.log(chalk.green(`Wrote ${artifacts.paths.spendSummaryJsonPath}`));
20
+ console.log(chalk.green(`Wrote ${artifacts.paths.spendSummaryMarkdownPath}`));
21
+ console.log(chalk.green(`Evidence directory: ${artifacts.outputDirectory}`));
22
+ });
23
+ }
24
+ //# sourceMappingURL=spend.js.map
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerSummaryCommand(program: Command): void;
@@ -0,0 +1,19 @@
1
+ import chalk from "chalk";
2
+ import { writeJsonArtifact, writeTextArtifact } from "../../core/artifact-writer.js";
3
+ import { createRunSummary, formatRunSummary, formatRunSummaryMarkdown } from "../../core/run-aggregator.js";
4
+ export function registerSummaryCommand(program) {
5
+ program
6
+ .command("summary")
7
+ .description("Summarize local compaction run reports across .compaction/runs/*/report.json.")
8
+ .action(async () => {
9
+ const summary = await createRunSummary();
10
+ const consoleSummary = formatRunSummary(summary);
11
+ const markdownSummary = formatRunSummaryMarkdown(summary);
12
+ const summaryJsonPath = await writeJsonArtifact(".compaction", "summary.json", summary);
13
+ const summaryMarkdownPath = await writeTextArtifact(".compaction", "summary.md", markdownSummary);
14
+ console.log(chalk.cyan(consoleSummary));
15
+ console.log(chalk.green(`Wrote ${summaryJsonPath}`));
16
+ console.log(chalk.green(`Wrote ${summaryMarkdownPath}`));
17
+ });
18
+ }
19
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Open-core public/proprietary boundary (Phase 1c/1d).
3
+ *
4
+ * The proprietary optimization/eval engine lives in `src/engine/**` and is BUILT into
5
+ * `dist/engine/**` for the in-repo dev/test/API build, but is EXCLUDED from the published
6
+ * npm tarball (see `package.json` `files`). Shipped modules must therefore never STATICALLY
7
+ * `import` an engine module — doing so would (a) pull engine code into the published static
8
+ * graph and (b) crash a public install at module-load time.
9
+ *
10
+ * Engine-backed CLI commands instead LAZY-LOAD their engine module through a dynamic `import()`
11
+ * (which is NOT part of the static import graph). When the engine build is present (in-repo) the
12
+ * command runs normally. When it is ABSENT (public install) the dynamic import throws
13
+ * `ERR_MODULE_NOT_FOUND`; `runEngineCommand()` catches that, prints the single sanctioned
14
+ * boundary message, exits non-zero, and prints NO stack trace and NO engine output. Any OTHER
15
+ * error (a real bug inside a present engine) is re-thrown unchanged.
16
+ */
17
+ /**
18
+ * The EXACT, single sanctioned degrade message. Product-critic reviewed (Phase 1c/1d):
19
+ * it names the boundary factually and immediately reaffirms what stays free. Do not fork
20
+ * per-command variants of this string.
21
+ */
22
+ export declare const ENGINE_DEGRADE_MESSAGE: string;
23
+ /**
24
+ * True when `error` is the Node "module not found" thrown by a dynamic `import()` of an
25
+ * engine module that was excluded from the published package (vs. a real runtime error
26
+ * raised from inside an engine module that IS present).
27
+ */
28
+ export declare function isEngineAbsentError(error: unknown): boolean;
29
+ /**
30
+ * Run an engine-backed command body. If the engine build is absent (public install), print
31
+ * the sanctioned boundary message to stderr, set a non-zero exit code, and return WITHOUT a
32
+ * stack trace. Any other error propagates unchanged so real bugs are never masked.
33
+ *
34
+ * Usage:
35
+ * await runEngineCommand(async () => {
36
+ * const { optimizeOpenAIAgents } = await import("../../engine/openai-agents-optimization.js");
37
+ * // ...use it...
38
+ * });
39
+ */
40
+ export declare function runEngineCommand(body: () => Promise<void>): Promise<void>;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Open-core public/proprietary boundary (Phase 1c/1d).
3
+ *
4
+ * The proprietary optimization/eval engine lives in `src/engine/**` and is BUILT into
5
+ * `dist/engine/**` for the in-repo dev/test/API build, but is EXCLUDED from the published
6
+ * npm tarball (see `package.json` `files`). Shipped modules must therefore never STATICALLY
7
+ * `import` an engine module — doing so would (a) pull engine code into the published static
8
+ * graph and (b) crash a public install at module-load time.
9
+ *
10
+ * Engine-backed CLI commands instead LAZY-LOAD their engine module through a dynamic `import()`
11
+ * (which is NOT part of the static import graph). When the engine build is present (in-repo) the
12
+ * command runs normally. When it is ABSENT (public install) the dynamic import throws
13
+ * `ERR_MODULE_NOT_FOUND`; `runEngineCommand()` catches that, prints the single sanctioned
14
+ * boundary message, exits non-zero, and prints NO stack trace and NO engine output. Any OTHER
15
+ * error (a real bug inside a present engine) is re-thrown unchanged.
16
+ */
17
+ /**
18
+ * The EXACT, single sanctioned degrade message. Product-critic reviewed (Phase 1c/1d):
19
+ * it names the boundary factually and immediately reaffirms what stays free. Do not fork
20
+ * per-command variants of this string.
21
+ */
22
+ export const ENGINE_DEGRADE_MESSAGE = "Optimization and stronger evals require Compaction API or a private engine build. " +
23
+ "Local capture, measurement, reports, and redacted share bundles remain available.";
24
+ /**
25
+ * True when `error` is the Node "module not found" thrown by a dynamic `import()` of an
26
+ * engine module that was excluded from the published package (vs. a real runtime error
27
+ * raised from inside an engine module that IS present).
28
+ */
29
+ export function isEngineAbsentError(error) {
30
+ if (!error || typeof error !== "object")
31
+ return false;
32
+ const code = error.code;
33
+ return code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND";
34
+ }
35
+ /**
36
+ * Run an engine-backed command body. If the engine build is absent (public install), print
37
+ * the sanctioned boundary message to stderr, set a non-zero exit code, and return WITHOUT a
38
+ * stack trace. Any other error propagates unchanged so real bugs are never masked.
39
+ *
40
+ * Usage:
41
+ * await runEngineCommand(async () => {
42
+ * const { optimizeOpenAIAgents } = await import("../../engine/openai-agents-optimization.js");
43
+ * // ...use it...
44
+ * });
45
+ */
46
+ export async function runEngineCommand(body) {
47
+ try {
48
+ await body();
49
+ }
50
+ catch (error) {
51
+ if (isEngineAbsentError(error)) {
52
+ process.stderr.write(`${ENGINE_DEGRADE_MESSAGE}\n`);
53
+ process.exitCode = 1;
54
+ return;
55
+ }
56
+ throw error;
57
+ }
58
+ }
59
+ //# sourceMappingURL=engine-degrade.js.map
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { registerAnalyzeCommand } from "./commands/analyze.js";
4
+ import { registerAdapterCommand } from "./commands/adapter.js";
5
+ import { registerAggregateCommand } from "./commands/aggregate.js";
6
+ import { registerAuditCommand } from "./commands/audit.js";
7
+ import { registerApplyCommand } from "./commands/apply.js";
8
+ import { registerApplyContextCommand } from "./commands/apply-context.js";
9
+ import { registerApproveCommand } from "./commands/approve.js";
10
+ import { registerBillingDeltaCommand } from "./commands/billing-delta.js";
11
+ import { registerInitCommand } from "./commands/init.js";
12
+ import { registerCaptureCommand } from "./commands/capture.js";
13
+ import { registerCompactCommand } from "./commands/compact.js";
14
+ import { registerEvalCommand } from "./commands/eval.js";
15
+ import { registerExportSessionSeedCommand } from "./commands/export-session-seed.js";
16
+ import { registerFeedbackCommand } from "./commands/feedback.js";
17
+ import { registerImportCommand } from "./commands/import.js";
18
+ import { registerIntegrationsCommand } from "./commands/integrations.js";
19
+ import { registerLaunchTreatmentSessionCommand } from "./commands/launch-treatment-session.js";
20
+ import { registerOptimizeCommand } from "./commands/optimize.js";
21
+ import { registerRecommendCommand } from "./commands/recommend.js";
22
+ import { registerReviewCommand } from "./commands/review.js";
23
+ import { registerRunCommand } from "./commands/run.js";
24
+ import { registerSpendCommand } from "./commands/spend.js";
25
+ import { registerSummaryCommand } from "./commands/summary.js";
26
+ const program = new Command();
27
+ program
28
+ .name("compaction")
29
+ .description("CLI-first trace compaction tools for AI agent workflows.")
30
+ .version("0.1.0");
31
+ registerAnalyzeCommand(program);
32
+ registerAdapterCommand(program);
33
+ registerAggregateCommand(program);
34
+ registerAuditCommand(program);
35
+ registerApplyCommand(program);
36
+ registerApplyContextCommand(program);
37
+ registerApproveCommand(program);
38
+ registerBillingDeltaCommand(program);
39
+ registerInitCommand(program);
40
+ registerCaptureCommand(program);
41
+ registerCompactCommand(program);
42
+ registerEvalCommand(program);
43
+ registerExportSessionSeedCommand(program);
44
+ registerFeedbackCommand(program);
45
+ registerImportCommand(program);
46
+ registerIntegrationsCommand(program);
47
+ registerLaunchTreatmentSessionCommand(program);
48
+ registerOptimizeCommand(program);
49
+ registerRecommendCommand(program);
50
+ registerReviewCommand(program);
51
+ registerRunCommand(program);
52
+ registerSpendCommand(program);
53
+ registerSummaryCommand(program);
54
+ program.parseAsync(process.argv).catch((error) => {
55
+ const message = error instanceof Error ? error.message : String(error);
56
+ console.error(message);
57
+ process.exitCode = 1;
58
+ });
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,32 @@
1
+ import { type TraceAdapterSource, type TraceAdapterStatus } from "./trace-adapters.js";
2
+ import type { AgentTrace } from "./types.js";
3
+ export type AdapterValidationSource = TraceAdapterSource;
4
+ export type AdapterValidationStatus = TraceAdapterStatus;
5
+ export interface AdapterValidationReport {
6
+ validation_id: string;
7
+ generated_at: string;
8
+ input_path: string;
9
+ source: AdapterValidationSource;
10
+ adapter_id: AdapterValidationSource;
11
+ status: AdapterValidationStatus;
12
+ output_trace_id: string | null;
13
+ message_count: number;
14
+ supported_format_detected: boolean;
15
+ warnings: string[];
16
+ failures: string[];
17
+ normalization_steps: string[];
18
+ skipped_fields: string[];
19
+ limitations: string[];
20
+ recommended_next_command: string | null;
21
+ }
22
+ export interface AdapterValidationArtifacts {
23
+ report: AdapterValidationReport;
24
+ normalizedTrace: AgentTrace | null;
25
+ paths: {
26
+ outputDirectory: string;
27
+ normalizedTracePath: string;
28
+ validationReportJsonPath: string;
29
+ validationReportMarkdownPath: string;
30
+ };
31
+ }
32
+ export declare function validateAdapterFixtureFile(inputPath: string, source: string, outputRoot?: string): Promise<AdapterValidationArtifacts>;