@codemieai/code 0.0.16 → 0.0.18
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/README.md +62 -5
- package/bin/agent-executor.js +7 -28
- package/bin/codemie-claude.js +18 -0
- package/bin/codemie-codex.js +18 -0
- package/bin/codemie-deepagents.js +18 -0
- package/bin/codemie-gemini.js +18 -0
- package/dist/agents/codemie-code/agent.d.ts.map +1 -1
- package/dist/agents/codemie-code/agent.js +3 -32
- package/dist/agents/codemie-code/agent.js.map +1 -1
- package/dist/agents/codemie-code/tools/planning.d.ts +2 -2
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +31 -62
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts +9 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +125 -10
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/core/BaseMetricsAdapter.d.ts +64 -0
- package/dist/agents/core/BaseMetricsAdapter.d.ts.map +1 -0
- package/dist/agents/core/BaseMetricsAdapter.js +74 -0
- package/dist/agents/core/BaseMetricsAdapter.js.map +1 -0
- package/dist/agents/core/types.d.ts +1 -0
- package/dist/agents/core/types.d.ts.map +1 -1
- package/dist/agents/plugins/claude.metrics.d.ts +112 -0
- package/dist/agents/plugins/claude.metrics.d.ts.map +1 -0
- package/dist/agents/plugins/claude.metrics.js +700 -0
- package/dist/agents/plugins/claude.metrics.js.map +1 -0
- package/dist/agents/plugins/claude.plugin.d.ts +9 -0
- package/dist/agents/plugins/claude.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/claude.plugin.js +52 -10
- package/dist/agents/plugins/claude.plugin.js.map +1 -1
- package/dist/agents/plugins/codemie-code.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/codemie-code.plugin.js +57 -13
- package/dist/agents/plugins/codemie-code.plugin.js.map +1 -1
- package/dist/agents/plugins/codex.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/codex.plugin.js +1 -3
- package/dist/agents/plugins/codex.plugin.js.map +1 -1
- package/dist/agents/plugins/gemini.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/gemini.plugin.js +0 -7
- package/dist/agents/plugins/gemini.plugin.js.map +1 -1
- package/dist/agents/plugins/history-parser.d.ts +52 -0
- package/dist/agents/plugins/history-parser.d.ts.map +1 -0
- package/dist/agents/plugins/history-parser.js +155 -0
- package/dist/agents/plugins/history-parser.js.map +1 -0
- package/dist/cli/commands/analytics/aggregator.d.ts +58 -0
- package/dist/cli/commands/analytics/aggregator.d.ts.map +1 -0
- package/dist/cli/commands/analytics/aggregator.js +702 -0
- package/dist/cli/commands/analytics/aggregator.js.map +1 -0
- package/dist/cli/commands/analytics/data-loader.d.ts +84 -0
- package/dist/cli/commands/analytics/data-loader.d.ts.map +1 -0
- package/dist/cli/commands/analytics/data-loader.js +211 -0
- package/dist/cli/commands/analytics/data-loader.js.map +1 -0
- package/dist/cli/commands/analytics/exporter.d.ts +20 -0
- package/dist/cli/commands/analytics/exporter.d.ts.map +1 -0
- package/dist/cli/commands/analytics/exporter.js +103 -0
- package/dist/cli/commands/analytics/exporter.js.map +1 -0
- package/dist/cli/commands/analytics/formatter.d.ts +49 -0
- package/dist/cli/commands/analytics/formatter.d.ts.map +1 -0
- package/dist/cli/commands/analytics/formatter.js +309 -0
- package/dist/cli/commands/analytics/formatter.js.map +1 -0
- package/dist/cli/commands/analytics/index.d.ts +6 -0
- package/dist/cli/commands/analytics/index.d.ts.map +1 -0
- package/dist/cli/commands/analytics/index.js +157 -0
- package/dist/cli/commands/analytics/index.js.map +1 -0
- package/dist/cli/commands/analytics/model-normalizer.d.ts +21 -0
- package/dist/cli/commands/analytics/model-normalizer.d.ts.map +1 -0
- package/dist/cli/commands/analytics/model-normalizer.js +44 -0
- package/dist/cli/commands/analytics/model-normalizer.js.map +1 -0
- package/dist/cli/commands/analytics/types.d.ts +188 -0
- package/dist/cli/commands/analytics/types.d.ts.map +1 -0
- package/dist/cli/commands/analytics/types.js +6 -0
- package/dist/cli/commands/analytics/types.js.map +1 -0
- package/dist/cli/commands/doctor/checks/AwsCliCheck.d.ts +9 -0
- package/dist/cli/commands/doctor/checks/AwsCliCheck.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/AwsCliCheck.js +28 -0
- package/dist/cli/commands/doctor/checks/AwsCliCheck.js.map +1 -0
- package/dist/cli/commands/doctor/checks/PythonCheck.d.ts.map +1 -1
- package/dist/cli/commands/doctor/checks/PythonCheck.js +10 -0
- package/dist/cli/commands/doctor/checks/PythonCheck.js.map +1 -1
- package/dist/cli/commands/doctor/checks/WorkflowsCheck.d.ts.map +1 -1
- package/dist/cli/commands/doctor/checks/WorkflowsCheck.js +2 -1
- package/dist/cli/commands/doctor/checks/WorkflowsCheck.js.map +1 -1
- package/dist/cli/commands/doctor/checks/index.d.ts +1 -0
- package/dist/cli/commands/doctor/checks/index.d.ts.map +1 -1
- package/dist/cli/commands/doctor/checks/index.js +1 -0
- package/dist/cli/commands/doctor/checks/index.js.map +1 -1
- package/dist/cli/commands/doctor/index.d.ts.map +1 -1
- package/dist/cli/commands/doctor/index.js +75 -3
- package/dist/cli/commands/doctor/index.js.map +1 -1
- package/dist/cli/commands/profile.d.ts.map +1 -1
- package/dist/cli/commands/profile.js +49 -89
- package/dist/cli/commands/profile.js.map +1 -1
- package/dist/cli/commands/setup.js +1 -21
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/env/types.d.ts +14 -2
- package/dist/env/types.d.ts.map +1 -1
- package/dist/env/types.js.map +1 -1
- package/dist/metrics/MetricsOrchestrator.d.ts +67 -0
- package/dist/metrics/MetricsOrchestrator.d.ts.map +1 -0
- package/dist/metrics/MetricsOrchestrator.js +287 -0
- package/dist/metrics/MetricsOrchestrator.js.map +1 -0
- package/dist/metrics/config.d.ts +38 -0
- package/dist/metrics/config.d.ts.map +1 -0
- package/dist/metrics/config.js +80 -0
- package/dist/metrics/config.js.map +1 -0
- package/dist/metrics/core/DeltaWriter.d.ts +49 -0
- package/dist/metrics/core/DeltaWriter.d.ts.map +1 -0
- package/dist/metrics/core/DeltaWriter.js +146 -0
- package/dist/metrics/core/DeltaWriter.js.map +1 -0
- package/dist/metrics/core/FileSnapshotter.d.ts +22 -0
- package/dist/metrics/core/FileSnapshotter.d.ts.map +1 -0
- package/dist/metrics/core/FileSnapshotter.js +74 -0
- package/dist/metrics/core/FileSnapshotter.js.map +1 -0
- package/dist/metrics/core/SessionCorrelator.d.ts +34 -0
- package/dist/metrics/core/SessionCorrelator.d.ts.map +1 -0
- package/dist/metrics/core/SessionCorrelator.js +115 -0
- package/dist/metrics/core/SessionCorrelator.js.map +1 -0
- package/dist/metrics/core/SyncStateManager.d.ts +69 -0
- package/dist/metrics/core/SyncStateManager.d.ts.map +1 -0
- package/dist/metrics/core/SyncStateManager.js +284 -0
- package/dist/metrics/core/SyncStateManager.js.map +1 -0
- package/dist/metrics/index.d.ts +9 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +11 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/session/SessionStore.d.ts +43 -0
- package/dist/metrics/session/SessionStore.d.ts.map +1 -0
- package/dist/metrics/session/SessionStore.js +142 -0
- package/dist/metrics/session/SessionStore.js.map +1 -0
- package/dist/metrics/sync/MetricsApiClient.d.ts +32 -0
- package/dist/metrics/sync/MetricsApiClient.d.ts.map +1 -0
- package/dist/metrics/sync/MetricsApiClient.js +155 -0
- package/dist/metrics/sync/MetricsApiClient.js.map +1 -0
- package/dist/metrics/sync/aggregator.d.ts +14 -0
- package/dist/metrics/sync/aggregator.d.ts.map +1 -0
- package/dist/metrics/sync/aggregator.js +214 -0
- package/dist/metrics/sync/aggregator.js.map +1 -0
- package/dist/metrics/sync/index.d.ts +10 -0
- package/dist/metrics/sync/index.d.ts.map +1 -0
- package/dist/metrics/sync/index.js +10 -0
- package/dist/metrics/sync/index.js.map +1 -0
- package/dist/metrics/sync/jsonl-writer.d.ts +28 -0
- package/dist/metrics/sync/jsonl-writer.d.ts.map +1 -0
- package/dist/metrics/sync/jsonl-writer.js +72 -0
- package/dist/metrics/sync/jsonl-writer.js.map +1 -0
- package/dist/metrics/sync/types.d.ts +73 -0
- package/dist/metrics/sync/types.d.ts.map +1 -0
- package/dist/metrics/sync/types.js +7 -0
- package/dist/metrics/sync/types.js.map +1 -0
- package/dist/metrics/types.d.ts +308 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +8 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/integration/setup-ui.d.ts +1 -1
- package/dist/providers/integration/setup-ui.d.ts.map +1 -1
- package/dist/providers/integration/setup-ui.js +51 -6
- package/dist/providers/integration/setup-ui.js.map +1 -1
- package/dist/providers/plugins/bedrock/bedrock.health.d.ts +53 -0
- package/dist/providers/plugins/bedrock/bedrock.health.d.ts.map +1 -0
- package/dist/providers/plugins/bedrock/bedrock.health.js +115 -0
- package/dist/providers/plugins/bedrock/bedrock.health.js.map +1 -0
- package/dist/providers/plugins/bedrock/bedrock.models.d.ts +26 -0
- package/dist/providers/plugins/bedrock/bedrock.models.d.ts.map +1 -0
- package/dist/providers/plugins/bedrock/bedrock.models.js +89 -0
- package/dist/providers/plugins/bedrock/bedrock.models.js.map +1 -0
- package/dist/providers/plugins/bedrock/bedrock.setup-steps.d.ts +12 -0
- package/dist/providers/plugins/bedrock/bedrock.setup-steps.d.ts.map +1 -0
- package/dist/providers/plugins/bedrock/bedrock.setup-steps.js +308 -0
- package/dist/providers/plugins/bedrock/bedrock.setup-steps.js.map +1 -0
- package/dist/providers/plugins/bedrock/bedrock.template.d.ts +11 -0
- package/dist/providers/plugins/bedrock/bedrock.template.d.ts.map +1 -0
- package/dist/providers/plugins/bedrock/bedrock.template.js +85 -0
- package/dist/providers/plugins/bedrock/bedrock.template.js.map +1 -0
- package/dist/providers/plugins/bedrock/index.d.ts +11 -0
- package/dist/providers/plugins/bedrock/index.d.ts.map +1 -0
- package/dist/providers/plugins/bedrock/index.js +11 -0
- package/dist/providers/plugins/bedrock/index.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.template.d.ts.map +1 -1
- package/dist/providers/plugins/ollama/ollama.template.js +2 -0
- package/dist/providers/plugins/ollama/ollama.template.js.map +1 -1
- package/dist/providers/plugins/sso/sso.http-client.d.ts +2 -0
- package/dist/providers/plugins/sso/sso.http-client.d.ts.map +1 -1
- package/dist/providers/plugins/sso/sso.http-client.js +9 -3
- package/dist/providers/plugins/sso/sso.http-client.js.map +1 -1
- package/dist/proxy/http-client.d.ts +1 -1
- package/dist/proxy/http-client.d.ts.map +1 -1
- package/dist/proxy/http-client.js +78 -12
- package/dist/proxy/http-client.js.map +1 -1
- package/dist/proxy/plugins/endpoint-blocker.plugin.d.ts +19 -0
- package/dist/proxy/plugins/endpoint-blocker.plugin.d.ts.map +1 -0
- package/dist/proxy/plugins/endpoint-blocker.plugin.js +61 -0
- package/dist/proxy/plugins/endpoint-blocker.plugin.js.map +1 -0
- package/dist/proxy/plugins/header-injection.plugin.js +3 -0
- package/dist/proxy/plugins/header-injection.plugin.js.map +1 -1
- package/dist/proxy/plugins/index.d.ts +3 -1
- package/dist/proxy/plugins/index.d.ts.map +1 -1
- package/dist/proxy/plugins/index.js +5 -1
- package/dist/proxy/plugins/index.js.map +1 -1
- package/dist/proxy/plugins/logging.plugin.d.ts +11 -3
- package/dist/proxy/plugins/logging.plugin.d.ts.map +1 -1
- package/dist/proxy/plugins/logging.plugin.js +189 -25
- package/dist/proxy/plugins/logging.plugin.js.map +1 -1
- package/dist/proxy/plugins/metrics-sync.plugin.d.ts +33 -0
- package/dist/proxy/plugins/metrics-sync.plugin.d.ts.map +1 -0
- package/dist/proxy/plugins/metrics-sync.plugin.js +320 -0
- package/dist/proxy/plugins/metrics-sync.plugin.js.map +1 -0
- package/dist/proxy/plugins/registry.d.ts.map +1 -1
- package/dist/proxy/plugins/registry.js +8 -1
- package/dist/proxy/plugins/registry.js.map +1 -1
- package/dist/proxy/plugins/types.d.ts +6 -2
- package/dist/proxy/plugins/types.d.ts.map +1 -1
- package/dist/proxy/types.d.ts +8 -1
- package/dist/proxy/types.d.ts.map +1 -1
- package/dist/utils/ascii-logo.d.ts +21 -0
- package/dist/utils/ascii-logo.d.ts.map +1 -0
- package/dist/utils/ascii-logo.js +85 -0
- package/dist/utils/ascii-logo.js.map +1 -0
- package/dist/utils/codemie-proxy.d.ts +2 -7
- package/dist/utils/codemie-proxy.d.ts.map +1 -1
- package/dist/utils/codemie-proxy.js +83 -61
- package/dist/utils/codemie-proxy.js.map +1 -1
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +22 -6
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/exec.d.ts +11 -0
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +17 -1
- package/dist/utils/exec.js.map +1 -1
- package/dist/utils/goodbye-messages.d.ts +13 -0
- package/dist/utils/goodbye-messages.d.ts.map +1 -0
- package/dist/utils/goodbye-messages.js +245 -0
- package/dist/utils/goodbye-messages.js.map +1 -0
- package/dist/utils/json-parser.d.ts +52 -0
- package/dist/utils/json-parser.d.ts.map +1 -0
- package/dist/utils/json-parser.js +126 -0
- package/dist/utils/json-parser.js.map +1 -0
- package/dist/utils/logger.d.ts +37 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +92 -20
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/sanitize.d.ts.map +1 -1
- package/dist/utils/sanitize.js +0 -1
- package/dist/utils/sanitize.js.map +1 -1
- package/dist/utils/which.d.ts +20 -0
- package/dist/utils/which.d.ts.map +1 -0
- package/dist/utils/which.js +47 -0
- package/dist/utils/which.js.map +1 -0
- package/package.json +10 -5
- package/dist/analytics/aggregation/adapters/claude.adapter.d.ts +0 -37
- package/dist/analytics/aggregation/adapters/claude.adapter.d.ts.map +0 -1
- package/dist/analytics/aggregation/adapters/claude.adapter.js +0 -531
- package/dist/analytics/aggregation/adapters/claude.adapter.js.map +0 -1
- package/dist/analytics/aggregation/adapters/codex.adapter.d.ts +0 -25
- package/dist/analytics/aggregation/adapters/codex.adapter.d.ts.map +0 -1
- package/dist/analytics/aggregation/adapters/codex.adapter.js +0 -396
- package/dist/analytics/aggregation/adapters/codex.adapter.js.map +0 -1
- package/dist/analytics/aggregation/adapters/gemini.adapter.d.ts +0 -36
- package/dist/analytics/aggregation/adapters/gemini.adapter.d.ts.map +0 -1
- package/dist/analytics/aggregation/adapters/gemini.adapter.js +0 -365
- package/dist/analytics/aggregation/adapters/gemini.adapter.js.map +0 -1
- package/dist/analytics/aggregation/adapters/index.d.ts +0 -7
- package/dist/analytics/aggregation/adapters/index.d.ts.map +0 -1
- package/dist/analytics/aggregation/adapters/index.js +0 -7
- package/dist/analytics/aggregation/adapters/index.js.map +0 -1
- package/dist/analytics/aggregation/aggregator.d.ts +0 -49
- package/dist/analytics/aggregation/aggregator.d.ts.map +0 -1
- package/dist/analytics/aggregation/aggregator.js +0 -239
- package/dist/analytics/aggregation/aggregator.js.map +0 -1
- package/dist/analytics/aggregation/core/BaseAnalyticsAdapter.d.ts +0 -99
- package/dist/analytics/aggregation/core/BaseAnalyticsAdapter.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/BaseAnalyticsAdapter.js +0 -110
- package/dist/analytics/aggregation/core/BaseAnalyticsAdapter.js.map +0 -1
- package/dist/analytics/aggregation/core/adapter.interface.d.ts +0 -76
- package/dist/analytics/aggregation/core/adapter.interface.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/adapter.interface.js +0 -9
- package/dist/analytics/aggregation/core/adapter.interface.js.map +0 -1
- package/dist/analytics/aggregation/core/aggregation-utils.d.ts +0 -86
- package/dist/analytics/aggregation/core/aggregation-utils.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/aggregation-utils.js +0 -126
- package/dist/analytics/aggregation/core/aggregation-utils.js.map +0 -1
- package/dist/analytics/aggregation/core/discovery.d.ts +0 -40
- package/dist/analytics/aggregation/core/discovery.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/discovery.js +0 -132
- package/dist/analytics/aggregation/core/discovery.js.map +0 -1
- package/dist/analytics/aggregation/core/file-utils.d.ts +0 -24
- package/dist/analytics/aggregation/core/file-utils.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/file-utils.js +0 -143
- package/dist/analytics/aggregation/core/file-utils.js.map +0 -1
- package/dist/analytics/aggregation/core/index.d.ts +0 -14
- package/dist/analytics/aggregation/core/index.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/index.js +0 -14
- package/dist/analytics/aggregation/core/index.js.map +0 -1
- package/dist/analytics/aggregation/core/project-mapping.d.ts +0 -50
- package/dist/analytics/aggregation/core/project-mapping.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/project-mapping.js +0 -102
- package/dist/analytics/aggregation/core/project-mapping.js.map +0 -1
- package/dist/analytics/aggregation/core/streaming.d.ts +0 -26
- package/dist/analytics/aggregation/core/streaming.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/streaming.js +0 -58
- package/dist/analytics/aggregation/core/streaming.js.map +0 -1
- package/dist/analytics/aggregation/core/user-prompt-source.d.ts +0 -81
- package/dist/analytics/aggregation/core/user-prompt-source.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/user-prompt-source.js +0 -69
- package/dist/analytics/aggregation/core/user-prompt-source.js.map +0 -1
- package/dist/analytics/aggregation/core/user-prompt-sources/json.d.ts +0 -49
- package/dist/analytics/aggregation/core/user-prompt-sources/json.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/user-prompt-sources/json.js +0 -66
- package/dist/analytics/aggregation/core/user-prompt-sources/json.js.map +0 -1
- package/dist/analytics/aggregation/core/user-prompt-sources/jsonl.d.ts +0 -43
- package/dist/analytics/aggregation/core/user-prompt-sources/jsonl.d.ts.map +0 -1
- package/dist/analytics/aggregation/core/user-prompt-sources/jsonl.js +0 -56
- package/dist/analytics/aggregation/core/user-prompt-sources/jsonl.js.map +0 -1
- package/dist/analytics/aggregation/index.d.ts +0 -8
- package/dist/analytics/aggregation/index.d.ts.map +0 -1
- package/dist/analytics/aggregation/index.js +0 -8
- package/dist/analytics/aggregation/index.js.map +0 -1
- package/dist/analytics/aggregation/types.d.ts +0 -278
- package/dist/analytics/aggregation/types.d.ts.map +0 -1
- package/dist/analytics/aggregation/types.js +0 -8
- package/dist/analytics/aggregation/types.js.map +0 -1
- package/dist/analytics/collector.d.ts +0 -46
- package/dist/analytics/collector.d.ts.map +0 -1
- package/dist/analytics/collector.js +0 -83
- package/dist/analytics/collector.js.map +0 -1
- package/dist/analytics/config.d.ts +0 -15
- package/dist/analytics/config.d.ts.map +0 -1
- package/dist/analytics/config.js +0 -65
- package/dist/analytics/config.js.map +0 -1
- package/dist/analytics/index.d.ts +0 -99
- package/dist/analytics/index.d.ts.map +0 -1
- package/dist/analytics/index.js +0 -280
- package/dist/analytics/index.js.map +0 -1
- package/dist/analytics/plugins/api-metrics.plugin.d.ts +0 -26
- package/dist/analytics/plugins/api-metrics.plugin.d.ts.map +0 -1
- package/dist/analytics/plugins/api-metrics.plugin.js +0 -97
- package/dist/analytics/plugins/api-metrics.plugin.js.map +0 -1
- package/dist/analytics/plugins/index.d.ts +0 -15
- package/dist/analytics/plugins/index.d.ts.map +0 -1
- package/dist/analytics/plugins/index.js +0 -15
- package/dist/analytics/plugins/index.js.map +0 -1
- package/dist/analytics/plugins/model-metrics.plugin.d.ts +0 -39
- package/dist/analytics/plugins/model-metrics.plugin.d.ts.map +0 -1
- package/dist/analytics/plugins/model-metrics.plugin.js +0 -105
- package/dist/analytics/plugins/model-metrics.plugin.js.map +0 -1
- package/dist/analytics/plugins/provider-metrics.plugin.d.ts +0 -41
- package/dist/analytics/plugins/provider-metrics.plugin.d.ts.map +0 -1
- package/dist/analytics/plugins/provider-metrics.plugin.js +0 -123
- package/dist/analytics/plugins/provider-metrics.plugin.js.map +0 -1
- package/dist/analytics/plugins/types.d.ts +0 -61
- package/dist/analytics/plugins/types.d.ts.map +0 -1
- package/dist/analytics/plugins/types.js +0 -54
- package/dist/analytics/plugins/types.js.map +0 -1
- package/dist/analytics/privacy.d.ts +0 -10
- package/dist/analytics/privacy.d.ts.map +0 -1
- package/dist/analytics/privacy.js +0 -20
- package/dist/analytics/privacy.js.map +0 -1
- package/dist/analytics/remote-submission/cursor-manager.d.ts +0 -71
- package/dist/analytics/remote-submission/cursor-manager.d.ts.map +0 -1
- package/dist/analytics/remote-submission/cursor-manager.js +0 -204
- package/dist/analytics/remote-submission/cursor-manager.js.map +0 -1
- package/dist/analytics/remote-submission/index.d.ts +0 -12
- package/dist/analytics/remote-submission/index.d.ts.map +0 -1
- package/dist/analytics/remote-submission/index.js +0 -11
- package/dist/analytics/remote-submission/index.js.map +0 -1
- package/dist/analytics/remote-submission/lock-manager.d.ts +0 -71
- package/dist/analytics/remote-submission/lock-manager.d.ts.map +0 -1
- package/dist/analytics/remote-submission/lock-manager.js +0 -238
- package/dist/analytics/remote-submission/lock-manager.js.map +0 -1
- package/dist/analytics/remote-submission/metric-transformer.d.ts +0 -21
- package/dist/analytics/remote-submission/metric-transformer.d.ts.map +0 -1
- package/dist/analytics/remote-submission/metric-transformer.js +0 -82
- package/dist/analytics/remote-submission/metric-transformer.js.map +0 -1
- package/dist/analytics/remote-submission/submitter.d.ts +0 -79
- package/dist/analytics/remote-submission/submitter.d.ts.map +0 -1
- package/dist/analytics/remote-submission/submitter.js +0 -362
- package/dist/analytics/remote-submission/submitter.js.map +0 -1
- package/dist/analytics/remote-submission/types.d.ts +0 -123
- package/dist/analytics/remote-submission/types.d.ts.map +0 -1
- package/dist/analytics/remote-submission/types.js +0 -13
- package/dist/analytics/remote-submission/types.js.map +0 -1
- package/dist/analytics/session.d.ts +0 -56
- package/dist/analytics/session.d.ts.map +0 -1
- package/dist/analytics/session.js +0 -95
- package/dist/analytics/session.js.map +0 -1
- package/dist/analytics/types.d.ts +0 -104
- package/dist/analytics/types.d.ts.map +0 -1
- package/dist/analytics/types.js +0 -15
- package/dist/analytics/types.js.map +0 -1
- package/dist/analytics/writer.d.ts +0 -18
- package/dist/analytics/writer.d.ts.map +0 -1
- package/dist/analytics/writer.js +0 -44
- package/dist/analytics/writer.js.map +0 -1
- package/dist/cli/commands/analytics.d.ts +0 -3
- package/dist/cli/commands/analytics.d.ts.map +0 -1
- package/dist/cli/commands/analytics.js +0 -748
- package/dist/cli/commands/analytics.js.map +0 -1
- package/dist/utils/analytics-reader.d.ts +0 -117
- package/dist/utils/analytics-reader.d.ts.map +0 -1
- package/dist/utils/analytics-reader.js +0 -421
- package/dist/utils/analytics-reader.js.map +0 -1
- package/dist/utils/date-formatter.d.ts +0 -88
- package/dist/utils/date-formatter.d.ts.map +0 -1
- package/dist/utils/date-formatter.js +0 -133
- package/dist/utils/date-formatter.js.map +0 -1
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Logging Plugin - Request/Response Logging
|
|
2
|
+
* Logging Plugin - Request/Response Logging
|
|
3
3
|
* Priority: 50 (runs before analytics)
|
|
4
4
|
*
|
|
5
|
-
* Purpose: Logs detailed proxy request/response information
|
|
5
|
+
* Purpose: Logs detailed proxy request/response information with smart content handling
|
|
6
6
|
* Separates operational logging from analytics metrics
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* Logs:
|
|
9
|
+
* - Request: method, URL, content-type, headers, body (parsed JSON or raw)
|
|
10
|
+
* - Response: status, content-type, headers, body (smart handling based on type)
|
|
11
|
+
* - JSON: Parsed and structured
|
|
12
|
+
* - SSE (Server-Sent Events): First/last events + stats (avoids logging full stream)
|
|
13
|
+
* - Other: Raw content (truncated if > 1000 bytes)
|
|
14
|
+
* - Streaming: chunk count, bytes transferred, streaming detection
|
|
15
|
+
*
|
|
16
|
+
* Log Level: DEBUG (file + console when CODEMIE_DEBUG=1)
|
|
9
17
|
* Log Location: ~/.codemie/logs/debug-YYYY-MM-DD.log
|
|
10
18
|
*
|
|
11
19
|
* SOLID: Single responsibility = log proxy activity
|
|
@@ -23,15 +31,49 @@ export class LoggingPlugin {
|
|
|
23
31
|
}
|
|
24
32
|
class LoggingInterceptor {
|
|
25
33
|
name = 'logging';
|
|
34
|
+
chunkCount = 0;
|
|
35
|
+
totalBytes = 0;
|
|
36
|
+
responseChunks = [];
|
|
37
|
+
responseContentType = null;
|
|
26
38
|
async onRequest(context) {
|
|
27
39
|
try {
|
|
28
|
-
|
|
40
|
+
// Reset counters for new request
|
|
41
|
+
this.chunkCount = 0;
|
|
42
|
+
this.totalBytes = 0;
|
|
43
|
+
this.responseChunks = [];
|
|
44
|
+
this.responseContentType = null;
|
|
45
|
+
// Get request content type
|
|
46
|
+
const contentType = context.headers['content-type'] || context.headers['Content-Type'] || 'unknown';
|
|
47
|
+
// Parse request body based on content type
|
|
48
|
+
let requestBodyParsed = null;
|
|
49
|
+
if (context.requestBody) {
|
|
50
|
+
try {
|
|
51
|
+
const bodyString = context.requestBody.toString('utf-8');
|
|
52
|
+
if (contentType.includes('application/json')) {
|
|
53
|
+
requestBodyParsed = JSON.parse(bodyString);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Log raw for non-JSON
|
|
57
|
+
requestBodyParsed = bodyString;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Parse error - log as string
|
|
62
|
+
requestBodyParsed = context.requestBody.toString('utf-8');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
logger.debug(`[proxy-request] ${context.method} ${context.url}`, {
|
|
29
66
|
requestId: context.requestId,
|
|
30
67
|
sessionId: context.sessionId,
|
|
31
68
|
agent: context.agentName,
|
|
69
|
+
profile: context.profile,
|
|
70
|
+
provider: context.provider,
|
|
71
|
+
model: context.model,
|
|
32
72
|
targetUrl: context.targetUrl,
|
|
73
|
+
contentType,
|
|
33
74
|
bodySize: context.requestBody?.length || 0,
|
|
34
|
-
headers: this.sanitizeHeaders(context.headers)
|
|
75
|
+
headers: this.sanitizeHeaders(context.headers),
|
|
76
|
+
requestBody: requestBodyParsed
|
|
35
77
|
});
|
|
36
78
|
}
|
|
37
79
|
catch (error) {
|
|
@@ -39,14 +81,137 @@ class LoggingInterceptor {
|
|
|
39
81
|
logger.error(`[${this.name}] Error logging request:`, error);
|
|
40
82
|
}
|
|
41
83
|
}
|
|
42
|
-
async
|
|
84
|
+
async onResponseHeaders(context, headers) {
|
|
43
85
|
try {
|
|
44
|
-
|
|
86
|
+
// Capture response content type for use in response body logging
|
|
87
|
+
const contentTypeHeader = headers['content-type'] || headers['Content-Type'];
|
|
88
|
+
this.responseContentType = Array.isArray(contentTypeHeader)
|
|
89
|
+
? contentTypeHeader[0]
|
|
90
|
+
: contentTypeHeader || 'unknown';
|
|
91
|
+
logger.debug(`[proxy-response-headers] ${context.url}`, {
|
|
45
92
|
requestId: context.requestId,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
93
|
+
sessionId: context.sessionId,
|
|
94
|
+
agent: context.agentName,
|
|
95
|
+
profile: context.profile,
|
|
96
|
+
provider: context.provider,
|
|
97
|
+
model: context.model,
|
|
98
|
+
headers: {
|
|
99
|
+
'content-type': this.responseContentType,
|
|
100
|
+
'content-length': headers['content-length'],
|
|
101
|
+
'transfer-encoding': headers['transfer-encoding']
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
logger.error(`[${this.name}] Error logging response headers:`, error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async onResponseChunk(context, chunk) {
|
|
110
|
+
try {
|
|
111
|
+
this.chunkCount++;
|
|
112
|
+
this.totalBytes += chunk.length;
|
|
113
|
+
// Collect chunks for full response body
|
|
114
|
+
this.responseChunks.push(Buffer.from(chunk));
|
|
115
|
+
// Log every 1000th chunk to avoid spam (or first/last chunks)
|
|
116
|
+
if (this.chunkCount === 1 || this.chunkCount % 1000 === 0) {
|
|
117
|
+
logger.debug(`[proxy-streaming] ${context.url}`, {
|
|
118
|
+
requestId: context.requestId,
|
|
119
|
+
sessionId: context.sessionId,
|
|
120
|
+
chunkNumber: this.chunkCount,
|
|
121
|
+
chunkSize: chunk.length,
|
|
122
|
+
totalBytes: this.totalBytes
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
logger.error(`[${this.name}] Error logging chunk:`, error);
|
|
128
|
+
}
|
|
129
|
+
return chunk;
|
|
130
|
+
}
|
|
131
|
+
async onResponseComplete(context, metadata) {
|
|
132
|
+
try {
|
|
133
|
+
// Capture chunks for logging (use local reference to avoid race conditions)
|
|
134
|
+
const chunksToLog = this.responseChunks;
|
|
135
|
+
const chunkCount = this.chunkCount;
|
|
136
|
+
const totalBytes = this.totalBytes;
|
|
137
|
+
const contentType = this.responseContentType || 'unknown';
|
|
138
|
+
// CRITICAL: Clear state immediately for next request
|
|
139
|
+
this.responseChunks = [];
|
|
140
|
+
this.chunkCount = 0;
|
|
141
|
+
this.totalBytes = 0;
|
|
142
|
+
this.responseContentType = null;
|
|
143
|
+
// Process response body asynchronously (don't block)
|
|
144
|
+
// Use setImmediate to defer heavy work to next tick
|
|
145
|
+
setImmediate(() => {
|
|
146
|
+
try {
|
|
147
|
+
let responseBodyParsed = null;
|
|
148
|
+
let isStreaming = false;
|
|
149
|
+
if (chunksToLog.length > 0) {
|
|
150
|
+
const fullBody = Buffer.concat(chunksToLog).toString('utf-8');
|
|
151
|
+
// Check if this is a streaming response (SSE)
|
|
152
|
+
isStreaming = contentType.includes('text/event-stream') || fullBody.startsWith('event:');
|
|
153
|
+
if (isStreaming) {
|
|
154
|
+
// For streaming responses, log first and last few events instead of full body
|
|
155
|
+
const lines = fullBody.split('\n').filter(line => line.trim());
|
|
156
|
+
const eventCount = lines.filter(line => line.startsWith('event:')).length;
|
|
157
|
+
responseBodyParsed = {
|
|
158
|
+
type: 'text/event-stream',
|
|
159
|
+
eventCount,
|
|
160
|
+
firstEvents: lines.slice(0, 10).join('\n'),
|
|
161
|
+
lastEvents: lines.slice(-10).join('\n'),
|
|
162
|
+
totalLines: lines.length,
|
|
163
|
+
bodySizeBytes: fullBody.length
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
else if (contentType.includes('application/json')) {
|
|
167
|
+
// Parse JSON responses
|
|
168
|
+
try {
|
|
169
|
+
responseBodyParsed = JSON.parse(fullBody);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Invalid JSON - log as string
|
|
173
|
+
responseBodyParsed = fullBody;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
// Log raw for other content types (truncate if too long)
|
|
178
|
+
responseBodyParsed = fullBody.length > 1000
|
|
179
|
+
? fullBody.substring(0, 1000) + '... (truncated)'
|
|
180
|
+
: fullBody;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
logger.debug(`[proxy-response] ${metadata.statusCode} ${context.url} (${metadata.durationMs}ms)`, {
|
|
184
|
+
requestId: context.requestId,
|
|
185
|
+
sessionId: context.sessionId,
|
|
186
|
+
agent: context.agentName,
|
|
187
|
+
profile: context.profile,
|
|
188
|
+
provider: context.provider,
|
|
189
|
+
model: context.model,
|
|
190
|
+
statusCode: metadata.statusCode,
|
|
191
|
+
statusMessage: metadata.statusMessage,
|
|
192
|
+
contentType,
|
|
193
|
+
isStreaming,
|
|
194
|
+
bytesSent: metadata.bytesSent,
|
|
195
|
+
durationMs: metadata.durationMs,
|
|
196
|
+
totalChunks: chunkCount,
|
|
197
|
+
totalBytesStreamed: totalBytes,
|
|
198
|
+
responseBody: responseBodyParsed
|
|
199
|
+
});
|
|
200
|
+
// Log completion marker to track if we reach this point
|
|
201
|
+
logger.debug(`[proxy-complete] Request fully processed for ${context.url}`, {
|
|
202
|
+
requestId: context.requestId,
|
|
203
|
+
sessionId: context.sessionId,
|
|
204
|
+
agent: context.agentName,
|
|
205
|
+
profile: context.profile,
|
|
206
|
+
provider: context.provider,
|
|
207
|
+
model: context.model,
|
|
208
|
+
finalStatus: 'success'
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
// Don't break proxy flow on logging errors
|
|
213
|
+
logger.error(`[${this.name}] Error logging response (deferred):`, error);
|
|
214
|
+
}
|
|
50
215
|
});
|
|
51
216
|
}
|
|
52
217
|
catch (error) {
|
|
@@ -56,10 +221,16 @@ class LoggingInterceptor {
|
|
|
56
221
|
}
|
|
57
222
|
async onError(context, error) {
|
|
58
223
|
try {
|
|
59
|
-
logger.
|
|
224
|
+
logger.debug(`[proxy-error] ${error.name}: ${error.message}`, {
|
|
60
225
|
requestId: context.requestId,
|
|
226
|
+
sessionId: context.sessionId,
|
|
227
|
+
agent: context.agentName,
|
|
228
|
+
profile: context.profile,
|
|
229
|
+
provider: context.provider,
|
|
230
|
+
model: context.model,
|
|
61
231
|
url: context.url,
|
|
62
232
|
errorType: error.name,
|
|
233
|
+
errorMessage: error.message,
|
|
63
234
|
errorStack: error.stack
|
|
64
235
|
});
|
|
65
236
|
}
|
|
@@ -69,24 +240,17 @@ class LoggingInterceptor {
|
|
|
69
240
|
}
|
|
70
241
|
}
|
|
71
242
|
/**
|
|
72
|
-
*
|
|
243
|
+
* Filter headers to only include X-Codemie headers
|
|
73
244
|
*/
|
|
74
245
|
sanitizeHeaders(headers) {
|
|
75
|
-
const
|
|
246
|
+
const filtered = {};
|
|
76
247
|
for (const [key, value] of Object.entries(headers)) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
lowerKey.includes('api-key') ||
|
|
81
|
-
lowerKey.includes('token') ||
|
|
82
|
-
lowerKey.includes('cookie')) {
|
|
83
|
-
sanitized[key] = '[REDACTED]';
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
sanitized[key] = value;
|
|
248
|
+
// Only include X-Codemie headers
|
|
249
|
+
if (key.toLowerCase().startsWith('x-codemie')) {
|
|
250
|
+
filtered[key] = value;
|
|
87
251
|
}
|
|
88
252
|
}
|
|
89
|
-
return
|
|
253
|
+
return filtered;
|
|
90
254
|
}
|
|
91
255
|
}
|
|
92
256
|
//# sourceMappingURL=logging.plugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.plugin.js","sourceRoot":"","sources":["../../../src/proxy/plugins/logging.plugin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"logging.plugin.js","sourceRoot":"","sources":["../../../src/proxy/plugins/logging.plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Sync Plugin
|
|
3
|
+
* Priority: 100 (runs after logging plugin)
|
|
4
|
+
*
|
|
5
|
+
* Purpose: Syncs metrics to CodeMie API in background
|
|
6
|
+
* - Runs only in SSO mode (ai-run-sso provider)
|
|
7
|
+
* - Background timer (every 5 minutes)
|
|
8
|
+
* - Aggregates pending deltas into single metric
|
|
9
|
+
* - Marks deltas as synced in JSONL
|
|
10
|
+
* - Final sync on proxy shutdown
|
|
11
|
+
*
|
|
12
|
+
* SOLID: Single responsibility = sync metrics
|
|
13
|
+
* KISS: Simple timer-based sync
|
|
14
|
+
*/
|
|
15
|
+
import { ProxyPlugin, PluginContext, ProxyInterceptor } from './types.js';
|
|
16
|
+
export declare class MetricsSyncPlugin implements ProxyPlugin {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
version: string;
|
|
20
|
+
priority: number;
|
|
21
|
+
createInterceptor(context: PluginContext): Promise<ProxyInterceptor>;
|
|
22
|
+
/**
|
|
23
|
+
* Check if metrics sync is enabled
|
|
24
|
+
* Priority: ENV > Profile config > Default (true)
|
|
25
|
+
*/
|
|
26
|
+
private isSyncEnabled;
|
|
27
|
+
/**
|
|
28
|
+
* Check if dry-run mode is enabled
|
|
29
|
+
* Priority: ENV > Profile config > Default (false)
|
|
30
|
+
*/
|
|
31
|
+
private isDryRunEnabled;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=metrics-sync.plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-sync.plugin.d.ts","sourceRoot":"","sources":["../../../src/proxy/plugins/metrics-sync.plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAQ1E,qBAAa,iBAAkB,YAAW,WAAW;IACnD,EAAE,SAAiC;IACnC,IAAI,SAAkB;IACtB,OAAO,SAAW;IAClB,QAAQ,SAAO;IAET,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAkC1E;;;OAGG;IACH,OAAO,CAAC,aAAa;IAgBrB;;;OAGG;IACH,OAAO,CAAC,eAAe;CAexB"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Sync Plugin
|
|
3
|
+
* Priority: 100 (runs after logging plugin)
|
|
4
|
+
*
|
|
5
|
+
* Purpose: Syncs metrics to CodeMie API in background
|
|
6
|
+
* - Runs only in SSO mode (ai-run-sso provider)
|
|
7
|
+
* - Background timer (every 5 minutes)
|
|
8
|
+
* - Aggregates pending deltas into single metric
|
|
9
|
+
* - Marks deltas as synced in JSONL
|
|
10
|
+
* - Final sync on proxy shutdown
|
|
11
|
+
*
|
|
12
|
+
* SOLID: Single responsibility = sync metrics
|
|
13
|
+
* KISS: Simple timer-based sync
|
|
14
|
+
*/
|
|
15
|
+
import { logger } from '../../utils/logger.js';
|
|
16
|
+
import { MetricsApiClient } from '../../metrics/sync/MetricsApiClient.js';
|
|
17
|
+
import { readJSONL, writeJSONLAtomic } from '../../metrics/sync/jsonl-writer.js';
|
|
18
|
+
import { aggregateDeltas } from '../../metrics/sync/aggregator.js';
|
|
19
|
+
import { SessionStore } from '../../metrics/session/SessionStore.js';
|
|
20
|
+
import { getSessionMetricsPath } from '../../metrics/config.js';
|
|
21
|
+
export class MetricsSyncPlugin {
|
|
22
|
+
id = '@codemie/proxy-metrics-sync';
|
|
23
|
+
name = 'Metrics Sync';
|
|
24
|
+
version = '1.0.0';
|
|
25
|
+
priority = 100; // Run after logging (priority 50)
|
|
26
|
+
async createInterceptor(context) {
|
|
27
|
+
// Only create interceptor if we have necessary context
|
|
28
|
+
if (!context.config.sessionId) {
|
|
29
|
+
logger.debug('[MetricsSyncPlugin] Skipping: Session ID not available');
|
|
30
|
+
throw new Error('Session ID not available (metrics sync disabled)');
|
|
31
|
+
}
|
|
32
|
+
if (!context.credentials) {
|
|
33
|
+
logger.debug('[MetricsSyncPlugin] Skipping: SSO credentials not available');
|
|
34
|
+
throw new Error('SSO credentials not available (metrics sync disabled)');
|
|
35
|
+
}
|
|
36
|
+
// Check if metrics sync is enabled (from config or env var)
|
|
37
|
+
const syncEnabled = this.isSyncEnabled(context);
|
|
38
|
+
if (!syncEnabled) {
|
|
39
|
+
logger.debug('[MetricsSyncPlugin] Skipping: Metrics sync disabled by configuration');
|
|
40
|
+
throw new Error('Metrics sync disabled by configuration');
|
|
41
|
+
}
|
|
42
|
+
logger.info('[MetricsSyncPlugin] Initializing metrics sync');
|
|
43
|
+
// Check if dry-run mode is enabled
|
|
44
|
+
const dryRun = this.isDryRunEnabled(context);
|
|
45
|
+
return new MetricsSyncInterceptor(context.config.sessionId, context.config.targetApiUrl, context.credentials.cookies, context.config.clientType, context.config.version, dryRun);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if metrics sync is enabled
|
|
49
|
+
* Priority: ENV > Profile config > Default (true)
|
|
50
|
+
*/
|
|
51
|
+
isSyncEnabled(context) {
|
|
52
|
+
// Check environment variable first
|
|
53
|
+
const envEnabled = process.env.CODEMIE_METRICS_SYNC_ENABLED;
|
|
54
|
+
if (envEnabled !== undefined) {
|
|
55
|
+
return envEnabled === 'true' || envEnabled === '1';
|
|
56
|
+
}
|
|
57
|
+
// Check profile config (if available)
|
|
58
|
+
if (context.profileConfig?.metrics?.sync?.enabled !== undefined) {
|
|
59
|
+
return context.profileConfig.metrics.sync.enabled;
|
|
60
|
+
}
|
|
61
|
+
// Default to enabled for SSO mode
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if dry-run mode is enabled
|
|
66
|
+
* Priority: ENV > Profile config > Default (false)
|
|
67
|
+
*/
|
|
68
|
+
isDryRunEnabled(context) {
|
|
69
|
+
// Check environment variable first
|
|
70
|
+
const envDryRun = process.env.CODEMIE_METRICS_DRY_RUN;
|
|
71
|
+
if (envDryRun !== undefined) {
|
|
72
|
+
return envDryRun === 'true' || envDryRun === '1';
|
|
73
|
+
}
|
|
74
|
+
// Check profile config (if available)
|
|
75
|
+
if (context.profileConfig?.metrics?.sync?.dryRun !== undefined) {
|
|
76
|
+
return context.profileConfig.metrics.sync.dryRun;
|
|
77
|
+
}
|
|
78
|
+
// Default to disabled
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
class MetricsSyncInterceptor {
|
|
83
|
+
sessionId;
|
|
84
|
+
name = 'metrics-sync';
|
|
85
|
+
syncTimer;
|
|
86
|
+
sessionStore = new SessionStore();
|
|
87
|
+
apiClient;
|
|
88
|
+
syncInterval;
|
|
89
|
+
isSyncing = false;
|
|
90
|
+
version;
|
|
91
|
+
dryRun;
|
|
92
|
+
constructor(sessionId, baseUrl, cookies, clientType, version, dryRun = false) {
|
|
93
|
+
this.sessionId = sessionId;
|
|
94
|
+
// Get version from proxy config (passed from AgentCLI)
|
|
95
|
+
this.version = version || '0.0.0';
|
|
96
|
+
// Set dry-run mode (passed from plugin)
|
|
97
|
+
this.dryRun = dryRun;
|
|
98
|
+
if (this.dryRun) {
|
|
99
|
+
logger.info('[metrics-sync] Dry-run mode enabled - metrics will be logged but not sent');
|
|
100
|
+
}
|
|
101
|
+
// Build cookie header
|
|
102
|
+
const cookieHeader = Object.entries(cookies)
|
|
103
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
104
|
+
.join('; ');
|
|
105
|
+
this.apiClient = new MetricsApiClient({
|
|
106
|
+
baseUrl,
|
|
107
|
+
cookies: cookieHeader,
|
|
108
|
+
timeout: 30000,
|
|
109
|
+
retryAttempts: 3,
|
|
110
|
+
version: this.version,
|
|
111
|
+
clientType: clientType || 'codemie-cli'
|
|
112
|
+
});
|
|
113
|
+
// Get sync interval from env or default to 5 minutes
|
|
114
|
+
this.syncInterval = Number.parseInt(process.env.CODEMIE_METRICS_SYNC_INTERVAL || '300000', 10);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Called when proxy starts - initialize background timer
|
|
118
|
+
*/
|
|
119
|
+
async onProxyStart() {
|
|
120
|
+
logger.info(`[${this.name}] Starting metrics sync (interval: ${this.syncInterval}ms)`);
|
|
121
|
+
// Start background timer
|
|
122
|
+
this.syncTimer = setInterval(() => {
|
|
123
|
+
this.syncMetrics().catch(error => {
|
|
124
|
+
logger.error(`[${this.name}] Sync failed:`, error);
|
|
125
|
+
});
|
|
126
|
+
}, this.syncInterval);
|
|
127
|
+
logger.debug(`[${this.name}] Background timer started`);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Called when proxy stops - cleanup and final sync
|
|
131
|
+
*/
|
|
132
|
+
async onProxyStop() {
|
|
133
|
+
logger.info(`[${this.name}] Stopping metrics sync`);
|
|
134
|
+
// Stop timer
|
|
135
|
+
if (this.syncTimer) {
|
|
136
|
+
clearInterval(this.syncTimer);
|
|
137
|
+
this.syncTimer = undefined;
|
|
138
|
+
}
|
|
139
|
+
// Final sync (ensure all pending metrics are sent)
|
|
140
|
+
try {
|
|
141
|
+
await this.syncMetrics();
|
|
142
|
+
logger.info(`[${this.name}] Final sync completed`);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
logger.error(`[${this.name}] Final sync failed:`, error);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Sync metrics to API
|
|
150
|
+
*/
|
|
151
|
+
async syncMetrics() {
|
|
152
|
+
// Skip if already syncing (prevent concurrent syncs)
|
|
153
|
+
if (this.isSyncing) {
|
|
154
|
+
logger.debug(`[${this.name}] Sync already in progress, skipping`);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
this.isSyncing = true;
|
|
158
|
+
try {
|
|
159
|
+
const metricsFile = getSessionMetricsPath(this.sessionId);
|
|
160
|
+
// 1. Read all deltas from JSONL
|
|
161
|
+
const allDeltas = await readJSONL(metricsFile);
|
|
162
|
+
// 2. Filter for pending deltas only
|
|
163
|
+
const pendingDeltas = allDeltas.filter(d => d.syncStatus === 'pending');
|
|
164
|
+
if (pendingDeltas.length === 0) {
|
|
165
|
+
logger.debug(`[${this.name}] No pending deltas to sync`);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
logger.info(`[${this.name}] Syncing ${pendingDeltas.length} pending deltas`);
|
|
169
|
+
// Debug: Log collected deltas
|
|
170
|
+
logger.debug(`[${this.name}] Collected pending deltas:`, {
|
|
171
|
+
count: pendingDeltas.length,
|
|
172
|
+
deltas: pendingDeltas.map(d => {
|
|
173
|
+
// Calculate tool stats from tools and toolStatus
|
|
174
|
+
const totalTools = Object.values(d.tools || {}).reduce((sum, count) => sum + count, 0);
|
|
175
|
+
let successCount = 0;
|
|
176
|
+
let failureCount = 0;
|
|
177
|
+
if (d.toolStatus) {
|
|
178
|
+
for (const status of Object.values(d.toolStatus)) {
|
|
179
|
+
successCount += status.success || 0;
|
|
180
|
+
failureCount += status.failure || 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Calculate file operation totals
|
|
184
|
+
const fileOps = d.fileOperations || [];
|
|
185
|
+
const linesAdded = fileOps.reduce((sum, op) => sum + (op.linesAdded || 0), 0);
|
|
186
|
+
const linesRemoved = fileOps.reduce((sum, op) => sum + (op.linesRemoved || 0), 0);
|
|
187
|
+
const writeOps = fileOps.filter(op => op.type === 'write').length;
|
|
188
|
+
const editOps = fileOps.filter(op => op.type === 'edit').length;
|
|
189
|
+
const deleteOps = fileOps.filter(op => op.type === 'delete').length;
|
|
190
|
+
return {
|
|
191
|
+
recordId: d.recordId,
|
|
192
|
+
timestamp: typeof d.timestamp === 'number'
|
|
193
|
+
? new Date(d.timestamp).toISOString()
|
|
194
|
+
: d.timestamp,
|
|
195
|
+
tokens: d.tokens,
|
|
196
|
+
tools: {
|
|
197
|
+
total: totalTools,
|
|
198
|
+
success: successCount,
|
|
199
|
+
failure: failureCount,
|
|
200
|
+
breakdown: d.tools
|
|
201
|
+
},
|
|
202
|
+
fileOperations: {
|
|
203
|
+
created: writeOps,
|
|
204
|
+
modified: editOps,
|
|
205
|
+
deleted: deleteOps,
|
|
206
|
+
linesAdded,
|
|
207
|
+
linesRemoved
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
})
|
|
211
|
+
});
|
|
212
|
+
// 3. Load session metadata
|
|
213
|
+
const session = await this.sessionStore.loadSession(this.sessionId);
|
|
214
|
+
if (!session) {
|
|
215
|
+
logger.error(`[${this.name}] Session not found: ${this.sessionId}`);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
// 4. Aggregate pending deltas into metrics grouped by branch
|
|
219
|
+
const metrics = aggregateDeltas(pendingDeltas, session, this.version);
|
|
220
|
+
logger.info(`[${this.name}] Aggregated ${metrics.length} branch-specific metrics from ${pendingDeltas.length} deltas`);
|
|
221
|
+
// Debug: Log aggregated metrics
|
|
222
|
+
for (const metric of metrics) {
|
|
223
|
+
logger.debug(`[${this.name}] Aggregated metric for branch "${metric.attributes.git_branch}":`, {
|
|
224
|
+
name: metric.name,
|
|
225
|
+
attributes: {
|
|
226
|
+
// Identity
|
|
227
|
+
agent: metric.attributes.agent,
|
|
228
|
+
agent_version: metric.attributes.agent_version,
|
|
229
|
+
llm_model: metric.attributes.llm_model,
|
|
230
|
+
project: metric.attributes.project,
|
|
231
|
+
session_id: metric.attributes.session_id,
|
|
232
|
+
git_branch: metric.attributes.git_branch,
|
|
233
|
+
// Interaction totals
|
|
234
|
+
total_user_prompts: metric.attributes.total_user_prompts,
|
|
235
|
+
// Token totals
|
|
236
|
+
total_input_tokens: metric.attributes.total_input_tokens,
|
|
237
|
+
total_output_tokens: metric.attributes.total_output_tokens,
|
|
238
|
+
total_cache_read_input_tokens: metric.attributes.total_cache_read_input_tokens,
|
|
239
|
+
total_cache_creation_tokens: metric.attributes.total_cache_creation_tokens,
|
|
240
|
+
// Tool totals
|
|
241
|
+
total_tool_calls: metric.attributes.total_tool_calls,
|
|
242
|
+
successful_tool_calls: metric.attributes.successful_tool_calls,
|
|
243
|
+
failed_tool_calls: metric.attributes.failed_tool_calls,
|
|
244
|
+
// File operation totals
|
|
245
|
+
files_created: metric.attributes.files_created,
|
|
246
|
+
files_modified: metric.attributes.files_modified,
|
|
247
|
+
files_deleted: metric.attributes.files_deleted,
|
|
248
|
+
total_lines_added: metric.attributes.total_lines_added,
|
|
249
|
+
total_lines_removed: metric.attributes.total_lines_removed,
|
|
250
|
+
// Session info
|
|
251
|
+
session_duration_ms: metric.attributes.session_duration_ms,
|
|
252
|
+
count: metric.attributes.count
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
// 5. Send each branch metric to API or log in dry-run mode
|
|
257
|
+
if (this.dryRun) {
|
|
258
|
+
// Dry-run mode: Log what would be sent without actually sending
|
|
259
|
+
for (const metric of metrics) {
|
|
260
|
+
logger.info(`[${this.name}] [DRY-RUN] Would send metric for branch "${metric.attributes.git_branch}" to API:`, {
|
|
261
|
+
endpoint: `${this.apiClient['config'].baseUrl}/v1/metrics`,
|
|
262
|
+
method: 'POST',
|
|
263
|
+
headers: {
|
|
264
|
+
'Content-Type': 'application/json',
|
|
265
|
+
'User-Agent': `CodeMie-CLI/${this.version}`,
|
|
266
|
+
'X-CodeMie-Client': this.apiClient['config'].clientType,
|
|
267
|
+
'Cookie': '[REDACTED]'
|
|
268
|
+
},
|
|
269
|
+
payload: {
|
|
270
|
+
name: metric.name,
|
|
271
|
+
attributes: metric.attributes
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
logger.info(`[${this.name}] [DRY-RUN] Skipping actual API calls - ${pendingDeltas.length} deltas across ${metrics.length} branches would be synced`);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
// Normal mode: Send each branch metric to API
|
|
279
|
+
for (const metric of metrics) {
|
|
280
|
+
const response = await this.apiClient.sendMetric(metric);
|
|
281
|
+
if (!response.success) {
|
|
282
|
+
logger.error(`[${this.name}] Sync failed for branch "${metric.attributes.git_branch}": ${response.message}`);
|
|
283
|
+
// Continue with other branches even if one fails
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
logger.info(`[${this.name}] Successfully synced metric for branch "${metric.attributes.git_branch}"`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// 6. Mark deltas as synced in JSONL (atomic rewrite)
|
|
290
|
+
const syncedAt = Date.now();
|
|
291
|
+
const pendingRecordIds = new Set(pendingDeltas.map(d => d.recordId));
|
|
292
|
+
const updatedDeltas = allDeltas.map(d => pendingRecordIds.has(d.recordId)
|
|
293
|
+
? {
|
|
294
|
+
...d,
|
|
295
|
+
syncStatus: 'synced',
|
|
296
|
+
syncAttempts: d.syncAttempts + 1,
|
|
297
|
+
syncedAt
|
|
298
|
+
}
|
|
299
|
+
: d);
|
|
300
|
+
await writeJSONLAtomic(metricsFile, updatedDeltas);
|
|
301
|
+
logger.info(`[${this.name}] Successfully synced ${pendingDeltas.length} deltas across ${metrics.length} branches`);
|
|
302
|
+
// Debug: Log which deltas were marked as synced
|
|
303
|
+
logger.debug(`[${this.name}] Marked deltas as synced:`, {
|
|
304
|
+
syncedAt: new Date(syncedAt).toISOString(),
|
|
305
|
+
recordIds: Array.from(pendingRecordIds),
|
|
306
|
+
totalDeltasInFile: updatedDeltas.length,
|
|
307
|
+
syncedCount: updatedDeltas.filter(d => d.syncStatus === 'synced').length,
|
|
308
|
+
pendingCount: updatedDeltas.filter(d => d.syncStatus === 'pending').length
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
logger.error(`[${this.name}] Sync failed:`, error);
|
|
313
|
+
throw error;
|
|
314
|
+
}
|
|
315
|
+
finally {
|
|
316
|
+
this.isSyncing = false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=metrics-sync.plugin.js.map
|