@codemieai/code 0.0.15 → 0.0.17
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 +86 -14
- 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 +5 -34
- package/dist/agents/codemie-code/agent.js.map +1 -1
- package/dist/agents/codemie-code/config.d.ts.map +1 -1
- package/dist/agents/codemie-code/config.js +12 -4
- package/dist/agents/codemie-code/config.js.map +1 -1
- package/dist/agents/codemie-code/tools/planning.d.ts +1 -1
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +30 -63
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts +10 -6
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +108 -36
- 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 +46 -14
- 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 +2 -4
- package/dist/agents/plugins/codex.plugin.js.map +1 -1
- package/dist/agents/plugins/deepagents.plugin.js +1 -1
- package/dist/agents/plugins/deepagents.plugin.js.map +1 -1
- package/dist/agents/plugins/gemini.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/gemini.plugin.js +1 -8
- 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/auth.d.ts.map +1 -1
- package/dist/cli/commands/auth.js +10 -5
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/doctor/checks/AIConfigCheck.d.ts.map +1 -1
- package/dist/cli/commands/doctor/checks/AIConfigCheck.js +12 -5
- package/dist/cli/commands/doctor/checks/AIConfigCheck.js.map +1 -1
- 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/formatter.d.ts +1 -1
- package/dist/cli/commands/doctor/formatter.d.ts.map +1 -1
- package/dist/cli/commands/doctor/formatter.js +1 -6
- package/dist/cli/commands/doctor/formatter.js.map +1 -1
- package/dist/cli/commands/doctor/index.d.ts.map +1 -1
- package/dist/cli/commands/doctor/index.js +107 -10
- package/dist/cli/commands/doctor/index.js.map +1 -1
- package/dist/cli/commands/doctor/type-adapters.d.ts +18 -0
- package/dist/cli/commands/doctor/type-adapters.d.ts.map +1 -0
- package/dist/cli/commands/doctor/type-adapters.js +75 -0
- package/dist/cli/commands/doctor/type-adapters.js.map +1 -0
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +1 -6
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/list.js +0 -5
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/profile.d.ts.map +1 -1
- package/dist/cli/commands/profile.js +130 -92
- package/dist/cli/commands/profile.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +147 -668
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +5 -2
- 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 +13 -0
- package/dist/metrics/sync/aggregator.d.ts.map +1 -0
- package/dist/metrics/sync/aggregator.js +196 -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 +72 -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/core/base/BaseHealthCheck.d.ts +57 -0
- package/dist/providers/core/base/BaseHealthCheck.d.ts.map +1 -0
- package/dist/providers/core/base/BaseHealthCheck.js +121 -0
- package/dist/providers/core/base/BaseHealthCheck.js.map +1 -0
- package/dist/providers/core/base/BaseModelProxy.d.ts +45 -0
- package/dist/providers/core/base/BaseModelProxy.d.ts.map +1 -0
- package/dist/providers/core/base/BaseModelProxy.js +43 -0
- package/dist/providers/core/base/BaseModelProxy.js.map +1 -0
- package/dist/providers/core/base/http-client.d.ts +57 -0
- package/dist/providers/core/base/http-client.d.ts.map +1 -0
- package/dist/providers/core/base/http-client.js +240 -0
- package/dist/providers/core/base/http-client.js.map +1 -0
- package/dist/providers/core/decorators.d.ts +13 -0
- package/dist/providers/core/decorators.d.ts.map +1 -0
- package/dist/providers/core/decorators.js +15 -0
- package/dist/providers/core/decorators.js.map +1 -0
- package/dist/providers/core/index.d.ts +13 -0
- package/dist/providers/core/index.d.ts.map +1 -0
- package/dist/providers/core/index.js +14 -0
- package/dist/providers/core/index.js.map +1 -0
- package/dist/providers/core/registry.d.ts +66 -0
- package/dist/providers/core/registry.d.ts.map +1 -0
- package/dist/providers/core/registry.js +105 -0
- package/dist/providers/core/registry.js.map +1 -0
- package/dist/providers/core/types.d.ts +285 -0
- package/dist/providers/core/types.d.ts.map +1 -0
- package/dist/providers/core/types.js +7 -0
- package/dist/providers/core/types.js.map +1 -0
- package/dist/providers/index.d.ts +22 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +24 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/integration/setup-ui.d.ts +76 -0
- package/dist/providers/integration/setup-ui.d.ts.map +1 -0
- package/dist/providers/integration/setup-ui.js +186 -0
- package/dist/providers/integration/setup-ui.js.map +1 -0
- 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/litellm/index.d.ts +8 -0
- package/dist/providers/plugins/litellm/index.d.ts.map +1 -0
- package/dist/providers/plugins/litellm/index.js +12 -0
- package/dist/providers/plugins/litellm/index.js.map +1 -0
- package/dist/providers/plugins/litellm/litellm.models.d.ts +27 -0
- package/dist/providers/plugins/litellm/litellm.models.d.ts.map +1 -0
- package/dist/providers/plugins/litellm/litellm.models.js +48 -0
- package/dist/providers/plugins/litellm/litellm.models.js.map +1 -0
- package/dist/providers/plugins/litellm/litellm.setup-steps.d.ts +8 -0
- package/dist/providers/plugins/litellm/litellm.setup-steps.d.ts.map +1 -0
- package/dist/providers/plugins/litellm/litellm.setup-steps.js +52 -0
- package/dist/providers/plugins/litellm/litellm.setup-steps.js.map +1 -0
- package/dist/providers/plugins/litellm/litellm.template.d.ts +11 -0
- package/dist/providers/plugins/litellm/litellm.template.d.ts.map +1 -0
- package/dist/providers/plugins/litellm/litellm.template.js +59 -0
- package/dist/providers/plugins/litellm/litellm.template.js.map +1 -0
- package/dist/providers/plugins/ollama/index.d.ts +11 -0
- package/dist/providers/plugins/ollama/index.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/index.js +11 -0
- package/dist/providers/plugins/ollama/index.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.health.d.ts +48 -0
- package/dist/providers/plugins/ollama/ollama.health.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/ollama.health.js +87 -0
- package/dist/providers/plugins/ollama/ollama.health.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.models.d.ts +47 -0
- package/dist/providers/plugins/ollama/ollama.models.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/ollama.models.js +252 -0
- package/dist/providers/plugins/ollama/ollama.models.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts +16 -0
- package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/ollama.setup-steps.js +164 -0
- package/dist/providers/plugins/ollama/ollama.setup-steps.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.template.d.ts +11 -0
- package/dist/providers/plugins/ollama/ollama.template.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/ollama.template.js +89 -0
- package/dist/providers/plugins/ollama/ollama.template.js.map +1 -0
- package/dist/providers/plugins/sso/index.d.ts +12 -0
- package/dist/providers/plugins/sso/index.d.ts.map +1 -0
- package/dist/providers/plugins/sso/index.js +12 -0
- package/dist/providers/plugins/sso/index.js.map +1 -0
- package/dist/providers/plugins/sso/sso.auth.d.ts +50 -0
- package/dist/providers/plugins/sso/sso.auth.d.ts.map +1 -0
- package/dist/{utils/sso-auth.js → providers/plugins/sso/sso.auth.js} +37 -2
- package/dist/providers/plugins/sso/sso.auth.js.map +1 -0
- package/dist/providers/plugins/sso/sso.health.d.ts +44 -0
- package/dist/providers/plugins/sso/sso.health.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.health.js +178 -0
- package/dist/providers/plugins/sso/sso.health.js.map +1 -0
- package/dist/providers/plugins/sso/sso.http-client.d.ts +24 -0
- package/dist/providers/plugins/sso/sso.http-client.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.http-client.js +193 -0
- package/dist/providers/plugins/sso/sso.http-client.js.map +1 -0
- package/dist/providers/plugins/sso/sso.models.d.ts +48 -0
- package/dist/providers/plugins/sso/sso.models.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.models.js +139 -0
- package/dist/providers/plugins/sso/sso.models.js.map +1 -0
- package/dist/providers/plugins/sso/sso.setup-steps.d.ts +16 -0
- package/dist/providers/plugins/sso/sso.setup-steps.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.setup-steps.js +145 -0
- package/dist/providers/plugins/sso/sso.setup-steps.js.map +1 -0
- package/dist/providers/plugins/sso/sso.template.d.ts +11 -0
- package/dist/providers/plugins/sso/sso.template.d.ts.map +1 -0
- package/dist/providers/plugins/sso/sso.template.js +35 -0
- package/dist/providers/plugins/sso/sso.template.js.map +1 -0
- package/dist/proxy/errors.d.ts.map +1 -0
- package/dist/proxy/errors.js.map +1 -0
- package/dist/proxy/http-client.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/http-client.js +50 -15
- package/dist/proxy/http-client.js.map +1 -0
- 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.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/header-injection.plugin.js +10 -3
- package/dist/proxy/plugins/header-injection.plugin.js.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/index.d.ts +4 -2
- package/dist/proxy/plugins/index.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/index.js +7 -5
- package/dist/proxy/plugins/index.js.map +1 -0
- package/dist/proxy/plugins/logging.plugin.d.ts +22 -0
- package/dist/proxy/plugins/logging.plugin.d.ts.map +1 -0
- package/dist/proxy/plugins/logging.plugin.js +156 -0
- package/dist/proxy/plugins/logging.plugin.js.map +1 -0
- 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 +310 -0
- package/dist/proxy/plugins/metrics-sync.plugin.js.map +1 -0
- package/dist/proxy/plugins/registry.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/registry.js +9 -2
- package/dist/proxy/plugins/registry.js.map +1 -0
- package/dist/proxy/plugins/sso-auth.plugin.d.ts.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/sso-auth.plugin.js +1 -1
- package/dist/proxy/plugins/sso-auth.plugin.js.map +1 -0
- package/dist/{utils/proxy → proxy}/plugins/types.d.ts +8 -4
- package/dist/proxy/plugins/types.d.ts.map +1 -0
- package/dist/proxy/plugins/types.js.map +1 -0
- package/dist/{utils/proxy → proxy}/types.d.ts +7 -0
- package/dist/proxy/types.d.ts.map +1 -0
- package/dist/proxy/types.js.map +1 -0
- 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 +75 -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 +56 -61
- package/dist/utils/codemie-proxy.js.map +1 -1
- package/dist/utils/config-loader.d.ts +1 -6
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +49 -93
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/credential-store.d.ts +1 -1
- package/dist/utils/credential-store.d.ts.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 -22
- 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 -288
- 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 -49
- package/dist/analytics/remote-submission/metric-transformer.d.ts.map +0 -1
- package/dist/analytics/remote-submission/metric-transformer.js +0 -175
- package/dist/analytics/remote-submission/metric-transformer.js.map +0 -1
- package/dist/analytics/remote-submission/submitter.d.ts +0 -78
- package/dist/analytics/remote-submission/submitter.d.ts.map +0 -1
- package/dist/analytics/remote-submission/submitter.js +0 -381
- package/dist/analytics/remote-submission/submitter.js.map +0 -1
- package/dist/analytics/remote-submission/types.d.ts +0 -169
- 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/cli/commands/doctor/providers/AIRunSSOProviderCheck.d.ts +0 -11
- package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.d.ts.map +0 -1
- package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.js +0 -264
- package/dist/cli/commands/doctor/providers/AIRunSSOProviderCheck.js.map +0 -1
- package/dist/cli/commands/doctor/providers/BaseProviderCheck.d.ts +0 -12
- package/dist/cli/commands/doctor/providers/BaseProviderCheck.d.ts.map +0 -1
- package/dist/cli/commands/doctor/providers/BaseProviderCheck.js +0 -12
- package/dist/cli/commands/doctor/providers/BaseProviderCheck.js.map +0 -1
- package/dist/cli/commands/doctor/providers/StandardProviderCheck.d.ts +0 -11
- package/dist/cli/commands/doctor/providers/StandardProviderCheck.d.ts.map +0 -1
- package/dist/cli/commands/doctor/providers/StandardProviderCheck.js +0 -97
- package/dist/cli/commands/doctor/providers/StandardProviderCheck.js.map +0 -1
- package/dist/cli/commands/doctor/providers/index.d.ts +0 -30
- package/dist/cli/commands/doctor/providers/index.d.ts.map +0 -1
- package/dist/cli/commands/doctor/providers/index.js +0 -66
- package/dist/cli/commands/doctor/providers/index.js.map +0 -1
- package/dist/types/sso.d.ts +0 -42
- package/dist/types/sso.d.ts.map +0 -1
- package/dist/types/sso.js +0 -2
- package/dist/types/sso.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/async-tips.d.ts +0 -64
- package/dist/utils/async-tips.d.ts.map +0 -1
- package/dist/utils/async-tips.js +0 -203
- package/dist/utils/async-tips.js.map +0 -1
- package/dist/utils/codemie-integration-validator.d.ts +0 -18
- package/dist/utils/codemie-integration-validator.d.ts.map +0 -1
- package/dist/utils/codemie-integration-validator.js +0 -119
- package/dist/utils/codemie-integration-validator.js.map +0 -1
- package/dist/utils/codemie-model-fetcher.d.ts +0 -11
- package/dist/utils/codemie-model-fetcher.d.ts.map +0 -1
- package/dist/utils/codemie-model-fetcher.js +0 -317
- package/dist/utils/codemie-model-fetcher.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
- package/dist/utils/health-checker.d.ts +0 -20
- package/dist/utils/health-checker.d.ts.map +0 -1
- package/dist/utils/health-checker.js +0 -172
- package/dist/utils/health-checker.js.map +0 -1
- package/dist/utils/model-fetcher.d.ts +0 -21
- package/dist/utils/model-fetcher.d.ts.map +0 -1
- package/dist/utils/model-fetcher.js +0 -148
- package/dist/utils/model-fetcher.js.map +0 -1
- package/dist/utils/proxy/errors.d.ts.map +0 -1
- package/dist/utils/proxy/errors.js.map +0 -1
- package/dist/utils/proxy/http-client.d.ts.map +0 -1
- package/dist/utils/proxy/http-client.js.map +0 -1
- package/dist/utils/proxy/plugins/analytics.plugin.d.ts +0 -19
- package/dist/utils/proxy/plugins/analytics.plugin.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/analytics.plugin.js +0 -84
- package/dist/utils/proxy/plugins/analytics.plugin.js.map +0 -1
- package/dist/utils/proxy/plugins/header-injection.plugin.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/header-injection.plugin.js.map +0 -1
- package/dist/utils/proxy/plugins/index.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/index.js.map +0 -1
- package/dist/utils/proxy/plugins/registry.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/registry.js.map +0 -1
- package/dist/utils/proxy/plugins/sso-auth.plugin.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/sso-auth.plugin.js.map +0 -1
- package/dist/utils/proxy/plugins/types.d.ts.map +0 -1
- package/dist/utils/proxy/plugins/types.js.map +0 -1
- package/dist/utils/proxy/types.d.ts.map +0 -1
- package/dist/utils/proxy/types.js.map +0 -1
- package/dist/utils/sso-auth.d.ts +0 -15
- package/dist/utils/sso-auth.d.ts.map +0 -1
- package/dist/utils/sso-auth.js.map +0 -1
- package/dist/utils/tips.d.ts +0 -35
- package/dist/utils/tips.d.ts.map +0 -1
- package/dist/utils/tips.js +0 -93
- package/dist/utils/tips.js.map +0 -1
- /package/dist/{utils/proxy → proxy}/errors.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/errors.js +0 -0
- /package/dist/{utils/proxy → proxy}/http-client.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/plugins/header-injection.plugin.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/plugins/registry.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/plugins/sso-auth.plugin.d.ts +0 -0
- /package/dist/{utils/proxy → proxy}/plugins/types.js +0 -0
- /package/dist/{utils/proxy → proxy}/types.js +0 -0
|
@@ -0,0 +1,700 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Metrics Adapter
|
|
3
|
+
*
|
|
4
|
+
* Implements metrics support for Claude Code agent.
|
|
5
|
+
* Handles Claude-specific file formats and parsing logic.
|
|
6
|
+
*/
|
|
7
|
+
import { readFile, readdir } from 'fs/promises';
|
|
8
|
+
import { extname, join, dirname } from 'path';
|
|
9
|
+
import { homedir } from 'os';
|
|
10
|
+
import { existsSync } from 'fs';
|
|
11
|
+
import { BaseMetricsAdapter } from '../core/BaseMetricsAdapter.js';
|
|
12
|
+
import { logger } from '../../utils/logger.js';
|
|
13
|
+
import { parseMultiLineJSON } from '../../utils/json-parser.js';
|
|
14
|
+
import { HistoryParser } from './history-parser.js';
|
|
15
|
+
export class ClaudeMetricsAdapter extends BaseMetricsAdapter {
|
|
16
|
+
// Note: dataPaths now comes from ClaudePluginMetadata passed via constructor
|
|
17
|
+
/**
|
|
18
|
+
* Check if file matches Claude session pattern
|
|
19
|
+
* Pattern: ~/.claude/projects/{hash}/{session-id}.jsonl
|
|
20
|
+
* Note: Claude uses JSONL (JSON Lines) format, not regular JSON
|
|
21
|
+
* Matches UUID format but EXCLUDES agent-* files (those are sub-agents)
|
|
22
|
+
*/
|
|
23
|
+
matchesSessionPattern(path) {
|
|
24
|
+
// Explicitly reject agent-* files (sub-agents/sidechains)
|
|
25
|
+
if (path.includes('/agent-') || path.includes('\\agent-')) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
// Match UUID session files only
|
|
29
|
+
// UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.jsonl
|
|
30
|
+
return /\.claude\/projects\/[^/]+\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/.test(path);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Find all agent-*.jsonl files in the same directory as the session file
|
|
34
|
+
* that belong to the same Claude sessionId (filters by sessionId)
|
|
35
|
+
*
|
|
36
|
+
* Agent files contain sub-agent/tool execution data with potentially different models
|
|
37
|
+
*
|
|
38
|
+
* @param sessionFilePath - Path to the main session file
|
|
39
|
+
* @returns Array of agent file paths matching the same sessionId
|
|
40
|
+
*/
|
|
41
|
+
async findAgentFiles(sessionFilePath) {
|
|
42
|
+
try {
|
|
43
|
+
const dir = dirname(sessionFilePath);
|
|
44
|
+
if (!existsSync(dir)) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
// Read the sessionId from the file (may not be on first line)
|
|
48
|
+
// First line is often file-history-snapshot without sessionId
|
|
49
|
+
const mainContent = await readFile(sessionFilePath, 'utf-8');
|
|
50
|
+
const lines = mainContent.split('\n').filter(l => l.trim());
|
|
51
|
+
let targetSessionId;
|
|
52
|
+
for (const line of lines.slice(0, 10)) { // Check first 10 lines
|
|
53
|
+
try {
|
|
54
|
+
const event = JSON.parse(line);
|
|
55
|
+
if (event.sessionId) {
|
|
56
|
+
targetSessionId = event.sessionId;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!targetSessionId) {
|
|
65
|
+
logger.debug(`[ClaudeMetrics] No sessionId found in ${sessionFilePath}`);
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
// Find all agent files in the directory
|
|
69
|
+
const files = await readdir(dir);
|
|
70
|
+
const agentFileCandidates = files
|
|
71
|
+
.filter(f => f.startsWith('agent-') && f.endsWith('.jsonl'))
|
|
72
|
+
.map(f => join(dir, f));
|
|
73
|
+
// Filter agent files by matching sessionId
|
|
74
|
+
const matchingAgentFiles = [];
|
|
75
|
+
for (const agentFile of agentFileCandidates) {
|
|
76
|
+
try {
|
|
77
|
+
const content = await readFile(agentFile, 'utf-8');
|
|
78
|
+
const firstLine = content.split('\n')[0];
|
|
79
|
+
if (firstLine) {
|
|
80
|
+
const firstEvent = JSON.parse(firstLine);
|
|
81
|
+
if (firstEvent.sessionId === targetSessionId) {
|
|
82
|
+
matchingAgentFiles.push(agentFile);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Skip files that can't be parsed
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
logger.debug(`[ClaudeMetrics] Found ${matchingAgentFiles.length} agent files for session ${targetSessionId}`);
|
|
92
|
+
return matchingAgentFiles;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
logger.debug(`[ClaudeMetrics] Failed to find agent files:`, error);
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Parse all models from agent files
|
|
101
|
+
* Agent files may contain different models used by sub-agents/tools
|
|
102
|
+
*
|
|
103
|
+
* @param agentFilePaths - Array of agent file paths
|
|
104
|
+
* @returns Map of model names to call counts
|
|
105
|
+
*/
|
|
106
|
+
async parseModelsFromAgentFiles(agentFilePaths) {
|
|
107
|
+
const modelCalls = new Map();
|
|
108
|
+
for (const filePath of agentFilePaths) {
|
|
109
|
+
try {
|
|
110
|
+
const content = await readFile(filePath, 'utf-8');
|
|
111
|
+
const jsonObjects = parseMultiLineJSON(content);
|
|
112
|
+
for (const obj of jsonObjects) {
|
|
113
|
+
if (obj.message?.model) {
|
|
114
|
+
const model = obj.message.model;
|
|
115
|
+
modelCalls.set(model, (modelCalls.get(model) || 0) + 1);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
logger.debug(`[ClaudeMetrics] Failed to parse agent file ${filePath}:`, error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return modelCalls;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Extract session ID from Claude file path
|
|
127
|
+
* Examples:
|
|
128
|
+
* ~/.claude/projects/abc123/session-def-456.jsonl → session-def-456
|
|
129
|
+
* ~/.claude/projects/abc123/agent-abc123de.jsonl → agent-abc123de
|
|
130
|
+
*/
|
|
131
|
+
extractSessionId(path) {
|
|
132
|
+
const match = path.match(/([a-z0-9-]+)\.jsonl$/);
|
|
133
|
+
return match?.[1] || '';
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Parse Claude session file (multi-line JSON objects) and extract metrics
|
|
137
|
+
* Each object contains a conversation turn with message data
|
|
138
|
+
*/
|
|
139
|
+
async parseSessionFile(path) {
|
|
140
|
+
try {
|
|
141
|
+
const content = await readFile(path, 'utf-8');
|
|
142
|
+
const jsonObjects = parseMultiLineJSON(content);
|
|
143
|
+
if (jsonObjects.length === 0) {
|
|
144
|
+
throw new Error('Empty session file');
|
|
145
|
+
}
|
|
146
|
+
// Parse first object to get session metadata
|
|
147
|
+
const firstObject = jsonObjects[0];
|
|
148
|
+
const sessionId = firstObject.sessionId || '';
|
|
149
|
+
const workingDirectory = firstObject.cwd || '';
|
|
150
|
+
const gitBranch = firstObject.gitBranch;
|
|
151
|
+
// Aggregate metrics from all objects
|
|
152
|
+
let inputTokens = 0;
|
|
153
|
+
let outputTokens = 0;
|
|
154
|
+
let cacheCreationTokens = 0;
|
|
155
|
+
let cacheReadTokens = 0;
|
|
156
|
+
// Track all models (not just first)
|
|
157
|
+
const modelCalls = new Map();
|
|
158
|
+
// Tool tracking maps
|
|
159
|
+
const toolCalls = [];
|
|
160
|
+
const toolUseMap = new Map();
|
|
161
|
+
for (const turn of jsonObjects) {
|
|
162
|
+
// Track all models with call counts
|
|
163
|
+
if (turn.message?.model) {
|
|
164
|
+
const model = turn.message.model;
|
|
165
|
+
modelCalls.set(model, (modelCalls.get(model) || 0) + 1);
|
|
166
|
+
}
|
|
167
|
+
// Aggregate token usage
|
|
168
|
+
if (turn.message?.usage) {
|
|
169
|
+
const usage = turn.message.usage;
|
|
170
|
+
inputTokens += usage.input_tokens || 0;
|
|
171
|
+
outputTokens += usage.output_tokens || 0;
|
|
172
|
+
cacheCreationTokens += usage.cache_creation_input_tokens || 0;
|
|
173
|
+
cacheReadTokens += usage.cache_read_input_tokens || 0;
|
|
174
|
+
}
|
|
175
|
+
// Extract tool use events (from assistant messages)
|
|
176
|
+
if (turn.message?.role === 'assistant' && Array.isArray(turn.message.content)) {
|
|
177
|
+
for (const block of turn.message.content) {
|
|
178
|
+
if (block.type === 'tool_use') {
|
|
179
|
+
// Store tool_use for later correlation
|
|
180
|
+
toolUseMap.set(block.id, {
|
|
181
|
+
name: block.name,
|
|
182
|
+
timestamp: turn.timestamp || Date.now(),
|
|
183
|
+
input: block.input
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Extract tool result events (from user messages)
|
|
189
|
+
if (turn.message?.role === 'user' && Array.isArray(turn.message.content)) {
|
|
190
|
+
for (const block of turn.message.content) {
|
|
191
|
+
if (block.type === 'tool_result') {
|
|
192
|
+
const toolUse = toolUseMap.get(block.tool_use_id);
|
|
193
|
+
if (toolUse) {
|
|
194
|
+
const toolCall = {
|
|
195
|
+
id: block.tool_use_id,
|
|
196
|
+
name: toolUse.name, // Use raw tool name
|
|
197
|
+
timestamp: toolUse.timestamp,
|
|
198
|
+
status: block.is_error ? 'error' : 'success',
|
|
199
|
+
input: toolUse.input,
|
|
200
|
+
error: block.is_error ? (typeof block.content === 'string' ? block.content : JSON.stringify(block.content)) : undefined
|
|
201
|
+
};
|
|
202
|
+
// Extract file operation details
|
|
203
|
+
const fileOp = this.extractFileOperation(toolUse.name, toolUse.input);
|
|
204
|
+
if (fileOp) {
|
|
205
|
+
toolCall.fileOperation = fileOp;
|
|
206
|
+
}
|
|
207
|
+
toolCalls.push(toolCall);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Parse agent files to get models from sub-agents/tools
|
|
214
|
+
const agentFiles = await this.findAgentFiles(path);
|
|
215
|
+
const agentModels = await this.parseModelsFromAgentFiles(agentFiles);
|
|
216
|
+
// Merge agent models with session models
|
|
217
|
+
for (const [model, count] of agentModels) {
|
|
218
|
+
modelCalls.set(model, (modelCalls.get(model) || 0) + count);
|
|
219
|
+
}
|
|
220
|
+
// Build aggregated tool usage summary
|
|
221
|
+
const toolUsageSummary = this.buildToolUsageSummary(toolCalls);
|
|
222
|
+
// Get all models (raw, unnormalized)
|
|
223
|
+
const allModels = Array.from(modelCalls.keys());
|
|
224
|
+
const snapshot = {
|
|
225
|
+
sessionId,
|
|
226
|
+
timestamp: Date.now(),
|
|
227
|
+
tokens: {
|
|
228
|
+
input: inputTokens,
|
|
229
|
+
output: outputTokens,
|
|
230
|
+
cacheCreation: cacheCreationTokens > 0 ? cacheCreationTokens : undefined,
|
|
231
|
+
cacheRead: cacheReadTokens > 0 ? cacheReadTokens : undefined
|
|
232
|
+
},
|
|
233
|
+
toolCalls,
|
|
234
|
+
toolUsageSummary,
|
|
235
|
+
turnCount: jsonObjects.length,
|
|
236
|
+
model: allModels.length > 0 ? allModels[0] : undefined, // Primary model for backward compat
|
|
237
|
+
metadata: {
|
|
238
|
+
workingDirectory,
|
|
239
|
+
gitBranch,
|
|
240
|
+
totalInputTokens: inputTokens + cacheCreationTokens + cacheReadTokens,
|
|
241
|
+
models: allModels, // All raw model names (unnormalized)
|
|
242
|
+
modelCalls: Object.fromEntries(modelCalls) // Map of model -> call count
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
logger.debug(`[ClaudeMetrics] Parsed session ${sessionId}: ${inputTokens} input, ${outputTokens} output, ` +
|
|
246
|
+
`${cacheReadTokens} cache read, ${toolCalls.length} tool calls, ${allModels.length} models`);
|
|
247
|
+
return snapshot;
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
logger.error(`[ClaudeMetrics] Failed to parse session file: ${path}`, error);
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Extract file operation details from tool input and result
|
|
256
|
+
* Uses raw tool names (provider-specific, e.g., "Write", "Edit", "Read")
|
|
257
|
+
*
|
|
258
|
+
* @param toolName - Tool name (Read, Write, Edit, etc.)
|
|
259
|
+
* @param input - Tool input parameters
|
|
260
|
+
* @param toolUseResult - Tool execution result with structured data (optional)
|
|
261
|
+
*/
|
|
262
|
+
extractFileOperation(toolName, input, toolUseResult) {
|
|
263
|
+
// Map raw tool names to operation types
|
|
264
|
+
const typeMap = {
|
|
265
|
+
'Read': 'read',
|
|
266
|
+
'Write': 'write',
|
|
267
|
+
'Edit': 'edit',
|
|
268
|
+
// Note: Bash excluded - too varied to categorize reliably
|
|
269
|
+
'Grep': 'grep',
|
|
270
|
+
'Glob': 'glob'
|
|
271
|
+
};
|
|
272
|
+
const type = typeMap[toolName];
|
|
273
|
+
if (!type)
|
|
274
|
+
return undefined;
|
|
275
|
+
const fileOp = { type };
|
|
276
|
+
// Extract file path from toolUseResult (most accurate) or input
|
|
277
|
+
const filePath = toolUseResult?.filePath || toolUseResult?.file?.filePath || input?.file_path || input?.path;
|
|
278
|
+
if (filePath) {
|
|
279
|
+
fileOp.path = filePath;
|
|
280
|
+
fileOp.format = this.extractFormat(filePath);
|
|
281
|
+
fileOp.language = this.detectLanguage(filePath);
|
|
282
|
+
}
|
|
283
|
+
else if (input?.pattern) {
|
|
284
|
+
// For Grep/Glob operations
|
|
285
|
+
fileOp.pattern = input.pattern;
|
|
286
|
+
}
|
|
287
|
+
// Extract line changes from toolUseResult (most accurate source)
|
|
288
|
+
if (toolName === 'Write') {
|
|
289
|
+
// Write tool: calculate from toolUseResult.content or toolUseResult.file or input.content
|
|
290
|
+
const content = toolUseResult?.content || toolUseResult?.file?.content || input?.content;
|
|
291
|
+
if (content) {
|
|
292
|
+
const lines = content.split('\n');
|
|
293
|
+
fileOp.linesAdded = lines.length;
|
|
294
|
+
}
|
|
295
|
+
else if (toolUseResult?.file?.numLines) {
|
|
296
|
+
fileOp.linesAdded = toolUseResult.file.numLines;
|
|
297
|
+
}
|
|
298
|
+
else if (toolUseResult?.file?.totalLines) {
|
|
299
|
+
fileOp.linesAdded = toolUseResult.file.totalLines;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
else if (toolName === 'Edit' && toolUseResult?.structuredPatch) {
|
|
303
|
+
// Edit tool: use structured patch to get accurate line counts
|
|
304
|
+
let added = 0;
|
|
305
|
+
let removed = 0;
|
|
306
|
+
for (const patch of toolUseResult.structuredPatch) {
|
|
307
|
+
// Parse patch.lines array: "+line" = added, "-line" = removed, " line" = unchanged
|
|
308
|
+
for (const line of patch.lines || []) {
|
|
309
|
+
if (line.startsWith('+')) {
|
|
310
|
+
added++;
|
|
311
|
+
}
|
|
312
|
+
else if (line.startsWith('-')) {
|
|
313
|
+
removed++;
|
|
314
|
+
}
|
|
315
|
+
// Lines starting with space are unchanged (context)
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (added > 0)
|
|
319
|
+
fileOp.linesAdded = added;
|
|
320
|
+
if (removed > 0)
|
|
321
|
+
fileOp.linesRemoved = removed;
|
|
322
|
+
// If no adds/removes but edit happened, count as modified
|
|
323
|
+
if (added === 0 && removed === 0 && toolUseResult.structuredPatch.length > 0) {
|
|
324
|
+
fileOp.linesModified = toolUseResult.structuredPatch[0].oldLines || 0;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
else if (toolName === 'Read' && toolUseResult?.file) {
|
|
328
|
+
// Read tool: no line changes, but we have file info
|
|
329
|
+
// numLines already captured above
|
|
330
|
+
}
|
|
331
|
+
return fileOp;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Extract file format from path
|
|
335
|
+
*/
|
|
336
|
+
extractFormat(path) {
|
|
337
|
+
const ext = extname(path);
|
|
338
|
+
return ext ? ext.slice(1) : undefined;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Detect programming language from file extension
|
|
342
|
+
*/
|
|
343
|
+
detectLanguage(path) {
|
|
344
|
+
const ext = extname(path).toLowerCase();
|
|
345
|
+
const langMap = {
|
|
346
|
+
'.ts': 'typescript',
|
|
347
|
+
'.tsx': 'typescript',
|
|
348
|
+
'.js': 'javascript',
|
|
349
|
+
'.jsx': 'javascript',
|
|
350
|
+
'.py': 'python',
|
|
351
|
+
'.java': 'java',
|
|
352
|
+
'.go': 'go',
|
|
353
|
+
'.rs': 'rust',
|
|
354
|
+
'.cpp': 'cpp',
|
|
355
|
+
'.c': 'c',
|
|
356
|
+
'.rb': 'ruby',
|
|
357
|
+
'.php': 'php',
|
|
358
|
+
'.swift': 'swift',
|
|
359
|
+
'.kt': 'kotlin',
|
|
360
|
+
'.md': 'markdown',
|
|
361
|
+
'.json': 'json',
|
|
362
|
+
'.yaml': 'yaml',
|
|
363
|
+
'.yml': 'yaml'
|
|
364
|
+
};
|
|
365
|
+
return langMap[ext];
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Build aggregated tool usage summary from detailed tool calls
|
|
369
|
+
*/
|
|
370
|
+
buildToolUsageSummary(toolCalls) {
|
|
371
|
+
const summaryMap = new Map();
|
|
372
|
+
for (const call of toolCalls) {
|
|
373
|
+
let summary = summaryMap.get(call.name);
|
|
374
|
+
if (!summary) {
|
|
375
|
+
summary = {
|
|
376
|
+
name: call.name,
|
|
377
|
+
count: 0,
|
|
378
|
+
successCount: 0,
|
|
379
|
+
errorCount: 0,
|
|
380
|
+
fileOperations: {}
|
|
381
|
+
};
|
|
382
|
+
summaryMap.set(call.name, summary);
|
|
383
|
+
}
|
|
384
|
+
summary.count++;
|
|
385
|
+
if (call.status === 'success') {
|
|
386
|
+
summary.successCount++;
|
|
387
|
+
}
|
|
388
|
+
else if (call.status === 'error') {
|
|
389
|
+
summary.errorCount++;
|
|
390
|
+
}
|
|
391
|
+
// Aggregate file operations
|
|
392
|
+
if (call.fileOperation) {
|
|
393
|
+
const opType = call.fileOperation.type;
|
|
394
|
+
summary.fileOperations[opType] = (summary.fileOperations[opType] || 0) + 1;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return Array.from(summaryMap.values());
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Claude uses hash-based watermark (full file rewrite)
|
|
401
|
+
*/
|
|
402
|
+
getWatermarkStrategy() {
|
|
403
|
+
return 'hash';
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Claude initialization delay: 500ms
|
|
407
|
+
*/
|
|
408
|
+
getInitDelay() {
|
|
409
|
+
return 500;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Get user prompts for a specific session
|
|
413
|
+
* Claude stores user prompts in history file (path from metadata)
|
|
414
|
+
*
|
|
415
|
+
* @param sessionId - Claude session ID
|
|
416
|
+
* @param fromTimestamp - Start timestamp (Unix ms) - optional
|
|
417
|
+
* @param toTimestamp - End timestamp (Unix ms) - optional
|
|
418
|
+
* @returns Array of user prompts
|
|
419
|
+
*/
|
|
420
|
+
async getUserPrompts(sessionId, fromTimestamp, toTimestamp) {
|
|
421
|
+
try {
|
|
422
|
+
// Get history file path from metadata
|
|
423
|
+
if (!this.metadata?.dataPaths?.home || !this.metadata?.dataPaths?.history) {
|
|
424
|
+
logger.debug(`[ClaudeMetrics] No history path configured in metadata`);
|
|
425
|
+
return [];
|
|
426
|
+
}
|
|
427
|
+
const home = this.metadata.dataPaths.home.replace('~', homedir());
|
|
428
|
+
const historyPath = join(home, this.metadata.dataPaths.history);
|
|
429
|
+
const parser = new HistoryParser(historyPath);
|
|
430
|
+
// Get prompts for this session within time range
|
|
431
|
+
const prompts = await parser.getPromptsInRange(sessionId, fromTimestamp, toTimestamp);
|
|
432
|
+
logger.debug(`[ClaudeMetrics] Found ${prompts.length} user prompts for session ${sessionId}`);
|
|
433
|
+
return prompts;
|
|
434
|
+
}
|
|
435
|
+
catch (error) {
|
|
436
|
+
logger.error(`[ClaudeMetrics] Failed to get user prompts for session ${sessionId}:`, error);
|
|
437
|
+
return [];
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Parse session file and extract incremental delta records
|
|
442
|
+
* Returns array of delta records for turns with token usage
|
|
443
|
+
*
|
|
444
|
+
* Automatically discovers and parses ALL agent files for the session
|
|
445
|
+
* to capture sub-agents/sidechains that share the same Claude sessionId
|
|
446
|
+
*
|
|
447
|
+
* @param path - Path to agent session file
|
|
448
|
+
* @param processedRecordIds - Set of record IDs already written to metrics
|
|
449
|
+
* @param attachedUserPromptTexts - Set of user prompt texts already attached (persisted from sync state)
|
|
450
|
+
*/
|
|
451
|
+
async parseIncrementalMetrics(path, processedRecordIds = new Set(), attachedUserPromptTexts = new Set()) {
|
|
452
|
+
try {
|
|
453
|
+
// Find ALL agent files for this session (including sidechains)
|
|
454
|
+
const agentFiles = await this.findAgentFiles(path);
|
|
455
|
+
// Add the main file to the list if not already included
|
|
456
|
+
if (!agentFiles.includes(path)) {
|
|
457
|
+
agentFiles.unshift(path);
|
|
458
|
+
}
|
|
459
|
+
// Track initial size to determine newly attached prompts
|
|
460
|
+
const initialAttachedCount = attachedUserPromptTexts.size;
|
|
461
|
+
// Parse all agent files and merge deltas
|
|
462
|
+
const allDeltas = [];
|
|
463
|
+
let maxLastLine = 0;
|
|
464
|
+
for (const agentFile of agentFiles) {
|
|
465
|
+
const { deltas, lastLine } = await this.parseAgentFileDeltas(agentFile, processedRecordIds, attachedUserPromptTexts);
|
|
466
|
+
allDeltas.push(...deltas);
|
|
467
|
+
maxLastLine = Math.max(maxLastLine, lastLine);
|
|
468
|
+
}
|
|
469
|
+
// Calculate newly attached prompts (after processing - before processing)
|
|
470
|
+
const newlyAttachedPrompts = Array.from(attachedUserPromptTexts).slice(initialAttachedCount);
|
|
471
|
+
return {
|
|
472
|
+
deltas: allDeltas,
|
|
473
|
+
lastLine: maxLastLine,
|
|
474
|
+
newlyAttachedPrompts
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
logger.error(`[ClaudeMetrics] Failed to parse incremental metrics: ${path}`, error);
|
|
479
|
+
throw error;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Parse a single agent file for deltas
|
|
484
|
+
* Extracted from parseIncrementalMetrics for reuse across multiple files
|
|
485
|
+
*
|
|
486
|
+
* @param path - Path to agent file
|
|
487
|
+
* @param processedRecordIds - Set of record IDs already processed
|
|
488
|
+
* @param attachedUserPrompts - Set of user prompt display texts that have been attached (shared across files)
|
|
489
|
+
*/
|
|
490
|
+
async parseAgentFileDeltas(path, processedRecordIds, attachedUserPrompts = new Set()) {
|
|
491
|
+
try {
|
|
492
|
+
const content = await readFile(path, 'utf-8');
|
|
493
|
+
const jsonObjects = parseMultiLineJSON(content);
|
|
494
|
+
if (jsonObjects.length === 0) {
|
|
495
|
+
return { deltas: [], lastLine: 0 };
|
|
496
|
+
}
|
|
497
|
+
// FIRST PASS: Build tool_result map from ALL jsonObjects
|
|
498
|
+
// This ensures we can match tool_results that come after tool_use in the file
|
|
499
|
+
const toolResultMap = new Map();
|
|
500
|
+
for (const record of jsonObjects) {
|
|
501
|
+
if (record.message?.role === 'user' && Array.isArray(record.message.content)) {
|
|
502
|
+
for (const block of record.message.content) {
|
|
503
|
+
if (block.type === 'tool_result') {
|
|
504
|
+
toolResultMap.set(block.tool_use_id, {
|
|
505
|
+
timestamp: record.timestamp,
|
|
506
|
+
isError: block.is_error || false,
|
|
507
|
+
errorMessage: block.is_error ? (typeof block.content === 'string' ? block.content : JSON.stringify(block.content)) : undefined,
|
|
508
|
+
durationMs: block.durationMs,
|
|
509
|
+
toolUseResult: record.toolUseResult // Contains structured patch and file details
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
// Extract session ID from first record that has one
|
|
516
|
+
let extractedSessionId = '';
|
|
517
|
+
for (const record of jsonObjects) {
|
|
518
|
+
if (record.sessionId) {
|
|
519
|
+
extractedSessionId = record.sessionId;
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
// ZERO PASS: Get user prompts from history.jsonl and build UUID map
|
|
524
|
+
// Map user prompt UUIDs to prompts for direct correlation
|
|
525
|
+
const userPromptsByUuid = new Map();
|
|
526
|
+
try {
|
|
527
|
+
const userPrompts = await this.getUserPrompts(extractedSessionId);
|
|
528
|
+
logger.debug(`[ClaudeMetrics] Found ${userPrompts.length} user prompts in history.jsonl for session ${extractedSessionId}`);
|
|
529
|
+
// Build a map of record UUIDs to user prompts
|
|
530
|
+
// We'll correlate by finding user messages that match prompts
|
|
531
|
+
for (const record of jsonObjects) {
|
|
532
|
+
if (record.type === 'user' &&
|
|
533
|
+
record.message?.role === 'user' &&
|
|
534
|
+
typeof record.message.content === 'string') {
|
|
535
|
+
// This is an initial user message (not a tool result)
|
|
536
|
+
const messageContent = record.message.content;
|
|
537
|
+
const recordTime = typeof record.timestamp === 'string'
|
|
538
|
+
? new Date(record.timestamp).getTime()
|
|
539
|
+
: record.timestamp;
|
|
540
|
+
// Find matching prompt from history.jsonl by content or timestamp
|
|
541
|
+
const matchingPrompt = userPrompts.find(p => {
|
|
542
|
+
// Match by content (most reliable)
|
|
543
|
+
if (p.display === messageContent) {
|
|
544
|
+
return true;
|
|
545
|
+
}
|
|
546
|
+
// Fallback: match by timestamp (±10 seconds window for initial prompts)
|
|
547
|
+
const timeDiff = Math.abs(p.timestamp - recordTime);
|
|
548
|
+
return timeDiff <= 10000; // 10 second window
|
|
549
|
+
});
|
|
550
|
+
if (matchingPrompt && record.uuid) {
|
|
551
|
+
userPromptsByUuid.set(record.uuid, matchingPrompt);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
logger.debug(`[ClaudeMetrics] Matched ${userPromptsByUuid.size} prompts to message UUIDs`);
|
|
556
|
+
}
|
|
557
|
+
catch (error) {
|
|
558
|
+
logger.debug(`[ClaudeMetrics] Could not load user prompts (non-critical):`, error);
|
|
559
|
+
// Continue without user prompts - non-critical feature
|
|
560
|
+
}
|
|
561
|
+
// SECOND PASS: Create deltas for NEW records with usage (assistant messages)
|
|
562
|
+
// Skip records that have already been processed
|
|
563
|
+
const deltas = [];
|
|
564
|
+
const sessionModels = []; // Track all unique models
|
|
565
|
+
let lastUserPrompt;
|
|
566
|
+
for (const record of jsonObjects) {
|
|
567
|
+
// Track user prompts as we iterate (BEFORE processing/skipping)
|
|
568
|
+
// Only update lastUserPrompt for INITIAL user messages (with string content), not tool_result messages
|
|
569
|
+
if (record.type === 'user' &&
|
|
570
|
+
record.uuid &&
|
|
571
|
+
userPromptsByUuid.has(record.uuid) &&
|
|
572
|
+
record.message?.role === 'user' &&
|
|
573
|
+
typeof record.message.content === 'string') {
|
|
574
|
+
lastUserPrompt = userPromptsByUuid.get(record.uuid);
|
|
575
|
+
}
|
|
576
|
+
// Skip records already processed
|
|
577
|
+
if (processedRecordIds.has(record.uuid)) {
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
// Collect all unique models from all records (not just first)
|
|
581
|
+
if (record.message?.model && !sessionModels.includes(record.message.model)) {
|
|
582
|
+
sessionModels.push(record.message.model);
|
|
583
|
+
}
|
|
584
|
+
// Create delta for records with token usage
|
|
585
|
+
if (record.message?.usage && record.message?.role === 'assistant') {
|
|
586
|
+
// Check if this record has tool_use blocks waiting for tool_results
|
|
587
|
+
let hasUnresolvedTools = false;
|
|
588
|
+
if (Array.isArray(record.message.content)) {
|
|
589
|
+
for (const block of record.message.content) {
|
|
590
|
+
if (block.type === 'tool_use') {
|
|
591
|
+
if (!toolResultMap.has(block.id)) {
|
|
592
|
+
hasUnresolvedTools = true;
|
|
593
|
+
break;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
// Skip records with tool_use blocks that haven't received tool_results yet
|
|
599
|
+
if (hasUnresolvedTools) {
|
|
600
|
+
logger.debug(`[ClaudeMetrics] Skipping record ${record.uuid} - waiting for tool results`);
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
const usage = record.message.usage;
|
|
604
|
+
const inputTokens = usage.input_tokens || 0;
|
|
605
|
+
const outputTokens = usage.output_tokens || 0;
|
|
606
|
+
const cacheCreationTokens = usage.cache_creation_input_tokens || 0;
|
|
607
|
+
const cacheReadTokens = usage.cache_read_input_tokens || 0;
|
|
608
|
+
// Extract tool_use IDs from this record
|
|
609
|
+
const tools = {};
|
|
610
|
+
const toolStatus = {};
|
|
611
|
+
const fileOperations = [];
|
|
612
|
+
let apiErrorMessage;
|
|
613
|
+
if (Array.isArray(record.message.content)) {
|
|
614
|
+
for (const block of record.message.content) {
|
|
615
|
+
if (block.type === 'tool_use') {
|
|
616
|
+
// block IS the tool_use with name and input
|
|
617
|
+
const toolResult = toolResultMap.get(block.id);
|
|
618
|
+
// Only count if we have tool_result (tool was executed)
|
|
619
|
+
if (toolResult) {
|
|
620
|
+
// Use raw tool name (provider-specific)
|
|
621
|
+
const toolName = block.name;
|
|
622
|
+
tools[toolName] = (tools[toolName] || 0) + 1;
|
|
623
|
+
// Track success/failure
|
|
624
|
+
if (!toolStatus[toolName]) {
|
|
625
|
+
toolStatus[toolName] = { success: 0, failure: 0 };
|
|
626
|
+
}
|
|
627
|
+
if (toolResult.isError) {
|
|
628
|
+
toolStatus[toolName].failure++;
|
|
629
|
+
// Capture first error message
|
|
630
|
+
if (!apiErrorMessage && toolResult.errorMessage) {
|
|
631
|
+
apiErrorMessage = toolResult.errorMessage;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
toolStatus[toolName].success++;
|
|
636
|
+
// Only extract file operations for successful tool calls
|
|
637
|
+
const fileOp = this.extractFileOperation(toolName, block.input, toolResult.toolUseResult);
|
|
638
|
+
if (fileOp) {
|
|
639
|
+
// Add durationMs if available
|
|
640
|
+
if (toolResult.durationMs) {
|
|
641
|
+
fileOp.durationMs = toolResult.durationMs;
|
|
642
|
+
}
|
|
643
|
+
fileOperations.push(fileOp);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
// Include user prompt ONLY for the first assistant response after a user prompt
|
|
651
|
+
// Use shared Set to prevent duplication across ALL agent files
|
|
652
|
+
const userPrompts = [];
|
|
653
|
+
if (lastUserPrompt && lastUserPrompt.display && !attachedUserPrompts.has(lastUserPrompt.display)) {
|
|
654
|
+
userPrompts.push({
|
|
655
|
+
count: 1,
|
|
656
|
+
text: lastUserPrompt.display
|
|
657
|
+
});
|
|
658
|
+
// Mark as attached to prevent duplicate counting across multiple assistant turns AND agent files
|
|
659
|
+
attachedUserPrompts.add(lastUserPrompt.display);
|
|
660
|
+
// Clear lastUserPrompt so it doesn't attach to subsequent assistant turns
|
|
661
|
+
lastUserPrompt = undefined;
|
|
662
|
+
}
|
|
663
|
+
// Get model and gitBranch for this turn
|
|
664
|
+
const turnModel = record.message?.model;
|
|
665
|
+
const gitBranch = record.gitBranch;
|
|
666
|
+
// Create delta record (use message UUID as recordId for backtracking)
|
|
667
|
+
const delta = {
|
|
668
|
+
recordId: record.uuid, // Use message UUID for backtracking
|
|
669
|
+
sessionId: '', // Will be set by caller
|
|
670
|
+
agentSessionId: record.sessionId || '',
|
|
671
|
+
timestamp: record.timestamp || new Date().toISOString(),
|
|
672
|
+
gitBranch, // Git branch at time of this turn
|
|
673
|
+
tokens: {
|
|
674
|
+
input: inputTokens,
|
|
675
|
+
output: outputTokens,
|
|
676
|
+
cacheCreation: cacheCreationTokens > 0 ? cacheCreationTokens : undefined,
|
|
677
|
+
cacheRead: cacheReadTokens > 0 ? cacheReadTokens : undefined
|
|
678
|
+
},
|
|
679
|
+
tools,
|
|
680
|
+
toolStatus: Object.keys(toolStatus).length > 0 ? toolStatus : undefined,
|
|
681
|
+
fileOperations: fileOperations.length > 0 ? fileOperations : undefined,
|
|
682
|
+
userPrompts: userPrompts.length > 0 ? userPrompts : undefined,
|
|
683
|
+
apiErrorMessage,
|
|
684
|
+
models: turnModel ? [turnModel] : undefined // Store raw model name(s) for this turn
|
|
685
|
+
};
|
|
686
|
+
deltas.push(delta);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return {
|
|
690
|
+
deltas,
|
|
691
|
+
lastLine: jsonObjects.length
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
catch (error) {
|
|
695
|
+
logger.error(`[ClaudeMetrics] Failed to parse incremental metrics: ${path}`, error);
|
|
696
|
+
throw error;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
//# sourceMappingURL=claude.metrics.js.map
|