@codemieai/code 0.0.36 → 0.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/README.md +33 -0
  2. package/dist/agents/codemie-code/tools/assistant-invocation.d.ts.map +1 -1
  3. package/dist/agents/codemie-code/tools/assistant-invocation.js +2 -2
  4. package/dist/agents/codemie-code/tools/assistant-invocation.js.map +1 -1
  5. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  6. package/dist/agents/core/BaseAgentAdapter.js +23 -9
  7. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  8. package/dist/agents/core/extension/BaseExtensionInstaller.d.ts.map +1 -1
  9. package/dist/agents/core/extension/BaseExtensionInstaller.js +11 -4
  10. package/dist/agents/core/extension/BaseExtensionInstaller.js.map +1 -1
  11. package/dist/agents/core/session/BaseProcessor.d.ts +22 -1
  12. package/dist/agents/core/session/BaseProcessor.d.ts.map +1 -1
  13. package/dist/agents/plugins/claude/claude-acp.plugin.d.ts +5 -0
  14. package/dist/agents/plugins/claude/claude-acp.plugin.d.ts.map +1 -1
  15. package/dist/agents/plugins/claude/claude-acp.plugin.js +12 -2
  16. package/dist/agents/plugins/claude/claude-acp.plugin.js.map +1 -1
  17. package/dist/agents/plugins/claude/claude.plugin.d.ts +11 -0
  18. package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
  19. package/dist/agents/plugins/claude/claude.plugin.js +59 -2
  20. package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
  21. package/dist/agents/plugins/claude/claude.session.d.ts +5 -0
  22. package/dist/agents/plugins/claude/claude.session.d.ts.map +1 -1
  23. package/dist/agents/plugins/claude/claude.session.js +101 -2
  24. package/dist/agents/plugins/claude/claude.session.js.map +1 -1
  25. package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +1 -1
  26. package/dist/agents/plugins/claude/plugin/commands/README.md +103 -22
  27. package/dist/agents/plugins/claude/plugin/commands/memory-refresh.md +329 -18
  28. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts +0 -1
  29. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts.map +1 -1
  30. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js +13 -19
  31. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js.map +1 -1
  32. package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.d.ts.map +1 -1
  33. package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js +29 -4
  34. package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js.map +1 -1
  35. package/dist/cli/commands/assistants/chat.js +9 -6
  36. package/dist/cli/commands/assistants/chat.js.map +1 -1
  37. package/dist/cli/commands/assistants/constants.d.ts +2 -6
  38. package/dist/cli/commands/assistants/constants.d.ts.map +1 -1
  39. package/dist/cli/commands/assistants/constants.js +2 -5
  40. package/dist/cli/commands/assistants/constants.js.map +1 -1
  41. package/dist/cli/commands/assistants/index.d.ts.map +1 -1
  42. package/dist/cli/commands/assistants/index.js +1 -11
  43. package/dist/cli/commands/assistants/index.js.map +1 -1
  44. package/dist/cli/commands/assistants/setup/configuration/actions.d.ts +30 -0
  45. package/dist/cli/commands/assistants/setup/configuration/actions.d.ts.map +1 -0
  46. package/dist/cli/commands/assistants/setup/configuration/actions.js +63 -0
  47. package/dist/cli/commands/assistants/setup/configuration/actions.js.map +1 -0
  48. package/dist/cli/commands/assistants/setup/configuration/constants.d.ts +49 -0
  49. package/dist/cli/commands/assistants/setup/configuration/constants.d.ts.map +1 -0
  50. package/dist/cli/commands/assistants/setup/configuration/constants.js +56 -0
  51. package/dist/cli/commands/assistants/setup/configuration/constants.js.map +1 -0
  52. package/dist/cli/commands/assistants/setup/configuration/index.d.ts +9 -0
  53. package/dist/cli/commands/assistants/setup/configuration/index.d.ts.map +1 -0
  54. package/dist/cli/commands/assistants/setup/configuration/index.js +8 -0
  55. package/dist/cli/commands/assistants/setup/configuration/index.js.map +1 -0
  56. package/dist/cli/commands/assistants/setup/configuration/selection.d.ts +12 -0
  57. package/dist/cli/commands/assistants/setup/configuration/selection.d.ts.map +1 -0
  58. package/dist/cli/commands/assistants/setup/configuration/selection.js +94 -0
  59. package/dist/cli/commands/assistants/setup/configuration/selection.js.map +1 -0
  60. package/dist/cli/commands/assistants/setup/configuration/types.d.ts +22 -0
  61. package/dist/cli/commands/assistants/setup/configuration/types.d.ts.map +1 -0
  62. package/dist/cli/commands/assistants/setup/configuration/types.js +2 -0
  63. package/dist/cli/commands/assistants/setup/configuration/types.js.map +1 -0
  64. package/dist/cli/commands/assistants/setup/configuration/ui.d.ts +9 -0
  65. package/dist/cli/commands/assistants/setup/configuration/ui.d.ts.map +1 -0
  66. package/dist/cli/commands/assistants/setup/configuration/ui.js +86 -0
  67. package/dist/cli/commands/assistants/setup/configuration/ui.js.map +1 -0
  68. package/dist/cli/commands/assistants/setup/constants.d.ts +26 -0
  69. package/dist/cli/commands/assistants/setup/constants.d.ts.map +1 -0
  70. package/dist/cli/commands/assistants/setup/constants.js +21 -0
  71. package/dist/cli/commands/assistants/setup/constants.js.map +1 -0
  72. package/dist/cli/commands/assistants/setup/data.d.ts +30 -0
  73. package/dist/cli/commands/assistants/setup/data.d.ts.map +1 -0
  74. package/dist/cli/commands/assistants/setup/data.js +125 -0
  75. package/dist/cli/commands/assistants/setup/data.js.map +1 -0
  76. package/dist/cli/commands/assistants/setup/generators/claude-agent-generator.d.ts.map +1 -0
  77. package/dist/cli/commands/assistants/{generators → setup/generators}/claude-agent-generator.js +6 -2
  78. package/dist/cli/commands/assistants/setup/generators/claude-agent-generator.js.map +1 -0
  79. package/dist/cli/commands/assistants/setup/generators/claude-skill-generator.d.ts +12 -0
  80. package/dist/cli/commands/assistants/setup/generators/claude-skill-generator.d.ts.map +1 -0
  81. package/dist/cli/commands/assistants/setup/generators/claude-skill-generator.js +94 -0
  82. package/dist/cli/commands/assistants/setup/generators/claude-skill-generator.js.map +1 -0
  83. package/dist/cli/commands/assistants/setup/helpers.d.ts +27 -0
  84. package/dist/cli/commands/assistants/setup/helpers.d.ts.map +1 -0
  85. package/dist/cli/commands/assistants/setup/helpers.js +94 -0
  86. package/dist/cli/commands/assistants/setup/helpers.js.map +1 -0
  87. package/dist/cli/commands/assistants/setup/index.d.ts +17 -0
  88. package/dist/cli/commands/assistants/setup/index.d.ts.map +1 -0
  89. package/dist/cli/commands/assistants/setup/index.js +193 -0
  90. package/dist/cli/commands/assistants/setup/index.js.map +1 -0
  91. package/dist/cli/commands/assistants/setup/manualConfiguration/actions.d.ts +47 -0
  92. package/dist/cli/commands/assistants/setup/manualConfiguration/actions.d.ts.map +1 -0
  93. package/dist/cli/commands/assistants/setup/manualConfiguration/actions.js +140 -0
  94. package/dist/cli/commands/assistants/setup/manualConfiguration/actions.js.map +1 -0
  95. package/dist/cli/commands/assistants/setup/manualConfiguration/constants.d.ts +56 -0
  96. package/dist/cli/commands/assistants/setup/manualConfiguration/constants.d.ts.map +1 -0
  97. package/dist/cli/commands/assistants/setup/manualConfiguration/constants.js +61 -0
  98. package/dist/cli/commands/assistants/setup/manualConfiguration/constants.js.map +1 -0
  99. package/dist/cli/commands/assistants/setup/manualConfiguration/index.d.ts +12 -0
  100. package/dist/cli/commands/assistants/setup/manualConfiguration/index.d.ts.map +1 -0
  101. package/dist/cli/commands/assistants/setup/manualConfiguration/index.js +48 -0
  102. package/dist/cli/commands/assistants/setup/manualConfiguration/index.js.map +1 -0
  103. package/dist/cli/commands/assistants/setup/manualConfiguration/interactive-prompt.d.ts +6 -0
  104. package/dist/cli/commands/assistants/setup/manualConfiguration/interactive-prompt.d.ts.map +1 -0
  105. package/dist/cli/commands/assistants/setup/manualConfiguration/interactive-prompt.js +90 -0
  106. package/dist/cli/commands/assistants/setup/manualConfiguration/interactive-prompt.js.map +1 -0
  107. package/dist/cli/commands/assistants/setup/manualConfiguration/types.d.ts +37 -0
  108. package/dist/cli/commands/assistants/setup/manualConfiguration/types.d.ts.map +1 -0
  109. package/dist/cli/commands/assistants/setup/manualConfiguration/types.js +2 -0
  110. package/dist/cli/commands/assistants/setup/manualConfiguration/types.js.map +1 -0
  111. package/dist/cli/commands/assistants/setup/manualConfiguration/ui.d.ts +6 -0
  112. package/dist/cli/commands/assistants/setup/manualConfiguration/ui.d.ts.map +1 -0
  113. package/dist/cli/commands/assistants/setup/manualConfiguration/ui.js +103 -0
  114. package/dist/cli/commands/assistants/setup/manualConfiguration/ui.js.map +1 -0
  115. package/dist/cli/commands/assistants/setup/selection/actions.d.ts +31 -0
  116. package/dist/cli/commands/assistants/setup/selection/actions.d.ts.map +1 -0
  117. package/dist/cli/commands/assistants/setup/selection/actions.js +321 -0
  118. package/dist/cli/commands/assistants/setup/selection/actions.js.map +1 -0
  119. package/dist/cli/commands/assistants/setup/selection/constants.d.ts +79 -0
  120. package/dist/cli/commands/assistants/setup/selection/constants.d.ts.map +1 -0
  121. package/dist/cli/commands/assistants/setup/selection/constants.js +90 -0
  122. package/dist/cli/commands/assistants/setup/selection/constants.js.map +1 -0
  123. package/dist/cli/commands/assistants/setup/selection/index.d.ts +25 -0
  124. package/dist/cli/commands/assistants/setup/selection/index.d.ts.map +1 -0
  125. package/dist/cli/commands/assistants/setup/selection/index.js +127 -0
  126. package/dist/cli/commands/assistants/setup/selection/index.js.map +1 -0
  127. package/dist/cli/commands/assistants/setup/selection/interactive-prompt.d.ts +20 -0
  128. package/dist/cli/commands/assistants/setup/selection/interactive-prompt.d.ts.map +1 -0
  129. package/dist/cli/commands/assistants/setup/selection/interactive-prompt.js +328 -0
  130. package/dist/cli/commands/assistants/setup/selection/interactive-prompt.js.map +1 -0
  131. package/dist/cli/commands/assistants/setup/selection/types.d.ts +27 -0
  132. package/dist/cli/commands/assistants/setup/selection/types.d.ts.map +1 -0
  133. package/dist/cli/commands/assistants/setup/selection/types.js +2 -0
  134. package/dist/cli/commands/assistants/setup/selection/types.js.map +1 -0
  135. package/dist/cli/commands/assistants/setup/selection/ui.d.ts +11 -0
  136. package/dist/cli/commands/assistants/setup/selection/ui.d.ts.map +1 -0
  137. package/dist/cli/commands/assistants/setup/selection/ui.js +189 -0
  138. package/dist/cli/commands/assistants/setup/selection/ui.js.map +1 -0
  139. package/dist/cli/commands/assistants/setup/selection/utils.d.ts +36 -0
  140. package/dist/cli/commands/assistants/setup/selection/utils.d.ts.map +1 -0
  141. package/dist/cli/commands/assistants/setup/selection/utils.js +55 -0
  142. package/dist/cli/commands/assistants/setup/selection/utils.js.map +1 -0
  143. package/dist/cli/commands/assistants/setup/summary/index.d.ts +16 -0
  144. package/dist/cli/commands/assistants/setup/summary/index.d.ts.map +1 -0
  145. package/dist/cli/commands/assistants/setup/summary/index.js +48 -0
  146. package/dist/cli/commands/assistants/setup/summary/index.js.map +1 -0
  147. package/dist/cli/commands/hook.d.ts +72 -0
  148. package/dist/cli/commands/hook.d.ts.map +1 -1
  149. package/dist/cli/commands/hook.js +290 -110
  150. package/dist/cli/commands/hook.js.map +1 -1
  151. package/dist/cli/commands/log/cleaner.d.ts +37 -0
  152. package/dist/cli/commands/log/cleaner.d.ts.map +1 -0
  153. package/dist/cli/commands/log/cleaner.js +218 -0
  154. package/dist/cli/commands/log/cleaner.js.map +1 -0
  155. package/dist/cli/commands/log/filter.d.ts +55 -0
  156. package/dist/cli/commands/log/filter.d.ts.map +1 -0
  157. package/dist/cli/commands/log/filter.js +128 -0
  158. package/dist/cli/commands/log/filter.js.map +1 -0
  159. package/dist/cli/commands/log/follower.d.ts +36 -0
  160. package/dist/cli/commands/log/follower.d.ts.map +1 -0
  161. package/dist/cli/commands/log/follower.js +151 -0
  162. package/dist/cli/commands/log/follower.js.map +1 -0
  163. package/dist/cli/commands/log/formatter.d.ts +76 -0
  164. package/dist/cli/commands/log/formatter.d.ts.map +1 -0
  165. package/dist/cli/commands/log/formatter.js +261 -0
  166. package/dist/cli/commands/log/formatter.js.map +1 -0
  167. package/dist/cli/commands/log/index.d.ts +6 -0
  168. package/dist/cli/commands/log/index.d.ts.map +1 -0
  169. package/dist/cli/commands/log/index.js +400 -0
  170. package/dist/cli/commands/log/index.js.map +1 -0
  171. package/dist/cli/commands/log/parser.d.ts +20 -0
  172. package/dist/cli/commands/log/parser.d.ts.map +1 -0
  173. package/dist/cli/commands/log/parser.js +111 -0
  174. package/dist/cli/commands/log/parser.js.map +1 -0
  175. package/dist/cli/commands/log/reader.d.ts +66 -0
  176. package/dist/cli/commands/log/reader.d.ts.map +1 -0
  177. package/dist/cli/commands/log/reader.js +364 -0
  178. package/dist/cli/commands/log/reader.js.map +1 -0
  179. package/dist/cli/commands/log/types.d.ts +100 -0
  180. package/dist/cli/commands/log/types.d.ts.map +1 -0
  181. package/dist/cli/commands/log/types.js +5 -0
  182. package/dist/cli/commands/log/types.js.map +1 -0
  183. package/dist/cli/commands/profile/display.d.ts +1 -0
  184. package/dist/cli/commands/profile/display.d.ts.map +1 -1
  185. package/dist/cli/commands/profile/display.js +10 -2
  186. package/dist/cli/commands/profile/display.js.map +1 -1
  187. package/dist/cli/commands/profile/index.js +58 -22
  188. package/dist/cli/commands/profile/index.js.map +1 -1
  189. package/dist/cli/commands/setup.d.ts.map +1 -1
  190. package/dist/cli/commands/setup.js +143 -24
  191. package/dist/cli/commands/setup.js.map +1 -1
  192. package/dist/cli/index.js +2 -0
  193. package/dist/cli/index.js.map +1 -1
  194. package/dist/env/types.d.ts +10 -1
  195. package/dist/env/types.d.ts.map +1 -1
  196. package/dist/env/types.js.map +1 -1
  197. package/dist/index.d.ts +5 -0
  198. package/dist/index.d.ts.map +1 -1
  199. package/dist/index.js +10 -0
  200. package/dist/index.js.map +1 -1
  201. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts +5 -0
  202. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
  203. package/dist/providers/plugins/sso/session/SessionSyncer.js +102 -3
  204. package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
  205. package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.d.ts +0 -1
  206. package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.d.ts.map +1 -1
  207. package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.js +25 -48
  208. package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.js.map +1 -1
  209. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.d.ts.map +1 -1
  210. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js +8 -34
  211. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js.map +1 -1
  212. package/dist/utils/config.d.ts +35 -8
  213. package/dist/utils/config.d.ts.map +1 -1
  214. package/dist/utils/config.js +243 -33
  215. package/dist/utils/config.js.map +1 -1
  216. package/dist/utils/logger.d.ts +8 -0
  217. package/dist/utils/logger.d.ts.map +1 -1
  218. package/dist/utils/logger.js +42 -0
  219. package/dist/utils/logger.js.map +1 -1
  220. package/dist/utils/native-installer.d.ts +1 -0
  221. package/dist/utils/native-installer.d.ts.map +1 -1
  222. package/dist/utils/native-installer.js +21 -7
  223. package/dist/utils/native-installer.js.map +1 -1
  224. package/package.json +2 -2
  225. package/dist/agents/plugins/claude/plugin/commands/memory-add.md +0 -325
  226. package/dist/agents/plugins/claude/plugin/commands/memory-init.md +0 -18
  227. package/dist/cli/commands/assistants/generators/claude-agent-generator.d.ts.map +0 -1
  228. package/dist/cli/commands/assistants/generators/claude-agent-generator.js.map +0 -1
  229. package/dist/cli/commands/assistants/list.d.ts +0 -11
  230. package/dist/cli/commands/assistants/list.d.ts.map +0 -1
  231. package/dist/cli/commands/assistants/list.js +0 -323
  232. package/dist/cli/commands/assistants/list.js.map +0 -1
  233. /package/dist/cli/commands/assistants/{generators → setup/generators}/claude-agent-generator.d.ts +0 -0
