@codemieai/code 0.0.27 → 0.0.29
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 +9 -11
- package/bin/agent-executor.js +1 -1
- package/dist/agents/codemie-code/agent.js +1 -1
- package/dist/agents/codemie-code/config.d.ts +1 -1
- package/dist/agents/codemie-code/config.d.ts.map +1 -1
- package/dist/agents/codemie-code/config.js +3 -4
- package/dist/agents/codemie-code/config.js.map +1 -1
- package/dist/agents/codemie-code/index.js +1 -1
- package/dist/agents/codemie-code/storage/todoStorage.d.ts.map +1 -1
- package/dist/agents/codemie-code/storage/todoStorage.js +2 -2
- package/dist/agents/codemie-code/storage/todoStorage.js.map +1 -1
- package/dist/agents/codemie-code/tools/index.js +1 -1
- package/dist/agents/codemie-code/tools/index.js.map +1 -1
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +6 -10
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts +17 -9
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +80 -72
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/core/extension/BaseExtensionInstaller.d.ts +258 -0
- package/dist/agents/core/extension/BaseExtensionInstaller.d.ts.map +1 -0
- package/dist/agents/core/extension/BaseExtensionInstaller.js +522 -0
- package/dist/agents/core/extension/BaseExtensionInstaller.js.map +1 -0
- package/dist/agents/core/lifecycle-helpers.d.ts.map +1 -1
- package/dist/agents/core/lifecycle-helpers.js +16 -2
- package/dist/agents/core/lifecycle-helpers.js.map +1 -1
- package/dist/agents/core/metrics/index.d.ts +0 -2
- package/dist/agents/core/metrics/index.d.ts.map +1 -1
- package/dist/agents/core/metrics/index.js +0 -3
- package/dist/agents/core/metrics/index.js.map +1 -1
- package/dist/agents/core/metrics/types.d.ts +4 -232
- package/dist/agents/core/metrics/types.d.ts.map +1 -1
- package/dist/agents/core/metrics/types.js +2 -2
- package/dist/agents/core/session/BaseProcessor.d.ts +72 -0
- package/dist/agents/core/session/BaseProcessor.d.ts.map +1 -0
- package/dist/agents/core/session/BaseProcessor.js +9 -0
- package/dist/agents/core/session/BaseProcessor.js.map +1 -0
- package/dist/agents/core/session/BaseSessionAdapter.d.ts +99 -0
- package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -0
- package/dist/agents/core/session/BaseSessionAdapter.js +9 -0
- package/dist/agents/core/session/BaseSessionAdapter.js.map +1 -0
- package/dist/agents/core/session/SessionStore.d.ts +23 -0
- package/dist/agents/core/session/SessionStore.d.ts.map +1 -0
- package/dist/agents/core/session/SessionStore.js +75 -0
- package/dist/agents/core/session/SessionStore.js.map +1 -0
- package/dist/agents/core/session/session-config.d.ts +27 -0
- package/dist/agents/core/session/session-config.d.ts.map +1 -0
- package/dist/agents/core/session/session-config.js +61 -0
- package/dist/agents/core/session/session-config.js.map +1 -0
- package/dist/agents/core/session/types.d.ts +87 -0
- package/dist/agents/core/session/types.d.ts.map +1 -0
- package/dist/agents/core/session/types.js +8 -0
- package/dist/agents/core/session/types.js.map +1 -0
- package/dist/agents/core/session/utils/jsonl-reader.d.ts +15 -0
- package/dist/agents/core/session/utils/jsonl-reader.d.ts.map +1 -0
- package/dist/agents/core/session/utils/jsonl-reader.js +33 -0
- package/dist/agents/core/session/utils/jsonl-reader.js.map +1 -0
- package/dist/agents/core/session/utils/jsonl-writer.d.ts +26 -0
- package/dist/agents/core/session/utils/jsonl-writer.d.ts.map +1 -0
- package/dist/agents/core/session/utils/jsonl-writer.js +56 -0
- package/dist/agents/core/session/utils/jsonl-writer.js.map +1 -0
- package/dist/agents/core/types.d.ts +78 -11
- package/dist/agents/core/types.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude-message-types.d.ts +74 -0
- package/dist/agents/plugins/claude/claude-message-types.d.ts.map +1 -0
- package/dist/agents/plugins/claude/claude-message-types.js +8 -0
- package/dist/agents/plugins/claude/claude-message-types.js.map +1 -0
- package/dist/agents/plugins/claude/claude.plugin-installer.d.ts +53 -0
- package/dist/agents/plugins/claude/claude.plugin-installer.d.ts.map +1 -0
- package/dist/agents/plugins/claude/claude.plugin-installer.js +63 -0
- package/dist/agents/plugins/claude/claude.plugin-installer.js.map +1 -0
- package/dist/agents/plugins/claude/claude.plugin.d.ts +26 -0
- package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -0
- package/dist/agents/plugins/{claude.plugin.js → claude/claude.plugin.js} +20 -11
- package/dist/agents/plugins/claude/claude.plugin.js.map +1 -0
- package/dist/agents/plugins/claude/claude.session.d.ts +60 -0
- package/dist/agents/plugins/claude/claude.session.d.ts.map +1 -0
- package/dist/agents/plugins/claude/claude.session.js +339 -0
- package/dist/agents/plugins/claude/claude.session.js.map +1 -0
- package/dist/agents/plugins/claude/plugin/.claude-plugin/local-install.json +15 -0
- package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +9 -0
- package/dist/agents/plugins/claude/plugin/README.md +299 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/README.md +539 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/CLAUDE.md.template +511 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/INDEX.md +205 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/TEMPLATE_SIZES.md +74 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/api/api-patterns.md.template +207 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/layered-architecture.md.template +143 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/project-structure.md.template +127 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/data/database-patterns.md.template +168 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/development/development-practices.md.template +210 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/integration/external-integrations.md.template +160 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/security/security-practices.md.template +170 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/standards/code-quality.md.template +150 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/standards/git-workflow.md.template +177 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/testing/testing-patterns.md.template +143 -0
- package/dist/agents/plugins/claude/plugin/commands/README.md +0 -0
- package/dist/agents/plugins/claude/plugin/commands/codemie-catchup.md +10 -0
- package/dist/agents/plugins/claude/plugin/commands/codemie-init.md +731 -0
- package/dist/agents/plugins/claude/plugin/commands/memory-add.md +44 -0
- package/dist/agents/plugins/claude/plugin/commands/memory-init.md +18 -0
- package/dist/agents/plugins/claude/plugin/commands/memory-refresh.md +54 -0
- package/dist/agents/plugins/claude/plugin/hooks/hooks.json +71 -0
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts +51 -0
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts.map +1 -0
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js +840 -0
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js.map +1 -0
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.d.ts +37 -0
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.d.ts.map +1 -0
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js +275 -0
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js.map +1 -0
- package/dist/agents/plugins/codemie-code.plugin.js +1 -1
- package/dist/agents/plugins/codemie-code.plugin.js.map +1 -1
- package/dist/agents/plugins/gemini/extension/README.md +88 -0
- package/dist/agents/plugins/gemini/extension/gemini-extension.json +11 -0
- package/dist/agents/plugins/gemini/extension/hooks/hooks.json +65 -0
- package/dist/agents/plugins/gemini/gemini.extension-installer.d.ts +49 -0
- package/dist/agents/plugins/gemini/gemini.extension-installer.d.ts.map +1 -0
- package/dist/agents/plugins/gemini/gemini.extension-installer.js +63 -0
- package/dist/agents/plugins/gemini/gemini.extension-installer.js.map +1 -0
- package/dist/agents/plugins/gemini/gemini.hook-transformer.d.ts +43 -0
- package/dist/agents/plugins/gemini/gemini.hook-transformer.d.ts.map +1 -0
- package/dist/agents/plugins/gemini/gemini.hook-transformer.js +57 -0
- package/dist/agents/plugins/gemini/gemini.hook-transformer.js.map +1 -0
- package/dist/agents/plugins/gemini/gemini.plugin.d.ts +32 -0
- package/dist/agents/plugins/gemini/gemini.plugin.d.ts.map +1 -0
- package/dist/agents/plugins/gemini/gemini.plugin.js +136 -0
- package/dist/agents/plugins/gemini/gemini.plugin.js.map +1 -0
- package/dist/agents/plugins/gemini/gemini.session-adapter.d.ts +68 -0
- package/dist/agents/plugins/gemini/gemini.session-adapter.d.ts.map +1 -0
- package/dist/agents/plugins/gemini/gemini.session-adapter.js +268 -0
- package/dist/agents/plugins/gemini/gemini.session-adapter.js.map +1 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.d.ts +36 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.d.ts.map +1 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.js +186 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.js.map +1 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.d.ts +32 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.d.ts.map +1 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.js +193 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.js.map +1 -0
- package/dist/agents/plugins/gemini/session/utils/token-aggregator.d.ts +26 -0
- package/dist/agents/plugins/gemini/session/utils/token-aggregator.d.ts.map +1 -0
- package/dist/agents/plugins/gemini/session/utils/token-aggregator.js +38 -0
- package/dist/agents/plugins/gemini/session/utils/token-aggregator.js.map +1 -0
- package/dist/agents/plugins/gemini/session/utils/tool-aggregator.d.ts +33 -0
- package/dist/agents/plugins/gemini/session/utils/tool-aggregator.d.ts.map +1 -0
- package/dist/agents/plugins/gemini/session/utils/tool-aggregator.js +58 -0
- package/dist/agents/plugins/gemini/session/utils/tool-aggregator.js.map +1 -0
- package/dist/agents/plugins/gemini/session/utils/turn-detector.d.ts +70 -0
- package/dist/agents/plugins/gemini/session/utils/turn-detector.d.ts.map +1 -0
- package/dist/agents/plugins/gemini/session/utils/turn-detector.js +86 -0
- package/dist/agents/plugins/gemini/session/utils/turn-detector.js.map +1 -0
- package/dist/agents/registry.d.ts +7 -2
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js +17 -8
- package/dist/agents/registry.js.map +1 -1
- package/dist/cli/commands/analytics/data-loader.d.ts +1 -1
- package/dist/cli/commands/analytics/data-loader.d.ts.map +1 -1
- package/dist/cli/commands/analytics/data-loader.js +3 -3
- package/dist/cli/commands/analytics/data-loader.js.map +1 -1
- package/dist/cli/commands/analytics/index.js +1 -1
- package/dist/cli/commands/analytics/index.js.map +1 -1
- package/dist/cli/commands/doctor/checks/AIConfigCheck.js +1 -1
- package/dist/cli/commands/doctor/checks/AIConfigCheck.js.map +1 -1
- package/dist/cli/commands/doctor/checks/AwsCliCheck.js +1 -1
- package/dist/cli/commands/doctor/checks/AwsCliCheck.js.map +1 -1
- package/dist/cli/commands/doctor/checks/NpmCheck.js +1 -1
- package/dist/cli/commands/doctor/checks/NpmCheck.js.map +1 -1
- package/dist/cli/commands/doctor/checks/PythonCheck.d.ts +13 -0
- package/dist/cli/commands/doctor/checks/PythonCheck.d.ts.map +1 -1
- package/dist/cli/commands/doctor/checks/PythonCheck.js +91 -32
- package/dist/cli/commands/doctor/checks/PythonCheck.js.map +1 -1
- package/dist/cli/commands/doctor/checks/UvCheck.js +1 -1
- package/dist/cli/commands/doctor/checks/UvCheck.js.map +1 -1
- package/dist/cli/commands/doctor/types.d.ts +1 -1
- package/dist/cli/commands/doctor/types.d.ts.map +1 -1
- package/dist/cli/commands/hook.d.ts +7 -0
- package/dist/cli/commands/hook.d.ts.map +1 -0
- package/dist/cli/commands/hook.js +788 -0
- package/dist/cli/commands/hook.js.map +1 -0
- package/dist/cli/commands/profile/auth.js +1 -1
- package/dist/cli/commands/profile/auth.js.map +1 -1
- package/dist/{utils/profile-display.d.ts → cli/commands/profile/display.d.ts} +3 -3
- package/dist/cli/commands/profile/display.d.ts.map +1 -0
- package/dist/{utils/profile-display.js → cli/commands/profile/display.js} +2 -2
- package/dist/cli/commands/profile/display.js.map +1 -0
- package/dist/cli/commands/profile/index.js +2 -2
- package/dist/cli/commands/profile/index.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +4 -5
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/update.d.ts +3 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +291 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/version.js +1 -1
- package/dist/cli/commands/version.js.map +1 -1
- package/dist/{utils → cli}/first-time.d.ts +4 -0
- package/dist/cli/first-time.d.ts.map +1 -0
- package/dist/{utils → cli}/first-time.js +27 -14
- package/dist/cli/first-time.js.map +1 -0
- package/dist/cli/index.js +6 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/env/manager.d.ts.map +1 -1
- package/dist/env/manager.js +3 -4
- package/dist/env/manager.js.map +1 -1
- package/dist/frameworks/core/BaseFrameworkAdapter.js +1 -1
- package/dist/frameworks/core/BaseFrameworkAdapter.js.map +1 -1
- package/dist/frameworks/core/types.d.ts +1 -1
- package/dist/frameworks/plugins/bmad.plugin.js +2 -2
- package/dist/frameworks/plugins/bmad.plugin.js.map +1 -1
- package/dist/frameworks/plugins/speckit.plugin.d.ts.map +1 -1
- package/dist/frameworks/plugins/speckit.plugin.js +2 -3
- package/dist/frameworks/plugins/speckit.plugin.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/migrations/001-config-rename.migration.d.ts.map +1 -1
- package/dist/migrations/001-config-rename.migration.js +2 -2
- package/dist/migrations/001-config-rename.migration.js.map +1 -1
- package/dist/migrations/002-consolidate-sessions.migration.d.ts +50 -0
- package/dist/migrations/002-consolidate-sessions.migration.d.ts.map +1 -0
- package/dist/migrations/002-consolidate-sessions.migration.js +220 -0
- package/dist/migrations/002-consolidate-sessions.migration.js.map +1 -0
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +3 -2
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/tracker.d.ts.map +1 -1
- package/dist/migrations/tracker.js +2 -2
- package/dist/migrations/tracker.js.map +1 -1
- package/dist/providers/core/base/http-client.js +1 -1
- package/dist/providers/core/types.d.ts +1 -1
- package/dist/providers/plugins/ollama/ollama.template.d.ts.map +1 -1
- package/dist/providers/plugins/ollama/ollama.template.js +3 -1
- package/dist/providers/plugins/ollama/ollama.template.js.map +1 -1
- package/dist/providers/plugins/sso/index.d.ts +1 -1
- package/dist/providers/plugins/sso/index.d.ts.map +1 -1
- package/dist/providers/plugins/sso/index.js +1 -1
- package/dist/providers/plugins/sso/index.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.js +3 -3
- package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.d.ts +40 -0
- package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.d.ts.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.js +194 -0
- package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.js.map +1 -0
- package/dist/providers/plugins/sso/proxy/proxy-http-client.d.ts +1 -0
- package/dist/providers/plugins/sso/proxy/proxy-http-client.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/proxy-http-client.js +40 -6
- package/dist/providers/plugins/sso/proxy/proxy-http-client.js.map +1 -1
- package/dist/providers/plugins/sso/session/BaseProcessor.d.ts +72 -0
- package/dist/providers/plugins/sso/session/BaseProcessor.d.ts.map +1 -0
- package/dist/providers/plugins/sso/session/BaseProcessor.js +9 -0
- package/dist/providers/plugins/sso/session/BaseProcessor.js.map +1 -0
- package/dist/providers/plugins/sso/session/BaseSessionAdapter.d.ts +99 -0
- package/dist/providers/plugins/sso/session/BaseSessionAdapter.d.ts.map +1 -0
- package/dist/providers/plugins/sso/session/BaseSessionAdapter.js +9 -0
- package/dist/providers/plugins/sso/session/BaseSessionAdapter.js.map +1 -0
- package/dist/providers/plugins/sso/session/SessionSyncer.d.ts +36 -0
- package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -0
- package/dist/providers/plugins/sso/session/SessionSyncer.js +140 -0
- package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-api-client.d.ts +26 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-api-client.d.ts.map +1 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-api-client.js +146 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-api-client.js.map +1 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.d.ts +23 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.d.ts.map +1 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.js +171 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.js.map +1 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-types.d.ts +69 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-types.d.ts.map +1 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-types.js +7 -0
- package/dist/providers/plugins/sso/session/processors/conversations/conversation-types.js.map +1 -0
- package/dist/providers/plugins/sso/session/processors/metrics/MetricsWriter.d.ts +30 -0
- package/dist/providers/plugins/sso/session/processors/metrics/MetricsWriter.d.ts.map +1 -0
- package/dist/providers/plugins/sso/session/processors/metrics/MetricsWriter.js +79 -0
- package/dist/providers/plugins/sso/session/processors/metrics/MetricsWriter.js.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.metrics-aggregator.d.ts → session/processors/metrics/metrics-aggregator.d.ts} +6 -5
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.d.ts.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.metrics-aggregator.js → session/processors/metrics/metrics-aggregator.js} +20 -12
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.metrics-sender.d.ts → session/processors/metrics/metrics-api-client.d.ts} +18 -11
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.metrics-sender.js → session/processors/metrics/metrics-api-client.js} +143 -15
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.metrics-post-processor.d.ts → session/processors/metrics/metrics-post-processor.d.ts} +3 -3
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.metrics-post-processor.js → session/processors/metrics/metrics-post-processor.js} +3 -3
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js.map +1 -0
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.d.ts +24 -0
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.d.ts.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.metrics-sync.plugin.js → session/processors/metrics/metrics-sync-processor.js} +94 -165
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.metrics-types.d.ts → session/processors/metrics/metrics-types.d.ts} +2 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.d.ts.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.metrics-types.js → session/processors/metrics/metrics-types.js} +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.js.map +1 -0
- package/dist/providers/plugins/sso/session/utils/jsonl-reader.d.ts +15 -0
- package/dist/providers/plugins/sso/session/utils/jsonl-reader.d.ts.map +1 -0
- package/dist/providers/plugins/sso/session/utils/jsonl-reader.js +33 -0
- package/dist/providers/plugins/sso/session/utils/jsonl-reader.js.map +1 -0
- package/dist/providers/plugins/sso/session/utils/jsonl-writer.d.ts +26 -0
- package/dist/providers/plugins/sso/session/utils/jsonl-writer.d.ts.map +1 -0
- package/dist/providers/plugins/sso/{metrics/sync/sso.jsonl-writer.js → session/utils/jsonl-writer.js} +11 -27
- package/dist/providers/plugins/sso/session/utils/jsonl-writer.js.map +1 -0
- package/dist/providers/plugins/sso/sso.auth.js +1 -1
- package/dist/providers/plugins/sso/sso.auth.js.map +1 -1
- package/dist/providers/plugins/sso/sso.http-client.d.ts +1 -1
- package/dist/providers/plugins/sso/sso.http-client.js +1 -1
- package/dist/providers/plugins/sso/sso.http-client.js.map +1 -1
- package/dist/providers/plugins/sso/sso.template.d.ts.map +1 -1
- package/dist/providers/plugins/sso/sso.template.js +71 -43
- package/dist/providers/plugins/sso/sso.template.js.map +1 -1
- package/dist/utils/{config-loader.d.ts → config.d.ts} +6 -1
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/{config-loader.js → config.js} +30 -4
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/errors.d.ts +89 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +340 -0
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/exec.d.ts +6 -0
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +6 -0
- package/dist/utils/exec.js.map +1 -1
- package/dist/utils/file-operations.d.ts +20 -0
- package/dist/utils/file-operations.d.ts.map +1 -0
- package/dist/utils/file-operations.js +48 -0
- package/dist/utils/file-operations.js.map +1 -0
- package/dist/utils/logger.d.ts +2 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +15 -7
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/{json-parser.d.ts → parsers.d.ts} +1 -1
- package/dist/utils/parsers.d.ts.map +1 -0
- package/dist/utils/{json-parser.js → parsers.js} +1 -1
- package/dist/utils/parsers.js.map +1 -0
- package/dist/utils/{path-utils.d.ts → paths.d.ts} +77 -12
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/{path-utils.js → paths.js} +103 -12
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/{npm.d.ts → processes.d.ts} +44 -7
- package/dist/utils/processes.d.ts.map +1 -0
- package/dist/utils/{npm.js → processes.js} +129 -10
- package/dist/utils/processes.js.map +1 -0
- package/dist/utils/profile.d.ts +1 -16
- package/dist/utils/profile.d.ts.map +1 -1
- package/dist/utils/profile.js +1 -27
- package/dist/utils/profile.js.map +1 -1
- package/dist/utils/security.d.ts +62 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +396 -0
- package/dist/utils/security.js.map +1 -0
- package/package.json +11 -11
- package/scripts/copy-plugins.js +57 -0
- package/scripts/license-check.js +23 -0
- package/bin/codemie-codex.js +0 -18
- package/bin/codemie-deepagents.js +0 -18
- package/dist/agents/core/BaseMetricsAdapter.d.ts +0 -165
- package/dist/agents/core/BaseMetricsAdapter.d.ts.map +0 -1
- package/dist/agents/core/BaseMetricsAdapter.js +0 -308
- package/dist/agents/core/BaseMetricsAdapter.js.map +0 -1
- package/dist/agents/core/metrics/MetricsOrchestrator.d.ts +0 -81
- package/dist/agents/core/metrics/MetricsOrchestrator.d.ts.map +0 -1
- package/dist/agents/core/metrics/MetricsOrchestrator.js +0 -417
- package/dist/agents/core/metrics/MetricsOrchestrator.js.map +0 -1
- package/dist/agents/core/metrics/core/DeltaWriter.d.ts +0 -49
- package/dist/agents/core/metrics/core/DeltaWriter.d.ts.map +0 -1
- package/dist/agents/core/metrics/core/DeltaWriter.js +0 -152
- package/dist/agents/core/metrics/core/DeltaWriter.js.map +0 -1
- package/dist/agents/core/metrics/core/FileSnapshotter.d.ts +0 -22
- package/dist/agents/core/metrics/core/FileSnapshotter.d.ts.map +0 -1
- package/dist/agents/core/metrics/core/FileSnapshotter.js +0 -74
- package/dist/agents/core/metrics/core/FileSnapshotter.js.map +0 -1
- package/dist/agents/core/metrics/core/SessionCorrelator.d.ts +0 -34
- package/dist/agents/core/metrics/core/SessionCorrelator.d.ts.map +0 -1
- package/dist/agents/core/metrics/core/SessionCorrelator.js +0 -157
- package/dist/agents/core/metrics/core/SessionCorrelator.js.map +0 -1
- package/dist/agents/core/metrics/core/SyncStateManager.d.ts +0 -69
- package/dist/agents/core/metrics/core/SyncStateManager.d.ts.map +0 -1
- package/dist/agents/core/metrics/core/SyncStateManager.js +0 -283
- package/dist/agents/core/metrics/core/SyncStateManager.js.map +0 -1
- package/dist/agents/core/metrics/session/SessionStore.d.ts +0 -43
- package/dist/agents/core/metrics/session/SessionStore.d.ts.map +0 -1
- package/dist/agents/core/metrics/session/SessionStore.js +0 -146
- package/dist/agents/core/metrics/session/SessionStore.js.map +0 -1
- package/dist/agents/core/metrics-config.d.ts +0 -38
- package/dist/agents/core/metrics-config.d.ts.map +0 -1
- package/dist/agents/core/metrics-config.js +0 -95
- package/dist/agents/core/metrics-config.js.map +0 -1
- package/dist/agents/plugins/claude.metrics.d.ts +0 -102
- package/dist/agents/plugins/claude.metrics.d.ts.map +0 -1
- package/dist/agents/plugins/claude.metrics.js +0 -656
- package/dist/agents/plugins/claude.metrics.js.map +0 -1
- package/dist/agents/plugins/claude.plugin.d.ts +0 -19
- package/dist/agents/plugins/claude.plugin.d.ts.map +0 -1
- package/dist/agents/plugins/claude.plugin.js.map +0 -1
- package/dist/agents/plugins/codex.plugin.d.ts +0 -17
- package/dist/agents/plugins/codex.plugin.d.ts.map +0 -1
- package/dist/agents/plugins/codex.plugin.js +0 -386
- package/dist/agents/plugins/codex.plugin.js.map +0 -1
- package/dist/agents/plugins/deepagents.plugin.d.ts +0 -21
- package/dist/agents/plugins/deepagents.plugin.d.ts.map +0 -1
- package/dist/agents/plugins/deepagents.plugin.js +0 -104
- package/dist/agents/plugins/deepagents.plugin.js.map +0 -1
- package/dist/agents/plugins/gemini.metrics.d.ts +0 -99
- package/dist/agents/plugins/gemini.metrics.d.ts.map +0 -1
- package/dist/agents/plugins/gemini.metrics.js +0 -475
- package/dist/agents/plugins/gemini.metrics.js.map +0 -1
- package/dist/agents/plugins/gemini.plugin.d.ts +0 -16
- package/dist/agents/plugins/gemini.plugin.d.ts.map +0 -1
- package/dist/agents/plugins/gemini.plugin.js +0 -80
- package/dist/agents/plugins/gemini.plugin.js.map +0 -1
- package/dist/agents/plugins/history-parser.d.ts +0 -52
- package/dist/agents/plugins/history-parser.d.ts.map +0 -1
- package/dist/agents/plugins/history-parser.js +0 -155
- package/dist/agents/plugins/history-parser.js.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.jsonl-writer.d.ts +0 -28
- package/dist/providers/plugins/sso/metrics/sync/sso.jsonl-writer.d.ts.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.jsonl-writer.js.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.lifecycle-handler.d.ts +0 -62
- package/dist/providers/plugins/sso/metrics/sync/sso.lifecycle-handler.d.ts.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.lifecycle-handler.js +0 -157
- package/dist/providers/plugins/sso/metrics/sync/sso.lifecycle-handler.js.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-aggregator.d.ts.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-aggregator.js.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-api-client.d.ts +0 -32
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-api-client.d.ts.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-api-client.js +0 -159
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-api-client.js.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-post-processor.d.ts.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-post-processor.js.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-sender.d.ts.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-sender.js.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-sync.plugin.d.ts +0 -36
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-sync.plugin.d.ts.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-sync.plugin.js.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-types.d.ts.map +0 -1
- package/dist/providers/plugins/sso/metrics/sync/sso.metrics-types.js.map +0 -1
- package/dist/utils/config-loader.d.ts.map +0 -1
- package/dist/utils/config-loader.js.map +0 -1
- package/dist/utils/credential-store.d.ts +0 -22
- package/dist/utils/credential-store.d.ts.map +0 -1
- package/dist/utils/credential-store.js +0 -165
- package/dist/utils/credential-store.js.map +0 -1
- package/dist/utils/dirname.d.ts +0 -7
- package/dist/utils/dirname.d.ts.map +0 -1
- package/dist/utils/dirname.js +0 -11
- package/dist/utils/dirname.js.map +0 -1
- package/dist/utils/error-context.d.ts +0 -90
- package/dist/utils/error-context.d.ts.map +0 -1
- package/dist/utils/error-context.js +0 -338
- package/dist/utils/error-context.js.map +0 -1
- package/dist/utils/first-time.d.ts.map +0 -1
- package/dist/utils/first-time.js.map +0 -1
- package/dist/utils/git.d.ts +0 -13
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js +0 -37
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/installation-id.d.ts +0 -10
- package/dist/utils/installation-id.d.ts.map +0 -1
- package/dist/utils/installation-id.js +0 -30
- package/dist/utils/installation-id.js.map +0 -1
- package/dist/utils/json-parser.d.ts.map +0 -1
- package/dist/utils/json-parser.js.map +0 -1
- package/dist/utils/npm.d.ts.map +0 -1
- package/dist/utils/npm.js.map +0 -1
- package/dist/utils/path-utils.d.ts.map +0 -1
- package/dist/utils/path-utils.js.map +0 -1
- package/dist/utils/profile-display.d.ts.map +0 -1
- package/dist/utils/profile-display.js.map +0 -1
- package/dist/utils/sanitize.d.ts +0 -28
- package/dist/utils/sanitize.d.ts.map +0 -1
- package/dist/utils/sanitize.js +0 -212
- package/dist/utils/sanitize.js.map +0 -1
- package/dist/utils/which.d.ts +0 -20
- package/dist/utils/which.d.ts.map +0 -1
- package/dist/utils/which.js +0 -54
- package/dist/utils/which.js.map +0 -1
|
@@ -0,0 +1,788 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { logger } from '../../utils/logger.js';
|
|
3
|
+
import { AgentRegistry } from '../../agents/registry.js';
|
|
4
|
+
import { getSessionPath, getSessionMetricsPath, getSessionConversationPath } from '../../agents/core/session/session-config.js';
|
|
5
|
+
/**
|
|
6
|
+
* Read JSON from stdin
|
|
7
|
+
*/
|
|
8
|
+
async function readStdin() {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
let data = '';
|
|
11
|
+
process.stdin.setEncoding('utf-8');
|
|
12
|
+
process.stdin.on('data', (chunk) => (data += chunk));
|
|
13
|
+
process.stdin.on('end', () => resolve(data));
|
|
14
|
+
process.stdin.on('error', reject);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Initialize logger context using CODEMIE_SESSION_ID
|
|
19
|
+
*
|
|
20
|
+
* Uses CODEMIE_SESSION_ID from environment for:
|
|
21
|
+
* - Logging (logger.setSessionId)
|
|
22
|
+
* - Session files (~/.codemie/sessions/{sessionId}.json)
|
|
23
|
+
* - Metrics files (~/.codemie/sessions/{sessionId}_metrics.jsonl)
|
|
24
|
+
* - Conversation files (~/.codemie/sessions/{sessionId}_conversation.jsonl)
|
|
25
|
+
*
|
|
26
|
+
* @returns The CodeMie session ID from environment
|
|
27
|
+
* @throws Error if required environment variables are missing
|
|
28
|
+
*/
|
|
29
|
+
function initializeLoggerContext() {
|
|
30
|
+
const agentName = process.env.CODEMIE_AGENT;
|
|
31
|
+
if (!agentName) {
|
|
32
|
+
// Debug: Log all environment variables that start with CODEMIE_
|
|
33
|
+
const codemieEnvVars = Object.keys(process.env)
|
|
34
|
+
.filter(key => key.startsWith('CODEMIE_'))
|
|
35
|
+
.map(key => `${key}=${process.env[key]}`)
|
|
36
|
+
.join(', ');
|
|
37
|
+
console.error(`[hook:debug] CODEMIE_AGENT missing. Available CODEMIE_* vars: ${codemieEnvVars || 'none'}`);
|
|
38
|
+
throw new Error('CODEMIE_AGENT environment variable is required');
|
|
39
|
+
}
|
|
40
|
+
// Use CODEMIE_SESSION_ID from environment
|
|
41
|
+
const sessionId = process.env.CODEMIE_SESSION_ID;
|
|
42
|
+
if (!sessionId) {
|
|
43
|
+
throw new Error('CODEMIE_SESSION_ID environment variable is required');
|
|
44
|
+
}
|
|
45
|
+
// Set logger context
|
|
46
|
+
logger.setAgentName(agentName);
|
|
47
|
+
logger.setSessionId(sessionId);
|
|
48
|
+
// Set profile if available
|
|
49
|
+
const profileName = process.env.CODEMIE_PROFILE_NAME;
|
|
50
|
+
if (profileName) {
|
|
51
|
+
logger.setProfileName(profileName);
|
|
52
|
+
}
|
|
53
|
+
logger.debug(`[hook:init] Using CodeMie session ID: ${sessionId.slice(0, 8)}...`);
|
|
54
|
+
return sessionId;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Handle SessionStart event
|
|
58
|
+
* Creates session correlation document using hook data
|
|
59
|
+
*/
|
|
60
|
+
async function handleSessionStart(event, _rawInput, sessionId) {
|
|
61
|
+
// Create session record with correlation information
|
|
62
|
+
await createSessionRecord(event, sessionId);
|
|
63
|
+
// Send session start metrics (SSO provider only)
|
|
64
|
+
await sendSessionStartMetrics(event, sessionId, event.session_id);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Handle SessionEnd event
|
|
68
|
+
* Final sync and status update
|
|
69
|
+
* Note: Session ID cleanup happens automatically on next SessionStart via file detection
|
|
70
|
+
*/
|
|
71
|
+
async function handleSessionEnd(event, sessionId) {
|
|
72
|
+
logger.info(`[hook:SessionEnd] ${JSON.stringify(event)}`);
|
|
73
|
+
// 1. TRANSFORMATION: Transform remaining messages → JSONL (pending)
|
|
74
|
+
await performIncrementalSync(event, 'SessionEnd', sessionId);
|
|
75
|
+
// 2. API SYNC: Sync pending data to API using SessionSyncer
|
|
76
|
+
await syncPendingDataToAPI(sessionId, event.session_id);
|
|
77
|
+
// 3. Send session end metrics (needs to read session file)
|
|
78
|
+
await sendSessionEndMetrics(event, sessionId, event.session_id);
|
|
79
|
+
// 4. Update session status
|
|
80
|
+
await updateSessionStatus(event, sessionId);
|
|
81
|
+
// 5. Rename files LAST (after all operations that need to read session)
|
|
82
|
+
await renameSessionFiles(sessionId);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Sync pending data to API using SessionSyncer
|
|
86
|
+
* Same service used by plugin timer - ensures consistency
|
|
87
|
+
*
|
|
88
|
+
* @param sessionId - CodeMie session ID
|
|
89
|
+
* @param agentSessionId - Agent session ID for context
|
|
90
|
+
*/
|
|
91
|
+
async function syncPendingDataToAPI(sessionId, agentSessionId) {
|
|
92
|
+
try {
|
|
93
|
+
// Only sync for SSO provider
|
|
94
|
+
const provider = process.env.CODEMIE_PROVIDER;
|
|
95
|
+
if (provider !== 'ai-run-sso') {
|
|
96
|
+
logger.debug('[hook:SessionEnd] Skipping API sync (not SSO provider)');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
logger.info(`[hook:SessionEnd] Syncing pending data to API`);
|
|
100
|
+
// Build processing context
|
|
101
|
+
const context = await buildProcessingContext(sessionId, agentSessionId, '');
|
|
102
|
+
// Use SessionSyncer service (same as plugin)
|
|
103
|
+
const { SessionSyncer } = await import('../../providers/plugins/sso/session/SessionSyncer.js');
|
|
104
|
+
const syncer = new SessionSyncer();
|
|
105
|
+
// Sync pending data
|
|
106
|
+
const result = await syncer.sync(sessionId, context);
|
|
107
|
+
if (result.success) {
|
|
108
|
+
logger.info(`[hook:SessionEnd] API sync complete: ${result.message}`);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
logger.warn(`[hook:SessionEnd] API sync had failures: ${result.message}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
116
|
+
logger.error(`[hook:SessionEnd] Failed to sync pending data: ${errorMessage}`);
|
|
117
|
+
// Don't throw - sync failure should not block session end
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Handle PermissionRequest event
|
|
122
|
+
*/
|
|
123
|
+
async function handlePermissionRequest(event, _rawInput) {
|
|
124
|
+
logger.debug(`[hook:PermissionRequest] ${JSON.stringify(event)}`);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Perform incremental sync using unified SessionAdapter
|
|
128
|
+
*
|
|
129
|
+
* @param event - Hook event with transcript_path and session_id
|
|
130
|
+
* @param hookName - Name of the hook for logging (e.g., "Stop", "UserPromptSubmit")
|
|
131
|
+
* @param sessionId - The CodeMie session ID to use for this extraction
|
|
132
|
+
*/
|
|
133
|
+
async function performIncrementalSync(event, hookName, sessionId) {
|
|
134
|
+
logger.debug(`[hook:${hookName}] Event received: ${JSON.stringify(event)}`);
|
|
135
|
+
logger.info(`[hook:${hookName}] Starting session processing (agent_session=${event.session_id})`);
|
|
136
|
+
try {
|
|
137
|
+
// Get agent name from environment
|
|
138
|
+
const agentName = process.env.CODEMIE_AGENT;
|
|
139
|
+
if (!agentName) {
|
|
140
|
+
logger.warn(`[hook:${hookName}] Missing CODEMIE_AGENT, skipping extraction`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Use transcript_path directly from event
|
|
144
|
+
const agentSessionFile = event.transcript_path;
|
|
145
|
+
if (!agentSessionFile) {
|
|
146
|
+
logger.warn(`[hook:${hookName}] No transcript_path in event`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
logger.debug(`[hook:${hookName}] Using transcript: ${agentSessionFile}`);
|
|
150
|
+
// Get agent from registry
|
|
151
|
+
const agent = AgentRegistry.getAgent(agentName);
|
|
152
|
+
if (!agent) {
|
|
153
|
+
logger.error(`[hook:${hookName}] Agent not found in registry: ${agentName}`);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// Get session adapter (unified approach)
|
|
157
|
+
const sessionAdapter = agent.getSessionAdapter?.();
|
|
158
|
+
if (!sessionAdapter) {
|
|
159
|
+
logger.warn(`[hook:${hookName}] No session adapter available for agent ${agentName}`);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Build processing context
|
|
163
|
+
const context = await buildProcessingContext(sessionId, event.session_id, agentSessionFile);
|
|
164
|
+
// Process session with all processors (metrics + conversations)
|
|
165
|
+
logger.debug(`[hook:${hookName}] Calling SessionAdapter.processSession()`);
|
|
166
|
+
const result = await sessionAdapter.processSession(agentSessionFile, sessionId, context);
|
|
167
|
+
if (result.success) {
|
|
168
|
+
logger.info(`[hook:${hookName}] Session processing complete: ${result.totalRecords} records processed`);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
logger.warn(`[hook:${hookName}] Session processing had failures: ${result.failedProcessors.join(', ')}`);
|
|
172
|
+
}
|
|
173
|
+
// Log processor results
|
|
174
|
+
for (const [name, procResult] of Object.entries(result.processors)) {
|
|
175
|
+
const result = procResult;
|
|
176
|
+
if (result.success) {
|
|
177
|
+
logger.debug(`[hook:${hookName}] Processor ${name}: ${result.message || 'success'}`);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
logger.error(`[hook:${hookName}] Processor ${name}: ${result.message || 'failed'}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
186
|
+
logger.error(`[hook:${hookName}] Session processing failed: ${errorMessage}`);
|
|
187
|
+
// Don't throw - hook should not block agent execution or user prompts
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Build processing context for SessionAdapter
|
|
192
|
+
* @param sessionId - CodeMie session ID
|
|
193
|
+
* @param agentSessionId - Agent session ID
|
|
194
|
+
* @param agentSessionFile - Path to agent session file
|
|
195
|
+
* @returns Processing context for SessionAdapter
|
|
196
|
+
*/
|
|
197
|
+
async function buildProcessingContext(sessionId, agentSessionId, agentSessionFile) {
|
|
198
|
+
// Get environment variables
|
|
199
|
+
const provider = process.env.CODEMIE_PROVIDER;
|
|
200
|
+
const ssoUrl = process.env.CODEMIE_URL;
|
|
201
|
+
const apiUrl = process.env.CODEMIE_BASE_URL || '';
|
|
202
|
+
const cliVersion = process.env.CODEMIE_CLI_VERSION || '0.0.0';
|
|
203
|
+
const clientType = process.env.CODEMIE_CLIENT_TYPE || 'codemie-cli';
|
|
204
|
+
// Build context with SSO credentials if available
|
|
205
|
+
let cookies = '';
|
|
206
|
+
let apiKey;
|
|
207
|
+
if (provider === 'ai-run-sso' && ssoUrl && apiUrl) {
|
|
208
|
+
try {
|
|
209
|
+
const { CodeMieSSO } = await import('../../providers/plugins/sso/sso.auth.js');
|
|
210
|
+
const sso = new CodeMieSSO();
|
|
211
|
+
const credentials = await sso.getStoredCredentials(ssoUrl);
|
|
212
|
+
if (credentials?.cookies) {
|
|
213
|
+
cookies = Object.entries(credentials.cookies)
|
|
214
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
215
|
+
.join('; ');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
logger.debug('[hook] Failed to load SSO credentials:', error);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Check for API key (for local development)
|
|
223
|
+
if (process.env.CODEMIE_API_KEY) {
|
|
224
|
+
apiKey = process.env.CODEMIE_API_KEY;
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
apiBaseUrl: apiUrl,
|
|
228
|
+
cookies,
|
|
229
|
+
apiKey,
|
|
230
|
+
clientType,
|
|
231
|
+
version: cliVersion,
|
|
232
|
+
dryRun: false,
|
|
233
|
+
sessionId,
|
|
234
|
+
agentSessionId,
|
|
235
|
+
agentSessionFile
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Handle Stop event
|
|
240
|
+
* Extracts metrics and conversations from agent session file incrementally
|
|
241
|
+
*/
|
|
242
|
+
async function handleStop(event, sessionId) {
|
|
243
|
+
await performIncrementalSync(event, 'Stop', sessionId);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Handle SubagentStop event
|
|
247
|
+
* Appends agent thought to _conversations.jsonl for later sync
|
|
248
|
+
*/
|
|
249
|
+
async function handleSubagentStop(event, sessionId) {
|
|
250
|
+
await performIncrementalSync(event, 'SubagentStop', sessionId);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Handle PreCompact event
|
|
254
|
+
*/
|
|
255
|
+
async function handlePreCompact(event) {
|
|
256
|
+
logger.debug(`[hook:PreCompact] ${JSON.stringify(event)}`);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Normalize event name using agent-specific mapping
|
|
260
|
+
* Maps agent-specific event names to internal event names
|
|
261
|
+
*
|
|
262
|
+
* @param eventName - Original event name from hook
|
|
263
|
+
* @param agentName - Agent name (claude, gemini)
|
|
264
|
+
* @returns Normalized internal event name
|
|
265
|
+
*/
|
|
266
|
+
function normalizeEventName(eventName, agentName) {
|
|
267
|
+
try {
|
|
268
|
+
logger.info(`[hook:normalize] Input: eventName="${eventName}", agentName="${agentName}"`);
|
|
269
|
+
// Get agent from registry
|
|
270
|
+
const agent = AgentRegistry.getAgent(agentName);
|
|
271
|
+
if (!agent) {
|
|
272
|
+
logger.warn(`[hook:router] Agent not found for event normalization: ${agentName}`);
|
|
273
|
+
return eventName; // Return original name as fallback
|
|
274
|
+
}
|
|
275
|
+
// Check if agent has event name mapping
|
|
276
|
+
const eventMapping = agent.metadata?.hookConfig?.eventNameMapping;
|
|
277
|
+
if (!eventMapping) {
|
|
278
|
+
logger.info(`[hook:normalize] No mapping defined for agent ${agentName}, using event name as-is`);
|
|
279
|
+
// No mapping defined - assume agent uses internal names (like Claude)
|
|
280
|
+
return eventName;
|
|
281
|
+
}
|
|
282
|
+
logger.info(`[hook:normalize] Available mappings for ${agentName}: ${JSON.stringify(Object.keys(eventMapping))}`);
|
|
283
|
+
// Apply mapping
|
|
284
|
+
const normalizedName = eventMapping[eventName];
|
|
285
|
+
if (normalizedName) {
|
|
286
|
+
logger.info(`[hook:normalize] Mapped: ${eventName} → ${normalizedName} (agent=${agentName})`);
|
|
287
|
+
return normalizedName;
|
|
288
|
+
}
|
|
289
|
+
// Event not in mapping - return original
|
|
290
|
+
logger.info(`[hook:normalize] No mapping found for "${eventName}", using original name`);
|
|
291
|
+
return eventName;
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
295
|
+
logger.warn(`[hook:router] Failed to normalize event name: ${message}`);
|
|
296
|
+
return eventName; // Fallback to original
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Route event to appropriate handler based on hook_event_name
|
|
301
|
+
* Handles events gracefully with detailed logging and error context
|
|
302
|
+
*
|
|
303
|
+
* @param event - The hook event to route (may be transformed)
|
|
304
|
+
* @param rawInput - Raw JSON input string
|
|
305
|
+
* @param sessionId - The CodeMie session ID to use for all operations
|
|
306
|
+
* @param agentName - The agent name for event normalization
|
|
307
|
+
*/
|
|
308
|
+
async function routeHookEvent(event, rawInput, sessionId, agentName) {
|
|
309
|
+
const startTime = Date.now();
|
|
310
|
+
try {
|
|
311
|
+
// Normalize event name using agent-specific mapping
|
|
312
|
+
const originalEventName = event.hook_event_name;
|
|
313
|
+
logger.info(`[hook:router] Routing event: original="${originalEventName}", agent="${agentName}"`);
|
|
314
|
+
const normalizedEventName = normalizeEventName(originalEventName, agentName);
|
|
315
|
+
logger.info(`[hook:router] Normalized event name: "${normalizedEventName}"`);
|
|
316
|
+
switch (normalizedEventName) {
|
|
317
|
+
case 'SessionStart':
|
|
318
|
+
logger.info(`[hook:router] Calling handleSessionStart`);
|
|
319
|
+
await handleSessionStart(event, rawInput, sessionId);
|
|
320
|
+
break;
|
|
321
|
+
case 'SessionEnd':
|
|
322
|
+
logger.info(`[hook:router] Calling handleSessionEnd`);
|
|
323
|
+
await handleSessionEnd(event, sessionId);
|
|
324
|
+
break;
|
|
325
|
+
case 'PermissionRequest':
|
|
326
|
+
logger.info(`[hook:router] Calling handlePermissionRequest`);
|
|
327
|
+
await handlePermissionRequest(event, rawInput);
|
|
328
|
+
break;
|
|
329
|
+
case 'Stop':
|
|
330
|
+
logger.info(`[hook:router] Calling handleStop`);
|
|
331
|
+
await handleStop(event, sessionId);
|
|
332
|
+
break;
|
|
333
|
+
case 'SubagentStop':
|
|
334
|
+
logger.info(`[hook:router] Calling handleSubagentStop`);
|
|
335
|
+
await handleSubagentStop(event, sessionId);
|
|
336
|
+
break;
|
|
337
|
+
case 'PreCompact':
|
|
338
|
+
logger.info(`[hook:router] Calling handlePreCompact`);
|
|
339
|
+
await handlePreCompact(event);
|
|
340
|
+
break;
|
|
341
|
+
default:
|
|
342
|
+
logger.info(`[hook:router] Unsupported event: ${normalizedEventName} (silently ignored)`);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const duration = Date.now() - startTime;
|
|
346
|
+
logger.info(`[hook:router] Event handled successfully: ${normalizedEventName} (${duration}ms)`);
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
const duration = Date.now() - startTime;
|
|
350
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
351
|
+
const normalizedEventName = normalizeEventName(event.hook_event_name, agentName);
|
|
352
|
+
logger.error(`[hook:router] Event handler failed: ${normalizedEventName} (${duration}ms) error="${message}"`);
|
|
353
|
+
throw error;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Helper: Create and save session record
|
|
358
|
+
* Uses correlation information from hook event
|
|
359
|
+
*
|
|
360
|
+
* @param event - SessionStart event data
|
|
361
|
+
* @param sessionId - The CodeMie session ID from logger context
|
|
362
|
+
*/
|
|
363
|
+
async function createSessionRecord(event, sessionId) {
|
|
364
|
+
try {
|
|
365
|
+
// Get metadata from environment
|
|
366
|
+
const agentName = process.env.CODEMIE_AGENT;
|
|
367
|
+
const provider = process.env.CODEMIE_PROVIDER;
|
|
368
|
+
const project = process.env.CODEMIE_PROJECT;
|
|
369
|
+
if (!agentName || !provider) {
|
|
370
|
+
logger.warn('[hook:SessionStart] Missing required env vars for session creation');
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
// Determine working directory
|
|
374
|
+
const workingDirectory = event.cwd || process.cwd();
|
|
375
|
+
// Detect git branch
|
|
376
|
+
let gitBranch;
|
|
377
|
+
try {
|
|
378
|
+
const { detectGitBranch } = await import('../../utils/processes.js');
|
|
379
|
+
gitBranch = await detectGitBranch(workingDirectory);
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
logger.debug('[hook:SessionStart] Could not detect git branch:', error);
|
|
383
|
+
}
|
|
384
|
+
// Import session types and store
|
|
385
|
+
const { SessionStore } = await import('../../agents/core/session/SessionStore.js');
|
|
386
|
+
const sessionStore = new SessionStore();
|
|
387
|
+
// Create session record with correlation already matched
|
|
388
|
+
const session = {
|
|
389
|
+
sessionId,
|
|
390
|
+
agentName,
|
|
391
|
+
provider,
|
|
392
|
+
...(project && { project }),
|
|
393
|
+
startTime: Date.now(),
|
|
394
|
+
workingDirectory,
|
|
395
|
+
...(gitBranch && { gitBranch }),
|
|
396
|
+
status: 'active',
|
|
397
|
+
correlation: {
|
|
398
|
+
status: 'matched',
|
|
399
|
+
agentSessionId: event.session_id,
|
|
400
|
+
agentSessionFile: event.transcript_path,
|
|
401
|
+
retryCount: 0
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
// Save session
|
|
405
|
+
await sessionStore.saveSession(session);
|
|
406
|
+
logger.info(`[hook:SessionStart] Session created: id=${sessionId} agent=${agentName} ` +
|
|
407
|
+
`provider=${provider} agent_session=${event.session_id}`);
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
411
|
+
logger.error(`[hook:SessionStart] Failed to create session record: ${errorMessage}`);
|
|
412
|
+
// Don't throw - hook should not block agent execution
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Helper: Send session start metrics to CodeMie backend
|
|
417
|
+
* Only works with ai-run-sso provider
|
|
418
|
+
*
|
|
419
|
+
* @param event - SessionStart event data
|
|
420
|
+
* @param sessionId - The CodeMie session ID (for file operations)
|
|
421
|
+
* @param agentSessionId - The agent's session ID (for API)
|
|
422
|
+
*/
|
|
423
|
+
async function sendSessionStartMetrics(event, sessionId, agentSessionId) {
|
|
424
|
+
try {
|
|
425
|
+
// Only send metrics for SSO provider
|
|
426
|
+
const provider = process.env.CODEMIE_PROVIDER;
|
|
427
|
+
if (provider !== 'ai-run-sso') {
|
|
428
|
+
logger.debug('[hook:SessionStart] Skipping metrics (not SSO provider)');
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
// Get required environment variables
|
|
432
|
+
const agentName = process.env.CODEMIE_AGENT;
|
|
433
|
+
const ssoUrl = process.env.CODEMIE_URL;
|
|
434
|
+
const apiUrl = process.env.CODEMIE_BASE_URL;
|
|
435
|
+
const cliVersion = process.env.CODEMIE_CLI_VERSION;
|
|
436
|
+
const model = process.env.CODEMIE_MODEL;
|
|
437
|
+
const project = process.env.CODEMIE_PROJECT;
|
|
438
|
+
if (!sessionId || !agentName || !ssoUrl || !apiUrl) {
|
|
439
|
+
logger.debug('[hook:SessionStart] Missing required env vars for metrics');
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
// Determine working directory
|
|
443
|
+
const workingDirectory = event.cwd || process.cwd();
|
|
444
|
+
// Load SSO credentials
|
|
445
|
+
const { CodeMieSSO } = await import('../../providers/plugins/sso/sso.auth.js');
|
|
446
|
+
const sso = new CodeMieSSO();
|
|
447
|
+
const credentials = await sso.getStoredCredentials(ssoUrl);
|
|
448
|
+
if (!credentials || !credentials.cookies) {
|
|
449
|
+
logger.info(`[hook:SessionStart] No SSO credentials found for ${ssoUrl}`);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
// Build cookie header
|
|
453
|
+
const cookieHeader = Object.entries(credentials.cookies)
|
|
454
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
455
|
+
.join('; ');
|
|
456
|
+
// Use MetricsSender to send session start metric
|
|
457
|
+
const { MetricsSender } = await import('../../providers/plugins/sso/index.js');
|
|
458
|
+
const sender = new MetricsSender({
|
|
459
|
+
baseUrl: apiUrl,
|
|
460
|
+
cookies: cookieHeader,
|
|
461
|
+
timeout: 10000,
|
|
462
|
+
retryAttempts: 2,
|
|
463
|
+
version: cliVersion,
|
|
464
|
+
clientType: 'codemie-cli'
|
|
465
|
+
});
|
|
466
|
+
// Build status object with reason from event
|
|
467
|
+
const status = {
|
|
468
|
+
status: 'started',
|
|
469
|
+
reason: event.source // e.g., "startup"
|
|
470
|
+
};
|
|
471
|
+
// Send session start metric (use agent session ID for API)
|
|
472
|
+
await sender.sendSessionStart({
|
|
473
|
+
sessionId: agentSessionId,
|
|
474
|
+
agentName,
|
|
475
|
+
provider,
|
|
476
|
+
project,
|
|
477
|
+
model,
|
|
478
|
+
startTime: Date.now(),
|
|
479
|
+
workingDirectory
|
|
480
|
+
}, workingDirectory, status);
|
|
481
|
+
logger.info('[hook:SessionStart] Session start metrics sent successfully');
|
|
482
|
+
}
|
|
483
|
+
catch (error) {
|
|
484
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
485
|
+
logger.warn(`[hook:SessionStart] Failed to send metrics: ${errorMessage}`);
|
|
486
|
+
// Don't throw - metrics failures should not block agent execution
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Helper: Update session status on session end
|
|
491
|
+
*
|
|
492
|
+
* @param event - SessionEnd event data
|
|
493
|
+
* @param sessionId - The CodeMie session ID
|
|
494
|
+
*/
|
|
495
|
+
async function updateSessionStatus(event, sessionId) {
|
|
496
|
+
try {
|
|
497
|
+
// Import session store
|
|
498
|
+
const { SessionStore } = await import('../../agents/core/session/SessionStore.js');
|
|
499
|
+
const sessionStore = new SessionStore();
|
|
500
|
+
// Load existing session
|
|
501
|
+
const session = await sessionStore.loadSession(sessionId);
|
|
502
|
+
if (!session) {
|
|
503
|
+
logger.warn(`[hook:SessionEnd] Session not found: ${sessionId}`);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
// Determine status from exit reason
|
|
507
|
+
// Reason values from Claude Code:
|
|
508
|
+
// - clear: Session cleared with /clear command
|
|
509
|
+
// - logout: User logged out
|
|
510
|
+
// - prompt_input_exit: User exited while prompt input was visible
|
|
511
|
+
// - other: Other exit reasons
|
|
512
|
+
//
|
|
513
|
+
// Status mapping: All reasons → completed
|
|
514
|
+
const status = 'completed';
|
|
515
|
+
// Update session status and reason
|
|
516
|
+
await sessionStore.updateSessionStatus(sessionId, status, event.reason);
|
|
517
|
+
logger.info(`[hook:SessionEnd] Session status updated: id=${sessionId} status=${status} reason=${event.reason}`);
|
|
518
|
+
}
|
|
519
|
+
catch (error) {
|
|
520
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
521
|
+
logger.error(`[hook:SessionEnd] Failed to update session status: ${errorMessage}`);
|
|
522
|
+
// Don't throw - hook should not block agent execution
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Add 'completed_' prefix to a file path basename
|
|
527
|
+
* Example: /path/to/session.json → /path/to/completed_session.json
|
|
528
|
+
*/
|
|
529
|
+
async function addCompletedPrefix(filePath) {
|
|
530
|
+
const { dirname, basename, join } = await import('path');
|
|
531
|
+
return join(dirname(filePath), `completed_${basename(filePath)}`);
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Rename session files with 'completed_' prefix
|
|
535
|
+
* Uses session-config.ts helpers to ensure consistent paths.
|
|
536
|
+
*
|
|
537
|
+
* Renames:
|
|
538
|
+
* - Session file: {sessionId}.json → completed_{sessionId}.json
|
|
539
|
+
* - Metrics file: {sessionId}_metrics.jsonl → completed_{sessionId}_metrics.jsonl
|
|
540
|
+
* - Conversations file: {sessionId}_conversation.jsonl → completed_{sessionId}_conversation.jsonl
|
|
541
|
+
*
|
|
542
|
+
* @param sessionId - The CodeMie session ID
|
|
543
|
+
*/
|
|
544
|
+
async function renameSessionFiles(sessionId) {
|
|
545
|
+
const { rename } = await import('fs/promises');
|
|
546
|
+
const { existsSync } = await import('fs');
|
|
547
|
+
const renamedFiles = [];
|
|
548
|
+
const errors = [];
|
|
549
|
+
// 1. Rename session file
|
|
550
|
+
try {
|
|
551
|
+
const sessionFile = getSessionPath(sessionId);
|
|
552
|
+
const newSessionFile = await addCompletedPrefix(sessionFile);
|
|
553
|
+
if (existsSync(sessionFile)) {
|
|
554
|
+
await rename(sessionFile, newSessionFile);
|
|
555
|
+
renamedFiles.push('session');
|
|
556
|
+
logger.debug(`[hook:SessionEnd] Renamed session file: ${sessionId}.json → completed_${sessionId}.json`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
catch (error) {
|
|
560
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
561
|
+
errors.push(`session: ${errorMessage}`);
|
|
562
|
+
logger.warn(`[hook:SessionEnd] Failed to rename session file: ${errorMessage}`);
|
|
563
|
+
}
|
|
564
|
+
// 2. Rename metrics file
|
|
565
|
+
try {
|
|
566
|
+
const metricsFile = getSessionMetricsPath(sessionId);
|
|
567
|
+
const newMetricsFile = await addCompletedPrefix(metricsFile);
|
|
568
|
+
if (existsSync(metricsFile)) {
|
|
569
|
+
await rename(metricsFile, newMetricsFile);
|
|
570
|
+
renamedFiles.push('metrics');
|
|
571
|
+
logger.debug(`[hook:SessionEnd] Renamed metrics file: ${sessionId}_metrics.jsonl → completed_${sessionId}_metrics.jsonl`);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
catch (error) {
|
|
575
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
576
|
+
errors.push(`metrics: ${errorMessage}`);
|
|
577
|
+
logger.warn(`[hook:SessionEnd] Failed to rename metrics file: ${errorMessage}`);
|
|
578
|
+
}
|
|
579
|
+
// 3. Rename conversations file
|
|
580
|
+
try {
|
|
581
|
+
const conversationsFile = getSessionConversationPath(sessionId);
|
|
582
|
+
const newConversationsFile = await addCompletedPrefix(conversationsFile);
|
|
583
|
+
if (existsSync(conversationsFile)) {
|
|
584
|
+
await rename(conversationsFile, newConversationsFile);
|
|
585
|
+
renamedFiles.push('conversations');
|
|
586
|
+
logger.debug(`[hook:SessionEnd] Renamed conversations file: ${sessionId}_conversation.jsonl → completed_${sessionId}_conversation.jsonl`);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
catch (error) {
|
|
590
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
591
|
+
errors.push(`conversations: ${errorMessage}`);
|
|
592
|
+
logger.warn(`[hook:SessionEnd] Failed to rename conversations file: ${errorMessage}`);
|
|
593
|
+
}
|
|
594
|
+
// Log summary
|
|
595
|
+
if (renamedFiles.length > 0) {
|
|
596
|
+
logger.info(`[hook:SessionEnd] Renamed files: ${renamedFiles.join(', ')}`);
|
|
597
|
+
}
|
|
598
|
+
if (errors.length > 0) {
|
|
599
|
+
logger.warn(`[hook:SessionEnd] File rename errors: ${errors.join('; ')}`);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Helper: Send session end metrics to CodeMie backend
|
|
604
|
+
* Only works with ai-run-sso provider
|
|
605
|
+
*
|
|
606
|
+
* @param event - SessionEnd event data
|
|
607
|
+
* @param sessionId - The CodeMie session ID (for file operations)
|
|
608
|
+
* @param agentSessionId - The agent's session ID (for API)
|
|
609
|
+
*/
|
|
610
|
+
async function sendSessionEndMetrics(event, sessionId, agentSessionId) {
|
|
611
|
+
try {
|
|
612
|
+
// Only send metrics for SSO provider
|
|
613
|
+
const provider = process.env.CODEMIE_PROVIDER;
|
|
614
|
+
if (provider !== 'ai-run-sso') {
|
|
615
|
+
logger.debug('[hook:SessionEnd] Skipping metrics (not SSO provider)');
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
// Get required environment variables
|
|
619
|
+
const agentName = process.env.CODEMIE_AGENT;
|
|
620
|
+
const ssoUrl = process.env.CODEMIE_URL;
|
|
621
|
+
const apiUrl = process.env.CODEMIE_BASE_URL;
|
|
622
|
+
const cliVersion = process.env.CODEMIE_CLI_VERSION;
|
|
623
|
+
const model = process.env.CODEMIE_MODEL;
|
|
624
|
+
const project = process.env.CODEMIE_PROJECT;
|
|
625
|
+
if (!agentName || !ssoUrl || !apiUrl) {
|
|
626
|
+
logger.debug('[hook:SessionEnd] Missing required env vars for metrics');
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
// Load session to get start time
|
|
630
|
+
const { SessionStore } = await import('../../agents/core/session/SessionStore.js');
|
|
631
|
+
const sessionStore = new SessionStore();
|
|
632
|
+
const session = await sessionStore.loadSession(sessionId);
|
|
633
|
+
if (!session) {
|
|
634
|
+
logger.warn(`[hook:SessionEnd] Session not found for metrics: ${sessionId}`);
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
// Calculate duration
|
|
638
|
+
const durationMs = Date.now() - session.startTime;
|
|
639
|
+
// Build status object with reason from event
|
|
640
|
+
// Status is "completed" for normal session endings, with reason from Claude (e.g., "exit", "logout")
|
|
641
|
+
const status = {
|
|
642
|
+
status: 'completed',
|
|
643
|
+
reason: event.reason
|
|
644
|
+
};
|
|
645
|
+
// Load SSO credentials
|
|
646
|
+
const { CodeMieSSO } = await import('../../providers/plugins/sso/sso.auth.js');
|
|
647
|
+
const sso = new CodeMieSSO();
|
|
648
|
+
const credentials = await sso.getStoredCredentials(ssoUrl);
|
|
649
|
+
if (!credentials?.cookies) {
|
|
650
|
+
logger.info(`[hook:SessionEnd] No SSO credentials found for ${ssoUrl}`);
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
// Build cookie header
|
|
654
|
+
const cookieHeader = Object.entries(credentials.cookies)
|
|
655
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
656
|
+
.join('; ');
|
|
657
|
+
// Use MetricsSender to send session end metric
|
|
658
|
+
const { MetricsSender } = await import('../../providers/plugins/sso/index.js');
|
|
659
|
+
const sender = new MetricsSender({
|
|
660
|
+
baseUrl: apiUrl,
|
|
661
|
+
cookies: cookieHeader,
|
|
662
|
+
timeout: 10000,
|
|
663
|
+
retryAttempts: 2,
|
|
664
|
+
version: cliVersion,
|
|
665
|
+
clientType: 'codemie-cli'
|
|
666
|
+
});
|
|
667
|
+
// Send session end metric (use agent session ID for API)
|
|
668
|
+
await sender.sendSessionEnd({
|
|
669
|
+
sessionId: agentSessionId,
|
|
670
|
+
agentName,
|
|
671
|
+
provider,
|
|
672
|
+
project,
|
|
673
|
+
model,
|
|
674
|
+
startTime: session.startTime,
|
|
675
|
+
workingDirectory: session.workingDirectory
|
|
676
|
+
}, session.workingDirectory, status, durationMs
|
|
677
|
+
// error parameter omitted - undefined for normal termination
|
|
678
|
+
);
|
|
679
|
+
logger.info('[hook:SessionEnd] Session end metrics sent successfully', {
|
|
680
|
+
status,
|
|
681
|
+
reason: event.reason,
|
|
682
|
+
durationMs
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
catch (error) {
|
|
686
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
687
|
+
logger.warn(`[hook:SessionEnd] Failed to send metrics: ${errorMessage}`);
|
|
688
|
+
// Don't throw - metrics failures should not block agent execution
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Create unified hook command
|
|
693
|
+
* Routes to appropriate handler based on hook_event_name in JSON payload
|
|
694
|
+
*/
|
|
695
|
+
export function createHookCommand() {
|
|
696
|
+
return new Command('hook')
|
|
697
|
+
.description('Unified hook event handler (called by agent plugins)')
|
|
698
|
+
.action(async () => {
|
|
699
|
+
const hookStartTime = Date.now();
|
|
700
|
+
let event = null;
|
|
701
|
+
try {
|
|
702
|
+
// Read JSON from stdin
|
|
703
|
+
const input = await readStdin();
|
|
704
|
+
// Log raw input at debug level (may contain sensitive data)
|
|
705
|
+
logger.debug(`[hook] Received input (${input.length} bytes)`);
|
|
706
|
+
// Parse JSON
|
|
707
|
+
try {
|
|
708
|
+
event = JSON.parse(input);
|
|
709
|
+
}
|
|
710
|
+
catch (parseError) {
|
|
711
|
+
const parseMsg = parseError instanceof Error ? parseError.message : String(parseError);
|
|
712
|
+
logger.error(`[hook] Failed to parse JSON input: ${parseMsg}`);
|
|
713
|
+
logger.debug(`[hook] Invalid JSON: ${input.substring(0, 200)}...`);
|
|
714
|
+
process.exit(2); // Blocking error
|
|
715
|
+
}
|
|
716
|
+
// Validate required fields from hook input schema
|
|
717
|
+
if (!event.session_id) {
|
|
718
|
+
logger.error('[hook] Missing required field: session_id');
|
|
719
|
+
logger.debug(`[hook] Received event: ${JSON.stringify(event)}`);
|
|
720
|
+
process.exit(2); // Blocking error
|
|
721
|
+
}
|
|
722
|
+
if (!event.hook_event_name) {
|
|
723
|
+
logger.error('[hook] Missing required field: hook_event_name');
|
|
724
|
+
logger.debug(`[hook] Received event: ${JSON.stringify(event)}`);
|
|
725
|
+
process.exit(2); // Blocking error
|
|
726
|
+
}
|
|
727
|
+
if (!event.transcript_path) {
|
|
728
|
+
logger.error('[hook] Missing required field: transcript_path');
|
|
729
|
+
logger.debug(`[hook] Received event: ${JSON.stringify(event)}`);
|
|
730
|
+
process.exit(2); // Blocking error
|
|
731
|
+
}
|
|
732
|
+
// Initialize logger context using CODEMIE_SESSION_ID from environment
|
|
733
|
+
// This ensures consistent session ID across all hooks
|
|
734
|
+
const sessionId = initializeLoggerContext();
|
|
735
|
+
// Get agent name from environment
|
|
736
|
+
const agentName = process.env.CODEMIE_AGENT || 'unknown';
|
|
737
|
+
// Apply hook transformation if agent provides a transformer
|
|
738
|
+
let transformedEvent = event;
|
|
739
|
+
try {
|
|
740
|
+
const agent = AgentRegistry.getAgent(agentName);
|
|
741
|
+
if (agent) {
|
|
742
|
+
const transformer = agent.getHookTransformer?.();
|
|
743
|
+
if (transformer) {
|
|
744
|
+
logger.debug(`[hook] Applying ${agentName} hook transformer`);
|
|
745
|
+
transformedEvent = transformer.transform(event);
|
|
746
|
+
logger.debug(`[hook] Transformation complete: ${event.hook_event_name} → ${transformedEvent.hook_event_name}`);
|
|
747
|
+
}
|
|
748
|
+
else {
|
|
749
|
+
logger.debug(`[hook] No transformer available for ${agentName}, using event as-is`);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
catch (transformError) {
|
|
754
|
+
const transformMsg = transformError instanceof Error ? transformError.message : String(transformError);
|
|
755
|
+
logger.error(`[hook] Transformation failed: ${transformMsg}, using original event`);
|
|
756
|
+
// Continue with original event on transformation failure
|
|
757
|
+
transformedEvent = event;
|
|
758
|
+
}
|
|
759
|
+
// Log hook invocation
|
|
760
|
+
logger.info(`[hook] Processing ${transformedEvent.hook_event_name} event (codemie_session=${sessionId.slice(0, 8)}..., agent_session=${transformedEvent.session_id.slice(0, 8)}...)`);
|
|
761
|
+
// Route to appropriate handler with transformed event and session ID
|
|
762
|
+
await routeHookEvent(transformedEvent, input, sessionId, agentName);
|
|
763
|
+
// Log successful completion
|
|
764
|
+
const totalDuration = Date.now() - hookStartTime;
|
|
765
|
+
logger.info(`[hook] Completed ${event.hook_event_name} event successfully (${totalDuration}ms)`);
|
|
766
|
+
// Flush logger before exit to ensure write completes
|
|
767
|
+
await logger.close();
|
|
768
|
+
process.exit(0); // Success
|
|
769
|
+
}
|
|
770
|
+
catch (error) {
|
|
771
|
+
const totalDuration = Date.now() - hookStartTime;
|
|
772
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
773
|
+
const stack = error instanceof Error ? error.stack : undefined;
|
|
774
|
+
// Log detailed error information
|
|
775
|
+
const eventName = event?.hook_event_name || 'unknown';
|
|
776
|
+
const sessionId = event?.session_id || 'unknown';
|
|
777
|
+
logger.error(`[hook] Failed to handle ${eventName} event (${totalDuration}ms): ${message}`);
|
|
778
|
+
if (stack) {
|
|
779
|
+
logger.debug(`[hook] Error stack: ${stack}`);
|
|
780
|
+
}
|
|
781
|
+
logger.debug(`[hook] Event details: agent_session=${sessionId}`);
|
|
782
|
+
// Flush logger before exit
|
|
783
|
+
await logger.close();
|
|
784
|
+
process.exit(1); // Non-blocking warning
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
//# sourceMappingURL=hook.js.map
|