@@ -14,6 +14,34 @@ async function readStdin() {
14
14
  process.stdin.on('error', reject);
15
15
  });
16
16
  }
17
+ /**
18
+ * Helper function to get configuration value from config object or environment variable
19
+ * @param envKey - Environment variable key (e.g., 'CODEMIE_AGENT')
20
+ * @param config - Optional config object
21
+ * @returns Configuration value or undefined
22
+ */
23
+ function getConfigValue(envKey, config) {
24
+ if (config) {
25
+ // Map environment variable keys to config properties
26
+ const configMap = {
27
+ 'CODEMIE_AGENT': 'agentName',
28
+ 'CODEMIE_PROVIDER': 'provider',
29
+ 'CODEMIE_BASE_URL': 'apiBaseUrl',
30
+ 'CODEMIE_API_KEY': 'apiKey',
31
+ 'CODEMIE_CLIENT_TYPE': 'clientType',
32
+ 'CODEMIE_CLI_VERSION': 'version',
33
+ 'CODEMIE_PROFILE_NAME': 'profileName',
34
+ 'CODEMIE_PROJECT': 'project',
35
+ 'CODEMIE_MODEL': 'model',
36
+ 'CODEMIE_URL': 'ssoUrl',
37
+ };
38
+ const configKey = configMap[envKey];
39
+ if (configKey) {
40
+ return config[configKey];
41
+ }
42
+ }
43
+ return process.env[envKey];
44
+ }
17
45
  /**
18
46
  * Initialize logger context using CODEMIE_SESSION_ID
19
47
  *
@@ -57,27 +85,27 @@ function initializeLoggerContext() {
57
85
  * Handle SessionStart event
58
86
  * Creates session correlation document using hook data
59
87
  */
60
- async function handleSessionStart(event, _rawInput, sessionId) {
88
+ async function handleSessionStart(event, _rawInput, sessionId, config) {
61
89
  // Create session record with correlation information
62
- await createSessionRecord(event, sessionId);
90
+ await createSessionRecord(event, sessionId, config);
63
91
  // Send session start metrics (SSO provider only)
64
- await sendSessionStartMetrics(event, sessionId, event.session_id);
92
+ await sendSessionStartMetrics(event, sessionId, event.session_id, config);
65
93
  }
66
94
  /**
67
95
  * Handle SessionEnd event
68
96
  * Final sync and status update
69
97
  * Note: Session ID cleanup happens automatically on next SessionStart via file detection
70
98
  */
71
- async function handleSessionEnd(event, sessionId) {
99
+ async function handleSessionEnd(event, sessionId, config) {
72
100
  logger.info(`[hook:SessionEnd] ${JSON.stringify(event)}`);
73
101
  // 0. Final activity accumulation (handles edge case: session ends without Stop)
74
102
  await accumulateActiveDuration(sessionId);
75
103
  // 1. TRANSFORMATION: Transform remaining messages → JSONL (pending)
76
- await performIncrementalSync(event, 'SessionEnd', sessionId);
104
+ await performIncrementalSync(event, 'SessionEnd', sessionId, config);
77
105
  // 2. API SYNC: Sync pending data to API using SessionSyncer
78
- await syncPendingDataToAPI(sessionId, event.session_id);
106
+ await syncPendingDataToAPI(sessionId, event.session_id, config);
79
107
  // 3. Send session end metrics (needs to read session file)
80
- await sendSessionEndMetrics(event, sessionId, event.session_id);
108
+ await sendSessionEndMetrics(event, sessionId, event.session_id, config);
81
109
  // 4. Update session status
82
110
  await updateSessionStatus(event, sessionId);
83
111
  // 5. Rename files LAST (after all operations that need to read session)
@@ -89,18 +117,19 @@ async function handleSessionEnd(event, sessionId) {
89
117
  *
90
118
  * @param sessionId - CodeMie session ID
91
119
  * @param agentSessionId - Agent session ID for context
120
+ * @param config - Optional configuration object (if not provided, reads from environment variables)
92
121
  */
93
- async function syncPendingDataToAPI(sessionId, agentSessionId) {
122
+ async function syncPendingDataToAPI(sessionId, agentSessionId, config) {
94
123
  try {
95
124
  // Only sync for SSO provider
96
- const provider = process.env.CODEMIE_PROVIDER;
125
+ const provider = getConfigValue('CODEMIE_PROVIDER', config);
97
126
  if (provider !== 'ai-run-sso') {
98
127
  logger.debug('[hook:SessionEnd] Skipping API sync (not SSO provider)');
99
128
  return;
100
129
  }
101
130
  logger.info(`[hook:SessionEnd] Syncing pending data to API`);
102
131
  // Build processing context
103
- const context = await buildProcessingContext(sessionId, agentSessionId, '');
132
+ const context = await buildProcessingContext(sessionId, agentSessionId, '', config);
104
133
  // Use SessionSyncer service (same as plugin)
105
134
  const { SessionSyncer } = await import('../../providers/plugins/sso/session/SessionSyncer.js');
106
135
  const syncer = new SessionSyncer();
@@ -131,20 +160,27 @@ async function handlePermissionRequest(event, _rawInput) {
131
160
  * @param event - Hook event with transcript_path and session_id
132
161
  * @param hookName - Name of the hook for logging (e.g., "Stop", "UserPromptSubmit")
133
162
  * @param sessionId - The CodeMie session ID to use for this extraction
163
+ * @param config - Optional configuration object (if not provided, reads from environment variables)
134
164
  */
135
- async function performIncrementalSync(event, hookName, sessionId) {
165
+ async function performIncrementalSync(event, hookName, sessionId, config) {
136
166
  logger.debug(`[hook:${hookName}] Event received: ${JSON.stringify(event)}`);
137
167
  logger.info(`[hook:${hookName}] Starting session processing (agent_session=${event.session_id})`);
138
168
  try {
139
- // Get agent name from environment
140
- const agentName = process.env.CODEMIE_AGENT;
169
+ // Get agent name from config or environment
170
+ const agentName = getConfigValue('CODEMIE_AGENT', config);
141
171
  if (!agentName) {
172
+ if (config) {
173
+ throw new Error(`Missing required config: agentName`);
174
+ }
142
175
  logger.warn(`[hook:${hookName}] Missing CODEMIE_AGENT, skipping extraction`);
143
176
  return;
144
177
  }
145
178
  // Use transcript_path directly from event
146
179
  const agentSessionFile = event.transcript_path;
147
180
  if (!agentSessionFile) {
181
+ if (config) {
182
+ throw new Error(`Missing required field: transcript_path`);
183
+ }
148
184
  logger.warn(`[hook:${hookName}] No transcript_path in event`);
149
185
  return;
150
186
  }
@@ -152,17 +188,23 @@ async function performIncrementalSync(event, hookName, sessionId) {
152
188
  // Get agent from registry
153
189
  const agent = AgentRegistry.getAgent(agentName);
154
190
  if (!agent) {
191
+ if (config) {
192
+ throw new Error(`Agent not found in registry: ${agentName}`);
193
+ }
155
194
  logger.error(`[hook:${hookName}] Agent not found in registry: ${agentName}`);
156
195
  return;
157
196
  }
158
197
  // Get session adapter (unified approach)
159
198
  const sessionAdapter = agent.getSessionAdapter?.();
160
199
  if (!sessionAdapter) {
200
+ if (config) {
201
+ throw new Error(`No session adapter available for agent ${agentName}`);
202
+ }
161
203
  logger.warn(`[hook:${hookName}] No session adapter available for agent ${agentName}`);
162
204
  return;
163
205
  }
164
206
  // Build processing context
165
- const context = await buildProcessingContext(sessionId, event.session_id, agentSessionFile);
207
+ const context = await buildProcessingContext(sessionId, event.session_id, agentSessionFile, config);
166
208
  // Process session with all processors (metrics + conversations)
167
209
  logger.debug(`[hook:${hookName}] Calling SessionAdapter.processSession()`);
168
210
  const result = await sessionAdapter.processSession(agentSessionFile, sessionId, context);
@@ -194,19 +236,21 @@ async function performIncrementalSync(event, hookName, sessionId) {
194
236
  * @param sessionId - CodeMie session ID
195
237
  * @param agentSessionId - Agent session ID
196
238
  * @param agentSessionFile - Path to agent session file
239
+ * @param config - Optional configuration object (if not provided, reads from environment variables)
197
240
  * @returns Processing context for SessionAdapter
198
241
  */
199
- async function buildProcessingContext(sessionId, agentSessionId, agentSessionFile) {
200
- // Get environment variables
201
- const provider = process.env.CODEMIE_PROVIDER;
202
- const ssoUrl = process.env.CODEMIE_URL;
203
- const apiUrl = process.env.CODEMIE_BASE_URL || '';
204
- const cliVersion = process.env.CODEMIE_CLI_VERSION || '0.0.0';
205
- const clientType = process.env.CODEMIE_CLIENT_TYPE || 'codemie-cli';
242
+ async function buildProcessingContext(sessionId, agentSessionId, agentSessionFile, config) {
243
+ // Get configuration values from config object or environment variables
244
+ const provider = getConfigValue('CODEMIE_PROVIDER', config);
245
+ const ssoUrl = getConfigValue('CODEMIE_URL', config);
246
+ const apiUrl = getConfigValue('CODEMIE_BASE_URL', config) || '';
247
+ const cliVersion = getConfigValue('CODEMIE_CLI_VERSION', config) || '0.0.0';
248
+ const clientType = getConfigValue('CODEMIE_CLIENT_TYPE', config) || 'codemie-cli';
206
249
  // Build context with SSO credentials if available
207
- let cookies = '';
208
- let apiKey;
209
- if (provider === 'ai-run-sso' && ssoUrl && apiUrl) {
250
+ let cookies = config?.cookies || '';
251
+ let apiKey = config?.apiKey;
252
+ // If SSO provider and credentials not provided in config, try to load them
253
+ if (provider === 'ai-run-sso' && ssoUrl && apiUrl && !cookies) {
210
254
  try {
211
255
  const { CodeMieSSO } = await import('../../providers/plugins/sso/sso.auth.js');
212
256
  const sso = new CodeMieSSO();
@@ -221,9 +265,9 @@ async function buildProcessingContext(sessionId, agentSessionId, agentSessionFil
221
265
  logger.debug('[hook] Failed to load SSO credentials:', error);
222
266
  }
223
267
  }
224
- // Check for API key (for local development)
225
- if (process.env.CODEMIE_API_KEY) {
226
- apiKey = process.env.CODEMIE_API_KEY;
268
+ // Check for API key (for local development) if not in config
269
+ if (!apiKey) {
270
+ apiKey = getConfigValue('CODEMIE_API_KEY', config);
227
271
  }
228
272
  return {
229
273
  apiBaseUrl: apiUrl,
@@ -279,7 +323,7 @@ async function accumulateActiveDuration(sessionId) {
279
323
  * Handle UserPromptSubmit event
280
324
  * Starts activity tracking to measure active session time
281
325
  */
282
- async function handleUserPromptSubmit(event, sessionId) {
326
+ async function handleUserPromptSubmit(event, sessionId, _config) {
283
327
  logger.info(`[hook:UserPromptSubmit] ${JSON.stringify(event)}`);
284
328
  await startActivityTracking(sessionId);
285
329
  }
@@ -287,18 +331,18 @@ async function handleUserPromptSubmit(event, sessionId) {
287
331
  * Handle Stop event
288
332
  * Extracts metrics and conversations from agent session file incrementally
289
333
  */
290
- async function handleStop(event, sessionId) {
334
+ async function handleStop(event, sessionId, config) {
291
335
  // Accumulate active duration FIRST (marks end of active period)
292
336
  await accumulateActiveDuration(sessionId);
293
337
  // Then sync metrics/conversations
294
- await performIncrementalSync(event, 'Stop', sessionId);
338
+ await performIncrementalSync(event, 'Stop', sessionId, config);
295
339
  }
296
340
  /**
297
341
  * Handle SubagentStop event
298
342
  * Appends agent thought to _conversations.jsonl for later sync
299
343
  */
300
- async function handleSubagentStop(event, sessionId) {
301
- await performIncrementalSync(event, 'SubagentStop', sessionId);
344
+ async function handleSubagentStop(event, sessionId, config) {
345
+ await performIncrementalSync(event, 'SubagentStop', sessionId, config);
302
346
  }
303
347
  /**
304
348
  * Handle PreCompact event
@@ -355,8 +399,9 @@ function normalizeEventName(eventName, agentName) {
355
399
  * @param rawInput - Raw JSON input string
356
400
  * @param sessionId - The CodeMie session ID to use for all operations
357
401
  * @param agentName - The agent name for event normalization
402
+ * @param config - Optional configuration object (if not provided, reads from environment variables)
358
403
  */
359
- async function routeHookEvent(event, rawInput, sessionId, agentName) {
404
+ async function routeHookEvent(event, rawInput, sessionId, agentName, config) {
360
405
  const startTime = Date.now();
361
406
  try {
362
407
  // Normalize event name using agent-specific mapping
@@ -367,11 +412,11 @@ async function routeHookEvent(event, rawInput, sessionId, agentName) {
367
412
  switch (normalizedEventName) {
368
413
  case 'SessionStart':
369
414
  logger.info(`[hook:router] Calling handleSessionStart`);
370
- await handleSessionStart(event, rawInput, sessionId);
415
+ await handleSessionStart(event, rawInput, sessionId, config);
371
416
  break;
372
417
  case 'SessionEnd':
373
418
  logger.info(`[hook:router] Calling handleSessionEnd`);
374
- await handleSessionEnd(event, sessionId);
419
+ await handleSessionEnd(event, sessionId, config);
375
420
  break;
376
421
  case 'PermissionRequest':
377
422
  logger.info(`[hook:router] Calling handlePermissionRequest`);
@@ -379,15 +424,15 @@ async function routeHookEvent(event, rawInput, sessionId, agentName) {
379
424
  break;
380
425
  case 'Stop':
381
426
  logger.info(`[hook:router] Calling handleStop`);
382
- await handleStop(event, sessionId);
427
+ await handleStop(event, sessionId, config);
383
428
  break;
384
429
  case 'UserPromptSubmit':
385
430
  logger.info(`[hook:router] Calling handleUserPromptSubmit`);
386
- await handleUserPromptSubmit(event, sessionId);
431
+ await handleUserPromptSubmit(event, sessionId, config);
387
432
  break;
388
433
  case 'SubagentStop':
389
434
  logger.info(`[hook:router] Calling handleSubagentStop`);
390
- await handleSubagentStop(event, sessionId);
435
+ await handleSubagentStop(event, sessionId, config);
391
436
  break;
392
437
  case 'PreCompact':
393
438
  logger.info(`[hook:router] Calling handlePreCompact`);
@@ -414,14 +459,18 @@ async function routeHookEvent(event, rawInput, sessionId, agentName) {
414
459
  *
415
460
  * @param event - SessionStart event data
416
461
  * @param sessionId - The CodeMie session ID from logger context
462
+ * @param config - Optional configuration object (if not provided, reads from environment variables)
417
463
  */
418
- async function createSessionRecord(event, sessionId) {
464
+ async function createSessionRecord(event, sessionId, config) {
419
465
  try {
420
- // Get metadata from environment
421
- const agentName = process.env.CODEMIE_AGENT;
422
- const provider = process.env.CODEMIE_PROVIDER;
423
- const project = process.env.CODEMIE_PROJECT;
466
+ // Get metadata from config or environment
467
+ const agentName = getConfigValue('CODEMIE_AGENT', config);
468
+ const provider = getConfigValue('CODEMIE_PROVIDER', config);
469
+ const project = getConfigValue('CODEMIE_PROJECT', config);
424
470
  if (!agentName || !provider) {
471
+ if (config) {
472
+ throw new Error('Missing required config: agentName and provider are required for session creation');
473
+ }
425
474
  logger.warn('[hook:SessionStart] Missing required env vars for session creation');
426
475
  return;
427
476
  }
@@ -475,24 +524,25 @@ async function createSessionRecord(event, sessionId) {
475
524
  * @param event - SessionStart event data
476
525
  * @param sessionId - The CodeMie session ID (for file operations)
477
526
  * @param agentSessionId - The agent's session ID (for API)
527
+ * @param config - Optional configuration object (if not provided, reads from environment variables)
478
528
  */
479
- async function sendSessionStartMetrics(event, sessionId, agentSessionId) {
529
+ async function sendSessionStartMetrics(event, sessionId, agentSessionId, config) {
480
530
  try {
481
531
  // Only send metrics for SSO provider
482
- const provider = process.env.CODEMIE_PROVIDER;
532
+ const provider = getConfigValue('CODEMIE_PROVIDER', config);
483
533
  if (provider !== 'ai-run-sso') {
484
534
  logger.debug('[hook:SessionStart] Skipping metrics (not SSO provider)');
485
535
  return;
486
536
  }
487
- // Get required environment variables
488
- const agentName = process.env.CODEMIE_AGENT;
489
- const ssoUrl = process.env.CODEMIE_URL;
490
- const apiUrl = process.env.CODEMIE_BASE_URL;
491
- const cliVersion = process.env.CODEMIE_CLI_VERSION;
492
- const model = process.env.CODEMIE_MODEL;
493
- const project = process.env.CODEMIE_PROJECT;
537
+ // Get required configuration values
538
+ const agentName = getConfigValue('CODEMIE_AGENT', config);
539
+ const ssoUrl = getConfigValue('CODEMIE_URL', config);
540
+ const apiUrl = getConfigValue('CODEMIE_BASE_URL', config);
541
+ const cliVersion = getConfigValue('CODEMIE_CLI_VERSION', config);
542
+ const model = getConfigValue('CODEMIE_MODEL', config);
543
+ const project = getConfigValue('CODEMIE_PROJECT', config);
494
544
  if (!sessionId || !agentName || !ssoUrl || !apiUrl) {
495
- logger.debug('[hook:SessionStart] Missing required env vars for metrics');
545
+ logger.debug('[hook:SessionStart] Missing required config for metrics');
496
546
  return;
497
547
  }
498
548
  // Determine working directory
@@ -509,27 +559,37 @@ async function sendSessionStartMetrics(event, sessionId, agentSessionId) {
509
559
  catch (error) {
510
560
  logger.debug('[hook:SessionStart] MCP detection failed, continuing without MCP data', error);
511
561
  }
512
- // Load SSO credentials
513
- const { CodeMieSSO } = await import('../../providers/plugins/sso/sso.auth.js');
514
- const sso = new CodeMieSSO();
515
- const credentials = await sso.getStoredCredentials(ssoUrl);
516
- if (!credentials || !credentials.cookies) {
517
- logger.info(`[hook:SessionStart] No SSO credentials found for ${ssoUrl}`);
562
+ // Load SSO credentials if not provided in config
563
+ let cookieHeader = config?.cookies || '';
564
+ if (!cookieHeader && ssoUrl) {
565
+ try {
566
+ const { CodeMieSSO } = await import('../../providers/plugins/sso/sso.auth.js');
567
+ const sso = new CodeMieSSO();
568
+ const credentials = await sso.getStoredCredentials(ssoUrl);
569
+ if (credentials?.cookies) {
570
+ cookieHeader = Object.entries(credentials.cookies)
571
+ .map(([key, value]) => `${key}=${value}`)
572
+ .join('; ');
573
+ }
574
+ }
575
+ catch (error) {
576
+ logger.debug('[hook:SessionStart] Failed to load SSO credentials:', error);
577
+ }
578
+ }
579
+ if (!cookieHeader) {
580
+ logger.info(`[hook:SessionStart] No SSO credentials available for ${ssoUrl}`);
518
581
  return;
519
582
  }
520
- // Build cookie header
521
- const cookieHeader = Object.entries(credentials.cookies)
522
- .map(([key, value]) => `${key}=${value}`)
523
- .join('; ');
524
583
  // Use MetricsSender to send session start metric
525
584
  const { MetricsSender } = await import('../../providers/plugins/sso/index.js');
585
+ const clientType = getConfigValue('CODEMIE_CLIENT_TYPE', config) || 'codemie-cli';
526
586
  const sender = new MetricsSender({
527
587
  baseUrl: apiUrl,
528
588
  cookies: cookieHeader,
529
589
  timeout: 10000,
530
590
  retryAttempts: 2,
531
591
  version: cliVersion,
532
- clientType: 'codemie-cli'
592
+ clientType
533
593
  });
534
594
  // Build status object with reason from event
535
595
  const status = {
@@ -676,24 +736,25 @@ async function renameSessionFiles(sessionId) {
676
736
  * @param event - SessionEnd event data
677
737
  * @param sessionId - The CodeMie session ID (for file operations)
678
738
  * @param agentSessionId - The agent's session ID (for API)
739
+ * @param config - Optional configuration object (if not provided, reads from environment variables)
679
740
  */
680
- async function sendSessionEndMetrics(event, sessionId, agentSessionId) {
741
+ async function sendSessionEndMetrics(event, sessionId, agentSessionId, config) {
681
742
  try {
682
743
  // Only send metrics for SSO provider
683
- const provider = process.env.CODEMIE_PROVIDER;
744
+ const provider = getConfigValue('CODEMIE_PROVIDER', config);
684
745
  if (provider !== 'ai-run-sso') {
685
746
  logger.debug('[hook:SessionEnd] Skipping metrics (not SSO provider)');
686
747
  return;
687
748
  }
688
- // Get required environment variables
689
- const agentName = process.env.CODEMIE_AGENT;
690
- const ssoUrl = process.env.CODEMIE_URL;
691
- const apiUrl = process.env.CODEMIE_BASE_URL;
692
- const cliVersion = process.env.CODEMIE_CLI_VERSION;
693
- const model = process.env.CODEMIE_MODEL;
694
- const project = process.env.CODEMIE_PROJECT;
749
+ // Get required configuration values
750
+ const agentName = getConfigValue('CODEMIE_AGENT', config);
751
+ const ssoUrl = getConfigValue('CODEMIE_URL', config);
752
+ const apiUrl = getConfigValue('CODEMIE_BASE_URL', config);
753
+ const cliVersion = getConfigValue('CODEMIE_CLI_VERSION', config);
754
+ const model = getConfigValue('CODEMIE_MODEL', config);
755
+ const project = getConfigValue('CODEMIE_PROJECT', config);
695
756
  if (!agentName || !ssoUrl || !apiUrl) {
696
- logger.debug('[hook:SessionEnd] Missing required env vars for metrics');
757
+ logger.debug('[hook:SessionEnd] Missing required config for metrics');
697
758
  return;
698
759
  }
699
760
  // Load session to get start time
@@ -713,27 +774,37 @@ async function sendSessionEndMetrics(event, sessionId, agentSessionId) {
713
774
  status: 'completed',
714
775
  reason: event.reason
715
776
  };
716
- // Load SSO credentials
717
- const { CodeMieSSO } = await import('../../providers/plugins/sso/sso.auth.js');
718
- const sso = new CodeMieSSO();
719
- const credentials = await sso.getStoredCredentials(ssoUrl);
720
- if (!credentials?.cookies) {
777
+ // Load SSO credentials if not provided in config
778
+ let cookieHeader = config?.cookies || '';
779
+ if (!cookieHeader && ssoUrl) {
780
+ try {
781
+ const { CodeMieSSO } = await import('../../providers/plugins/sso/sso.auth.js');
782
+ const sso = new CodeMieSSO();
783
+ const credentials = await sso.getStoredCredentials(ssoUrl);
784
+ if (credentials?.cookies) {
785
+ cookieHeader = Object.entries(credentials.cookies)
786
+ .map(([key, value]) => `${key}=${value}`)
787
+ .join('; ');
788
+ }
789
+ }
790
+ catch (error) {
791
+ logger.debug('[hook:SessionEnd] Failed to load SSO credentials:', error);
792
+ }
793
+ }
794
+ if (!cookieHeader) {
721
795
  logger.info(`[hook:SessionEnd] No SSO credentials found for ${ssoUrl}`);
722
796
  return;
723
797
  }
724
- // Build cookie header
725
- const cookieHeader = Object.entries(credentials.cookies)
726
- .map(([key, value]) => `${key}=${value}`)
727
- .join('; ');
728
798
  // Use MetricsSender to send session end metric
729
799
  const { MetricsSender } = await import('../../providers/plugins/sso/index.js');
800
+ const clientType = getConfigValue('CODEMIE_CLIENT_TYPE', config) || 'codemie-cli';
730
801
  const sender = new MetricsSender({
731
802
  baseUrl: apiUrl,
732
803
  cookies: cookieHeader,
733
804
  timeout: 10000,
734
805
  retryAttempts: 2,
735
806
  version: cliVersion,
736
- clientType: 'codemie-cli'
807
+ clientType
737
808
  });
738
809
  // Send session end metric (use agent session ID for API)
739
810
  await sender.sendSessionEnd({
@@ -759,6 +830,137 @@ async function sendSessionEndMetrics(event, sessionId, agentSessionId) {
759
830
  // Don't throw - metrics failures should not block agent execution
760
831
  }
761
832
  }
833
+ /**
834
+ * Validate hook event required fields
835
+ * @param event - Hook event to validate
836
+ * @param config - Optional configuration object (if provided, throws errors; otherwise sets exitCode)
837
+ * @throws Error if validation fails and config is provided
838
+ */
839
+ function validateHookEvent(event, config) {
840
+ if (!event.session_id) {
841
+ const error = new Error('Missing required field: session_id');
842
+ if (config) {
843
+ throw error;
844
+ }
845
+ logger.error('[hook] Missing required field: session_id');
846
+ logger.debug(`[hook] Received event: ${JSON.stringify(event)}`);
847
+ process.exitCode = 2;
848
+ return;
849
+ }
850
+ if (!event.hook_event_name) {
851
+ const error = new Error('Missing required field: hook_event_name');
852
+ if (config) {
853
+ throw error;
854
+ }
855
+ logger.error('[hook] Missing required field: hook_event_name');
856
+ logger.debug(`[hook] Received event: ${JSON.stringify(event)}`);
857
+ process.exitCode = 2;
858
+ return;
859
+ }
860
+ if (!event.transcript_path) {
861
+ const error = new Error('Missing required field: transcript_path');
862
+ if (config) {
863
+ throw error;
864
+ }
865
+ logger.error('[hook] Missing required field: transcript_path');
866
+ logger.debug(`[hook] Received event: ${JSON.stringify(event)}`);
867
+ process.exitCode = 2;
868
+ return;
869
+ }
870
+ }
871
+ /**
872
+ * Initialize hook context (logger and session/agent info)
873
+ * @param config - Optional configuration object (if not provided, reads from environment variables)
874
+ * @returns Object with sessionId and agentName
875
+ */
876
+ function initializeHookContext(config) {
877
+ let sessionId;
878
+ let agentName;
879
+ if (config) {
880
+ // Use config object
881
+ sessionId = config.sessionId;
882
+ agentName = config.agentName;
883
+ // Initialize logger context from config
884
+ logger.setAgentName(config.agentName);
885
+ logger.setSessionId(config.sessionId);
886
+ if (config.profileName) {
887
+ logger.setProfileName(config.profileName);
888
+ }
889
+ }
890
+ else {
891
+ // Use environment variables (CLI mode)
892
+ sessionId = initializeLoggerContext();
893
+ agentName = process.env.CODEMIE_AGENT || 'unknown';
894
+ }
895
+ return { sessionId, agentName };
896
+ }
897
+ /**
898
+ * Apply hook transformation if agent provides a transformer
899
+ * @param event - Hook event to transform
900
+ * @param agentName - Agent name to get transformer from
901
+ * @returns Transformed event or original event if no transformer available
902
+ */
903
+ function applyHookTransformation(event, agentName) {
904
+ let transformedEvent = event;
905
+ try {
906
+ const agent = AgentRegistry.getAgent(agentName);
907
+ if (agent) {
908
+ const transformer = agent.getHookTransformer?.();
909
+ if (transformer) {
910
+ logger.debug(`[hook] Applying ${agentName} hook transformer`);
911
+ transformedEvent = transformer.transform(event);
912
+ logger.debug(`[hook] Transformation complete: ${event.hook_event_name} → ${transformedEvent.hook_event_name}`);
913
+ }
914
+ else {
915
+ logger.debug(`[hook] No transformer available for ${agentName}, using event as-is`);
916
+ }
917
+ }
918
+ }
919
+ catch (transformError) {
920
+ const transformMsg = transformError instanceof Error ? transformError.message : String(transformError);
921
+ logger.error(`[hook] Transformation failed: ${transformMsg}, using original event`);
922
+ // Continue with original event on transformation failure
923
+ transformedEvent = event;
924
+ }
925
+ return transformedEvent;
926
+ }
927
+ /**
928
+ * Normalize event name and log processing info
929
+ * @param event - Hook event (may be transformed)
930
+ * @param sessionId - CodeMie session ID
931
+ * @param agentName - Agent name
932
+ * @returns Normalized event name
933
+ */
934
+ function normalizeAndLogEvent(event, sessionId, agentName) {
935
+ const normalizedEventName = normalizeEventName(event.hook_event_name, agentName);
936
+ logger.info(`[hook] Processing ${normalizedEventName} event (codemie_session=${sessionId.slice(0, 8)}..., agent_session=${event.session_id.slice(0, 8)}...)`);
937
+ return normalizedEventName;
938
+ }
939
+ /**
940
+ * Process a hook event programmatically
941
+ * Main entry point for programmatic API usage (e.g., VSCode plugin)
942
+ *
943
+ * @param event - Hook event to process
944
+ * @param config - Optional configuration object (if not provided, reads from environment variables)
945
+ * @throws Error if event processing fails and config is provided
946
+ */
947
+ export async function processEvent(event, config) {
948
+ // Validate required fields
949
+ validateHookEvent(event, config);
950
+ if (process.exitCode === 2) {
951
+ return; // Validation failed in CLI mode
952
+ }
953
+ // Initialize logger context
954
+ const { sessionId, agentName } = initializeHookContext(config);
955
+ // Apply hook transformation if agent provides a transformer
956
+ const transformedEvent = applyHookTransformation(event, agentName);
957
+ // Normalize event name and log processing info
958
+ normalizeAndLogEvent(transformedEvent, sessionId, agentName);
959
+ // Route to appropriate handler
960
+ // Note: routeHookEvent expects rawInput for PermissionRequest, but we don't have it in programmatic mode
961
+ // Pass empty string as rawInput when config is provided
962
+ await routeHookEvent(transformedEvent, config ? '' : '', sessionId, agentName, config);
963
+ }
762
964
  /**
763
965
  * Create unified hook command
764
966
  * Routes to appropriate handler based on hook_event_name in JSON payload
@@ -802,33 +1004,11 @@ export function createHookCommand() {
802
1004
  }
803
1005
  // Initialize logger context using CODEMIE_SESSION_ID from environment
804
1006
  // This ensures consistent session ID across all hooks
805
- const sessionId = initializeLoggerContext();
806
- // Get agent name from environment
807
- const agentName = process.env.CODEMIE_AGENT || 'unknown';
1007
+ const { sessionId, agentName } = initializeHookContext();
808
1008
  // Apply hook transformation if agent provides a transformer
809
- let transformedEvent = event;
810
- try {
811
- const agent = AgentRegistry.getAgent(agentName);
812
- if (agent) {
813
- const transformer = agent.getHookTransformer?.();
814
- if (transformer) {
815
- logger.debug(`[hook] Applying ${agentName} hook transformer`);
816
- transformedEvent = transformer.transform(event);
817
- logger.debug(`[hook] Transformation complete: ${event.hook_event_name} → ${transformedEvent.hook_event_name}`);
818
- }
819
- else {
820
- logger.debug(`[hook] No transformer available for ${agentName}, using event as-is`);
821
- }
822
- }
823
- }
824
- catch (transformError) {
825
- const transformMsg = transformError instanceof Error ? transformError.message : String(transformError);
826
- logger.error(`[hook] Transformation failed: ${transformMsg}, using original event`);
827
- // Continue with original event on transformation failure
828
- transformedEvent = event;
829
- }
830
- // Log hook invocation
831
- logger.info(`[hook] Processing ${transformedEvent.hook_event_name} event (codemie_session=${sessionId.slice(0, 8)}..., agent_session=${transformedEvent.session_id.slice(0, 8)}...)`);
1009
+ const transformedEvent = applyHookTransformation(event, agentName);
1010
+ // Normalize event name and log processing info
1011
+ normalizeAndLogEvent(transformedEvent, sessionId, agentName);
832
1012
  // Route to appropriate handler with transformed event and session ID
833
1013
  await routeHookEvent(transformedEvent, input, sessionId, agentName);
834
1014
  // Log successful completion