ccjk 12.2.1 → 12.3.1

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 (135) hide show
  1. package/dist/chunks/agent-teams.mjs +3 -3
  2. package/dist/chunks/agent.mjs +2 -2
  3. package/dist/chunks/agents.mjs +4 -5
  4. package/dist/chunks/api-cli.mjs +5 -5
  5. package/dist/chunks/api-providers.mjs +1 -1
  6. package/dist/chunks/api.mjs +4 -4
  7. package/dist/chunks/auto-bootstrap.mjs +1 -1
  8. package/dist/chunks/auto-fixer.mjs +3 -3
  9. package/dist/chunks/auto-init.mjs +3 -77
  10. package/dist/chunks/auto-updater.mjs +9 -9
  11. package/dist/chunks/banner.mjs +2 -2
  12. package/dist/chunks/boost.mjs +4 -4
  13. package/dist/chunks/ccjk-agents.mjs +3 -3
  14. package/dist/chunks/ccjk-all.mjs +6 -6
  15. package/dist/chunks/ccjk-config.mjs +2 -2
  16. package/dist/chunks/ccjk-hooks.mjs +4 -4
  17. package/dist/chunks/ccjk-mcp.mjs +5 -5
  18. package/dist/chunks/ccjk-setup.mjs +5 -5
  19. package/dist/chunks/ccjk-skills.mjs +5 -5
  20. package/dist/chunks/ccr.mjs +14 -14
  21. package/dist/chunks/ccu.mjs +2 -2
  22. package/dist/chunks/check-updates.mjs +6 -6
  23. package/dist/chunks/claude-code-config-manager.mjs +5 -4
  24. package/dist/chunks/claude-code-incremental-manager.mjs +6 -6
  25. package/dist/chunks/claude-config.mjs +1 -1
  26. package/dist/chunks/claude-wrapper.mjs +1 -1
  27. package/dist/chunks/cli-hook.mjs +998 -8
  28. package/dist/chunks/codex-config-switch.mjs +6 -6
  29. package/dist/chunks/codex-provider-manager.mjs +6 -6
  30. package/dist/chunks/codex-uninstaller.mjs +2 -2
  31. package/dist/chunks/codex.mjs +5 -5
  32. package/dist/chunks/commands.mjs +2 -2
  33. package/dist/chunks/commands2.mjs +1 -1
  34. package/dist/chunks/commit.mjs +2 -2
  35. package/dist/chunks/completion.mjs +2 -2
  36. package/dist/chunks/config-consolidator.mjs +2 -2
  37. package/dist/chunks/config-switch.mjs +7 -7
  38. package/dist/chunks/config.mjs +3 -3
  39. package/dist/chunks/config2.mjs +4 -4
  40. package/dist/chunks/config3.mjs +3 -3
  41. package/dist/chunks/constants.mjs +1 -1
  42. package/dist/chunks/context-opt.mjs +442 -0
  43. package/dist/chunks/convoy-manager.mjs +355 -3
  44. package/dist/chunks/dashboard.mjs +2 -2
  45. package/dist/chunks/doctor.mjs +4 -4
  46. package/dist/chunks/evolution.mjs +2 -2
  47. package/dist/chunks/health-alerts.mjs +530 -4
  48. package/dist/chunks/help.mjs +1 -1
  49. package/dist/chunks/index.mjs +0 -23
  50. package/dist/chunks/index10.mjs +571 -634
  51. package/dist/chunks/index11.mjs +569 -1061
  52. package/dist/chunks/index12.mjs +1076 -914
  53. package/dist/chunks/index13.mjs +951 -135
  54. package/dist/chunks/index14.mjs +184 -209
  55. package/dist/chunks/index15.mjs +218 -0
  56. package/dist/chunks/index2.mjs +24 -19
  57. package/dist/chunks/index3.mjs +12 -19085
  58. package/dist/chunks/index4.mjs +19092 -16
  59. package/dist/chunks/index5.mjs +16 -7602
  60. package/dist/chunks/index6.mjs +7590 -159
  61. package/dist/chunks/index7.mjs +171 -1602
  62. package/dist/chunks/index8.mjs +1602 -19
  63. package/dist/chunks/index9.mjs +15 -612
  64. package/dist/chunks/init.mjs +13 -13
  65. package/dist/chunks/installer.mjs +5 -5
  66. package/dist/chunks/installer2.mjs +1 -1
  67. package/dist/chunks/interview.mjs +4 -4
  68. package/dist/chunks/manager.mjs +1 -1
  69. package/dist/chunks/marketplace.mjs +2 -2
  70. package/dist/chunks/mcp-cli.mjs +9 -9
  71. package/dist/chunks/mcp.mjs +7 -7
  72. package/dist/chunks/memory.mjs +3 -3
  73. package/dist/chunks/menu-hierarchical.mjs +14 -14
  74. package/dist/chunks/menu.mjs +12 -12
  75. package/dist/chunks/metrics-display.mjs +1 -1
  76. package/dist/chunks/migrator.mjs +1 -1
  77. package/dist/chunks/monitor.mjs +2 -2
  78. package/dist/chunks/notification.mjs +4 -4
  79. package/dist/chunks/onboarding-wizard.mjs +2 -2
  80. package/dist/chunks/onboarding.mjs +4 -4
  81. package/dist/chunks/package.mjs +1 -1
  82. package/dist/chunks/paradigm.mjs +1 -1
  83. package/dist/chunks/permission-manager.mjs +2 -2
  84. package/dist/chunks/permissions.mjs +3 -3
  85. package/dist/chunks/persistence-manager.mjs +3 -3
  86. package/dist/chunks/plugin.mjs +2 -2
  87. package/dist/chunks/prompts.mjs +5 -5
  88. package/dist/chunks/providers.mjs +2 -2
  89. package/dist/chunks/quick-actions.mjs +2 -2
  90. package/dist/chunks/quick-provider.mjs +6 -5
  91. package/dist/chunks/quick-setup.mjs +10 -10
  92. package/dist/chunks/remote.mjs +5 -5
  93. package/dist/chunks/session.mjs +2 -2
  94. package/dist/chunks/sessions.mjs +1 -1
  95. package/dist/chunks/silent-updater.mjs +1 -1
  96. package/dist/chunks/simple-config.mjs +1 -1
  97. package/dist/chunks/skill2.mjs +3 -3
  98. package/dist/chunks/skills-sync.mjs +4 -4
  99. package/dist/chunks/skills.mjs +3 -3
  100. package/dist/chunks/slash-commands.mjs +3 -3
  101. package/dist/chunks/startup.mjs +1 -1
  102. package/dist/chunks/stats.mjs +2 -2
  103. package/dist/chunks/status.mjs +2 -2
  104. package/dist/chunks/team.mjs +3 -3
  105. package/dist/chunks/thinking.mjs +4 -4
  106. package/dist/chunks/trace.mjs +2 -2
  107. package/dist/chunks/uninstall.mjs +8 -8
  108. package/dist/chunks/update.mjs +9 -9
  109. package/dist/chunks/upgrade-manager.mjs +3 -3
  110. package/dist/chunks/version-checker.mjs +4 -4
  111. package/dist/chunks/vim.mjs +3 -3
  112. package/dist/chunks/workflows.mjs +1 -1
  113. package/dist/chunks/wsl.mjs +1 -1
  114. package/dist/chunks/zero-config.mjs +3 -3
  115. package/dist/cli.mjs +56 -23
  116. package/dist/index.mjs +5 -5
  117. package/dist/shared/ccjk.B1TwPltj.mjs +78 -0
  118. package/dist/shared/{ccjk.CePkJq2S.mjs → ccjk.BfIpomdz.mjs} +1 -1
  119. package/dist/shared/{ccjk.D8ZLYSZZ.mjs → ccjk.CXzjn01x.mjs} +1 -1
  120. package/dist/shared/{ccjk.Cjj8SVrn.mjs → ccjk.Cot9p9_n.mjs} +1 -1
  121. package/dist/shared/{ccjk.CvChMYvB.mjs → ccjk.DCw2WnZU.mjs} +1 -1
  122. package/dist/shared/{ccjk.DG_o24cZ.mjs → ccjk.DJdmgr2d.mjs} +1 -1
  123. package/dist/shared/{ccjk.BIxuVL3_.mjs → ccjk.DcKLglJQ.mjs} +2 -2
  124. package/dist/shared/{ccjk.DLLw-h4Y.mjs → ccjk.DfXjf8EC.mjs} +2 -2
  125. package/dist/shared/{ccjk.KpFl2RDA.mjs → ccjk.DpstNaeR.mjs} +3 -3
  126. package/dist/shared/{ccjk.DOBWBkFR.mjs → ccjk.XsJWJuQP.mjs} +5 -5
  127. package/dist/shared/{ccjk._dESH4Rk.mjs → ccjk.dYDLfmph.mjs} +1 -1
  128. package/dist/shared/{ccjk.DS7UESmF.mjs → ccjk.hrRv8G6j.mjs} +4 -4
  129. package/dist/shared/{ccjk.BWFpnOr3.mjs → ccjk.mJpVRDZ8.mjs} +1 -1
  130. package/dist/templates/claude-code/common/settings.json +3 -1
  131. package/package.json +20 -18
  132. package/templates/claude-code/common/settings.json +3 -1
  133. package/dist/chunks/context-loader.mjs +0 -351
  134. package/dist/chunks/context.mjs +0 -372
  135. package/dist/chunks/health-check.mjs +0 -532
@@ -1,9 +1,18 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import { a as getGlobalStateManager, g as getGlobalConvoyManager, S as SessionIntelligence } from './convoy-manager.mjs';
2
+ import { a as getGlobalStateManager, g as getGlobalConvoyManager, c as contextLoader, S as SessionIntelligence } from './convoy-manager.mjs';
3
+ import { l as logger } from '../shared/ccjk.DJdmgr2d.mjs';
4
+ import { h as hookRegistry } from '../shared/ccjk.B1TwPltj.mjs';
5
+ import { Buffer } from 'node:buffer';
6
+ import { randomUUID } from 'node:crypto';
7
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
8
+ import { d as dirname, j as join } from '../shared/ccjk.bQ7Dh1g4.mjs';
3
9
  import { n as nanoid } from '../shared/ccjk.BoApaI4j.mjs';
4
- import { existsSync, readFileSync, writeFileSync } from 'node:fs';
5
- import { j as join } from '../shared/ccjk.bQ7Dh1g4.mjs';
6
10
  import process__default from 'node:process';
11
+ import 'tinyglobby';
12
+ import '../shared/ccjk.BfIpomdz.mjs';
13
+ import './index3.mjs';
14
+ import '../shared/ccjk.BAGoDD49.mjs';
15
+ import '../shared/ccjk.BxSmJ8B7.mjs';
7
16
  import 'node:child_process';
8
17
  import 'node:fs/promises';
9
18
  import 'node:os';
@@ -12,7 +21,918 @@ import './main.mjs';
12
21
  import 'module';
13
22
  import 'node:stream';
14
23
  import 'node:readline';
15
- import 'node:crypto';
24
+
25
+ async function emitCommandHookEvent(event, data, sessionId) {
26
+ try {
27
+ const context = {
28
+ event,
29
+ sessionId,
30
+ data,
31
+ timestamp: Date.now(),
32
+ metadata: {
33
+ source: "brain-router"
34
+ }
35
+ };
36
+ await hookRegistry.execute(context);
37
+ } catch (error) {
38
+ logger.debug(`Command hook bridge skipped for "${event}": ${String(error)}`);
39
+ }
40
+ }
41
+
42
+ const DEFAULT_CONFIG = {
43
+ enablePersistence: false,
44
+ maxHistorySize: 1e3,
45
+ messageRetentionTime: 24 * 60 * 60 * 1e3,
46
+ // 24 hours
47
+ enableLogging: true,
48
+ logLevel: "info",
49
+ enableValidation: true,
50
+ maxMessageSize: 1024 * 1024,
51
+ // 1MB
52
+ enableDeadLetterQueue: true
53
+ };
54
+ class FileMessageStorage {
55
+ filePath;
56
+ constructor(filePath) {
57
+ this.filePath = filePath;
58
+ this.ensureDirectory();
59
+ }
60
+ ensureDirectory() {
61
+ const dir = dirname(this.filePath);
62
+ if (!existsSync(dir)) {
63
+ mkdirSync(dir, { recursive: true });
64
+ }
65
+ }
66
+ async save(message) {
67
+ try {
68
+ const messages = await this.load();
69
+ messages.push(message);
70
+ writeFileSync(this.filePath, JSON.stringify(messages, null, 2), "utf-8");
71
+ } catch (error) {
72
+ console.error("Failed to save message:", error);
73
+ throw error;
74
+ }
75
+ }
76
+ async load(filter) {
77
+ try {
78
+ if (!existsSync(this.filePath)) {
79
+ return [];
80
+ }
81
+ const content = readFileSync(this.filePath, "utf-8");
82
+ const messages = JSON.parse(content);
83
+ if (filter) {
84
+ return messages.filter(filter);
85
+ }
86
+ return messages;
87
+ } catch (error) {
88
+ console.error("Failed to load messages:", error);
89
+ return [];
90
+ }
91
+ }
92
+ async delete(messageId) {
93
+ try {
94
+ const messages = await this.load();
95
+ const filtered = messages.filter((msg) => msg.id !== messageId);
96
+ writeFileSync(this.filePath, JSON.stringify(filtered, null, 2), "utf-8");
97
+ } catch (error) {
98
+ console.error("Failed to delete message:", error);
99
+ throw error;
100
+ }
101
+ }
102
+ async clear() {
103
+ try {
104
+ writeFileSync(this.filePath, JSON.stringify([], null, 2), "utf-8");
105
+ } catch (error) {
106
+ console.error("Failed to clear messages:", error);
107
+ throw error;
108
+ }
109
+ }
110
+ async getStats() {
111
+ try {
112
+ if (!existsSync(this.filePath)) {
113
+ return { count: 0, size: 0 };
114
+ }
115
+ const messages = await this.load();
116
+ const content = readFileSync(this.filePath, "utf-8");
117
+ return {
118
+ count: messages.length,
119
+ size: Buffer.byteLength(content, "utf-8")
120
+ };
121
+ } catch (error) {
122
+ console.error("Failed to get storage stats:", error);
123
+ return { count: 0, size: 0 };
124
+ }
125
+ }
126
+ }
127
+ class MessageBus {
128
+ config;
129
+ subscriptions;
130
+ messageHistory;
131
+ deadLetterQueue;
132
+ storage;
133
+ stats;
134
+ constructor(config = {}) {
135
+ this.config = { ...DEFAULT_CONFIG, ...config };
136
+ this.subscriptions = /* @__PURE__ */ new Map();
137
+ this.messageHistory = [];
138
+ this.deadLetterQueue = [];
139
+ if (this.config.enablePersistence && this.config.persistencePath) {
140
+ this.storage = new FileMessageStorage(this.config.persistencePath);
141
+ this.loadPersistedMessages();
142
+ }
143
+ this.stats = {
144
+ totalMessages: 0,
145
+ messagesByType: {},
146
+ messagesByStatus: {},
147
+ activeSubscriptions: 0,
148
+ historySize: 0,
149
+ deadLetterQueueSize: 0,
150
+ avgProcessingTime: 0
151
+ };
152
+ this.startCleanupInterval();
153
+ }
154
+ /**
155
+ * Publish a message to the bus
156
+ */
157
+ async publish(type, from, to, subject, payload, options = {}) {
158
+ const message = {
159
+ id: randomUUID(),
160
+ type,
161
+ from,
162
+ to,
163
+ subject,
164
+ payload,
165
+ priority: options.priority || "normal",
166
+ status: "pending",
167
+ timestamp: Date.now(),
168
+ correlationId: options.correlationId,
169
+ replyTo: options.replyTo,
170
+ metadata: options.metadata
171
+ };
172
+ if (this.config.enableValidation) {
173
+ this.validateMessage(message);
174
+ }
175
+ this.logMessage("publish", message);
176
+ this.updateStats(message);
177
+ this.addToHistory(message);
178
+ if (this.storage) {
179
+ await this.storage.save(message);
180
+ }
181
+ await this.routeMessage(message);
182
+ return message.id;
183
+ }
184
+ /**
185
+ * Subscribe to messages
186
+ */
187
+ subscribe(subscriber, handler, options = {}) {
188
+ const subscription = {
189
+ id: randomUUID(),
190
+ subscriber,
191
+ options,
192
+ handler,
193
+ createdAt: Date.now(),
194
+ unsubscribe: () => this.unsubscribe(subscription.id)
195
+ };
196
+ this.subscriptions.set(subscription.id, subscription);
197
+ this.stats.activeSubscriptions = this.subscriptions.size;
198
+ this.log("info", `Agent ${subscriber} subscribed with ID ${subscription.id}`);
199
+ return subscription;
200
+ }
201
+ /**
202
+ * Unsubscribe from messages
203
+ */
204
+ unsubscribe(subscriptionId) {
205
+ const subscription = this.subscriptions.get(subscriptionId);
206
+ if (subscription) {
207
+ this.subscriptions.delete(subscriptionId);
208
+ this.stats.activeSubscriptions = this.subscriptions.size;
209
+ this.log("info", `Subscription ${subscriptionId} removed`);
210
+ }
211
+ }
212
+ /**
213
+ * Get message by ID
214
+ */
215
+ getMessage(messageId) {
216
+ return this.messageHistory.find((msg) => msg.id === messageId);
217
+ }
218
+ /**
219
+ * Get messages by filter
220
+ */
221
+ getMessages(filter) {
222
+ return this.messageHistory.filter(filter);
223
+ }
224
+ /**
225
+ * Update message status
226
+ */
227
+ async updateMessageStatus(messageId, status, error) {
228
+ const message = this.getMessage(messageId);
229
+ if (message) {
230
+ message.status = status;
231
+ if (error) {
232
+ message.error = error;
233
+ }
234
+ if (status === "failed" && this.config.enableDeadLetterQueue) {
235
+ this.deadLetterQueue.push(message);
236
+ this.stats.deadLetterQueueSize = this.deadLetterQueue.length;
237
+ }
238
+ this.stats.messagesByStatus[status] = (this.stats.messagesByStatus[status] || 0) + 1;
239
+ if (this.storage) {
240
+ await this.storage.save(message);
241
+ }
242
+ this.log("debug", `Message ${messageId} status updated to ${status}`);
243
+ }
244
+ }
245
+ /**
246
+ * Get message bus statistics
247
+ */
248
+ getStats() {
249
+ return { ...this.stats };
250
+ }
251
+ /**
252
+ * Clear message history
253
+ */
254
+ async clearHistory() {
255
+ this.messageHistory = [];
256
+ this.stats.historySize = 0;
257
+ if (this.storage) {
258
+ await this.storage.clear();
259
+ }
260
+ this.log("info", "Message history cleared");
261
+ }
262
+ /**
263
+ * Clear dead letter queue
264
+ */
265
+ clearDeadLetterQueue() {
266
+ this.deadLetterQueue = [];
267
+ this.stats.deadLetterQueueSize = 0;
268
+ this.log("info", "Dead letter queue cleared");
269
+ }
270
+ /**
271
+ * Get dead letter queue messages
272
+ */
273
+ getDeadLetterQueue() {
274
+ return [...this.deadLetterQueue];
275
+ }
276
+ /**
277
+ * Shutdown message bus
278
+ */
279
+ async shutdown() {
280
+ this.log("info", "Shutting down message bus");
281
+ this.subscriptions.clear();
282
+ this.stats.activeSubscriptions = 0;
283
+ if (this.storage && this.messageHistory.length > 0) {
284
+ for (const message of this.messageHistory) {
285
+ await this.storage.save(message);
286
+ }
287
+ }
288
+ this.log("info", "Message bus shutdown complete");
289
+ }
290
+ /**
291
+ * Route message to subscribers
292
+ */
293
+ async routeMessage(message) {
294
+ const startTime = Date.now();
295
+ const matchingSubscriptions = this.findMatchingSubscriptions(message);
296
+ this.log("debug", `Routing message ${message.id} to ${matchingSubscriptions.length} subscribers`);
297
+ for (const subscription of matchingSubscriptions) {
298
+ try {
299
+ message.status = "processing";
300
+ if (subscription.options.async) {
301
+ await subscription.handler(message);
302
+ } else {
303
+ subscription.handler(message);
304
+ }
305
+ message.status = "completed";
306
+ } catch (error) {
307
+ this.log("error", `Error handling message ${message.id} in subscription ${subscription.id}:`, error);
308
+ await this.updateMessageStatus(message.id, "failed", {
309
+ code: "HANDLER_ERROR",
310
+ message: error instanceof Error ? error.message : String(error),
311
+ stack: error instanceof Error ? error.stack : void 0
312
+ });
313
+ }
314
+ }
315
+ const processingTime = Date.now() - startTime;
316
+ this.stats.avgProcessingTime = (this.stats.avgProcessingTime + processingTime) / 2;
317
+ }
318
+ /**
319
+ * Find subscriptions matching the message
320
+ */
321
+ findMatchingSubscriptions(message) {
322
+ const matching = [];
323
+ const subscriptions = Array.from(this.subscriptions.values());
324
+ for (const subscription of subscriptions) {
325
+ const isAddressed = message.to === "all" || message.to === subscription.subscriber || Array.isArray(message.to) && message.to.includes(subscription.subscriber);
326
+ if (!isAddressed) {
327
+ continue;
328
+ }
329
+ if (!this.matchesSubscriptionFilters(message, subscription.options)) {
330
+ continue;
331
+ }
332
+ matching.push(subscription);
333
+ }
334
+ return matching;
335
+ }
336
+ /**
337
+ * Check if message matches subscription filters
338
+ */
339
+ matchesSubscriptionFilters(message, options) {
340
+ if (options.type) {
341
+ const types = Array.isArray(options.type) ? options.type : [options.type];
342
+ if (!types.includes(message.type)) {
343
+ return false;
344
+ }
345
+ }
346
+ if (options.from) {
347
+ const senders = Array.isArray(options.from) ? options.from : [options.from];
348
+ if (!senders.includes(message.from)) {
349
+ return false;
350
+ }
351
+ }
352
+ if (options.priority) {
353
+ const priorities = Array.isArray(options.priority) ? options.priority : [options.priority];
354
+ if (!priorities.includes(message.priority)) {
355
+ return false;
356
+ }
357
+ }
358
+ if (options.filter && !options.filter(message)) {
359
+ return false;
360
+ }
361
+ return true;
362
+ }
363
+ /**
364
+ * Validate message
365
+ */
366
+ validateMessage(message) {
367
+ if (!message.id) {
368
+ throw new Error("Message ID is required");
369
+ }
370
+ if (!message.type) {
371
+ throw new Error("Message type is required");
372
+ }
373
+ if (!message.from) {
374
+ throw new Error("Message sender is required");
375
+ }
376
+ if (!message.to) {
377
+ throw new Error("Message recipient is required");
378
+ }
379
+ if (!message.subject) {
380
+ throw new Error("Message subject is required");
381
+ }
382
+ if (this.config.maxMessageSize) {
383
+ const messageSize = Buffer.byteLength(JSON.stringify(message), "utf-8");
384
+ if (messageSize > this.config.maxMessageSize) {
385
+ throw new Error(`Message size ${messageSize} exceeds maximum ${this.config.maxMessageSize}`);
386
+ }
387
+ }
388
+ }
389
+ /**
390
+ * Add message to history
391
+ */
392
+ addToHistory(message) {
393
+ this.messageHistory.push(message);
394
+ this.stats.historySize = this.messageHistory.length;
395
+ const maxHistorySize = this.config.maxHistorySize ?? 1e3;
396
+ if (this.messageHistory.length > maxHistorySize) {
397
+ this.messageHistory.shift();
398
+ this.stats.historySize = this.messageHistory.length;
399
+ }
400
+ }
401
+ /**
402
+ * Update statistics
403
+ */
404
+ updateStats(message) {
405
+ this.stats.totalMessages++;
406
+ this.stats.messagesByType[message.type] = (this.stats.messagesByType[message.type] || 0) + 1;
407
+ this.stats.messagesByStatus[message.status] = (this.stats.messagesByStatus[message.status] || 0) + 1;
408
+ }
409
+ /**
410
+ * Load persisted messages
411
+ */
412
+ async loadPersistedMessages() {
413
+ if (!this.storage) {
414
+ return;
415
+ }
416
+ try {
417
+ const messages = await this.storage.load();
418
+ this.messageHistory = messages;
419
+ this.stats.historySize = messages.length;
420
+ this.log("info", `Loaded ${messages.length} persisted messages`);
421
+ } catch (error) {
422
+ this.log("error", "Failed to load persisted messages:", error);
423
+ }
424
+ }
425
+ /**
426
+ * Start cleanup interval for old messages
427
+ */
428
+ startCleanupInterval() {
429
+ setInterval(() => {
430
+ const now = Date.now();
431
+ const retentionTime = this.config.messageRetentionTime ?? 864e5;
432
+ this.messageHistory = this.messageHistory.filter(
433
+ (msg) => now - msg.timestamp < retentionTime
434
+ );
435
+ this.stats.historySize = this.messageHistory.length;
436
+ this.deadLetterQueue = this.deadLetterQueue.filter(
437
+ (msg) => now - msg.timestamp < retentionTime
438
+ );
439
+ this.stats.deadLetterQueueSize = this.deadLetterQueue.length;
440
+ this.log("debug", "Cleanup completed");
441
+ }, 60 * 60 * 1e3);
442
+ }
443
+ /**
444
+ * Log message
445
+ */
446
+ logMessage(action, message) {
447
+ if (!this.config.enableLogging) {
448
+ return;
449
+ }
450
+ const logLevel = this.config.logLevel;
451
+ const shouldLog = logLevel === "debug" || logLevel === "info" && ["publish", "subscribe"].includes(action) || logLevel === "warn" && message.priority === "high" || logLevel === "error" && message.status === "failed";
452
+ if (shouldLog) {
453
+ this.log("debug", `[${action}] ${message.type} from ${message.from} to ${message.to}: ${message.subject}`);
454
+ }
455
+ }
456
+ /**
457
+ * Internal logging
458
+ */
459
+ log(level, message, ...args) {
460
+ if (!this.config.enableLogging) {
461
+ return;
462
+ }
463
+ const levels = ["debug", "info", "warn", "error"];
464
+ const configLevel = levels.indexOf(this.config.logLevel ?? "info");
465
+ const messageLevel = levels.indexOf(level);
466
+ if (messageLevel >= configLevel) {
467
+ console[level](`[MessageBus] ${message}`, ...args);
468
+ }
469
+ }
470
+ }
471
+ let globalMessageBus = null;
472
+ function getMessageBus(config) {
473
+ if (!globalMessageBus) {
474
+ globalMessageBus = new MessageBus(config);
475
+ }
476
+ return globalMessageBus;
477
+ }
478
+
479
+ class SkillRegistry extends EventEmitter {
480
+ skills;
481
+ filePathIndex;
482
+ triggerIndex;
483
+ messageBus = getMessageBus();
484
+ constructor() {
485
+ super();
486
+ this.skills = /* @__PURE__ */ new Map();
487
+ this.filePathIndex = /* @__PURE__ */ new Map();
488
+ this.triggerIndex = /* @__PURE__ */ new Map();
489
+ }
490
+ /**
491
+ * Register a skill
492
+ *
493
+ * @param skill - Parsed skill file
494
+ * @param source - Skill source type
495
+ * @returns Registered entry
496
+ */
497
+ register(skill, source = "user") {
498
+ const id = skill.metadata.name;
499
+ const existing = this.skills.get(id);
500
+ const dependencies = this.extractDependencies(skill.metadata);
501
+ const entry = {
502
+ id,
503
+ metadata: skill.metadata,
504
+ content: skill.content,
505
+ filePath: skill.filePath,
506
+ enabled: existing?.enabled ?? true,
507
+ source,
508
+ registeredAt: existing?.registeredAt ?? Date.now(),
509
+ modifiedAt: skill.modifiedAt?.getTime() ?? Date.now(),
510
+ estimatedTokens: this.estimateTokens(skill),
511
+ dependencies,
512
+ dependents: existing?.dependents || /* @__PURE__ */ new Set()
513
+ };
514
+ this.skills.set(id, entry);
515
+ this.filePathIndex.set(skill.filePath, id);
516
+ this.updateTriggerIndex(id, entry.metadata.triggers);
517
+ this.updateDependencyGraph(id, dependencies);
518
+ if (existing) {
519
+ this.emit("skill:updated", existing, entry);
520
+ this.publishMessage("skill:updated", { oldSkill: existing, newSkill: entry });
521
+ } else {
522
+ this.emit("skill:registered", entry);
523
+ this.publishMessage("skill:registered", entry);
524
+ }
525
+ return entry;
526
+ }
527
+ /**
528
+ * Unregister a skill by ID
529
+ *
530
+ * @param id - Skill ID
531
+ * @returns True if skill was unregistered
532
+ */
533
+ unregister(id) {
534
+ const entry = this.skills.get(id);
535
+ if (!entry)
536
+ return false;
537
+ if (entry.dependents.size > 0) {
538
+ const dependentList = Array.from(entry.dependents).join(", ");
539
+ throw new Error(`Cannot unregister skill "${id}": depended upon by: ${dependentList}`);
540
+ }
541
+ this.skills.delete(id);
542
+ this.filePathIndex.delete(entry.filePath);
543
+ for (const trigger of entry.metadata.triggers) {
544
+ const skills = this.triggerIndex.get(trigger);
545
+ if (skills) {
546
+ skills.delete(id);
547
+ if (skills.size === 0)
548
+ this.triggerIndex.delete(trigger);
549
+ }
550
+ }
551
+ for (const dep of entry.dependencies) {
552
+ const depEntry = this.skills.get(dep);
553
+ if (depEntry)
554
+ depEntry.dependents.delete(id);
555
+ }
556
+ this.emit("skill:unregistered", entry);
557
+ this.publishMessage("skill:unregistered", entry);
558
+ return true;
559
+ }
560
+ /**
561
+ * Unregister a skill by file path
562
+ *
563
+ * @param filePath - File path
564
+ * @returns True if skill was unregistered
565
+ */
566
+ unregisterByPath(filePath) {
567
+ const id = this.filePathIndex.get(filePath);
568
+ return id ? this.unregister(id) : false;
569
+ }
570
+ /**
571
+ * Get a skill by ID
572
+ *
573
+ * @param id - Skill ID
574
+ * @returns Skill entry or undefined
575
+ */
576
+ getById(id) {
577
+ return this.skills.get(id);
578
+ }
579
+ /**
580
+ * Get a skill by file path
581
+ *
582
+ * @param filePath - File path
583
+ * @returns Skill entry or undefined
584
+ */
585
+ getByPath(filePath) {
586
+ const id = this.filePathIndex.get(filePath);
587
+ return id ? this.skills.get(id) : void 0;
588
+ }
589
+ /**
590
+ * Get skills by trigger
591
+ *
592
+ * @param trigger - Trigger string (e.g., '/commit')
593
+ * @returns Array of matching skills
594
+ */
595
+ getByTrigger(trigger) {
596
+ const ids = this.triggerIndex.get(trigger);
597
+ if (!ids)
598
+ return [];
599
+ return Array.from(ids).map((id) => this.skills.get(id)).filter((e) => e !== void 0 && e.enabled);
600
+ }
601
+ /**
602
+ * Lookup skills with filters
603
+ *
604
+ * @param options - Lookup options
605
+ * @returns Array of matching skills
606
+ */
607
+ lookup(options = {}) {
608
+ let results = Array.from(this.skills.values());
609
+ if (options.enabled !== void 0) {
610
+ results = results.filter((e) => e.enabled === options.enabled);
611
+ }
612
+ if (options.category) {
613
+ results = results.filter((e) => e.metadata.category === options.category);
614
+ }
615
+ if (options.source) {
616
+ results = results.filter((e) => e.source === options.source);
617
+ }
618
+ if (options.userInvocable !== void 0) {
619
+ results = results.filter(
620
+ (e) => (e.metadata.user_invocable ?? true) === options.userInvocable
621
+ );
622
+ }
623
+ if (options.autoActivate !== void 0) {
624
+ results = results.filter(
625
+ (e) => (e.metadata.auto_activate ?? false) === options.autoActivate
626
+ );
627
+ }
628
+ if (options.agent) {
629
+ results = results.filter(
630
+ (e) => e.metadata.agent === options.agent || e.metadata.agents?.includes(options.agent)
631
+ );
632
+ }
633
+ if (options.search) {
634
+ const query = options.search.toLowerCase();
635
+ results = results.filter(
636
+ (e) => e.id.toLowerCase().includes(query) || e.metadata.description.toLowerCase().includes(query) || e.metadata.tags?.some((t) => t.toLowerCase().includes(query))
637
+ );
638
+ }
639
+ if (options.sortBy) {
640
+ const dir = options.sortDir === "desc" ? -1 : 1;
641
+ results.sort((a, b) => {
642
+ switch (options.sortBy) {
643
+ case "name":
644
+ return a.id.localeCompare(b.id) * dir;
645
+ case "priority":
646
+ return ((a.metadata.priority ?? 5) - (b.metadata.priority ?? 5)) * dir;
647
+ case "registeredAt":
648
+ return (a.registeredAt - b.registeredAt) * dir;
649
+ case "modifiedAt":
650
+ return (a.modifiedAt - b.modifiedAt) * dir;
651
+ default:
652
+ return 0;
653
+ }
654
+ });
655
+ }
656
+ if (options.limit) {
657
+ results = results.slice(0, options.limit);
658
+ }
659
+ return results;
660
+ }
661
+ /**
662
+ * Enable a skill
663
+ *
664
+ * @param id - Skill ID
665
+ * @returns True if enabled
666
+ */
667
+ enable(id) {
668
+ const entry = this.skills.get(id);
669
+ if (!entry || entry.enabled)
670
+ return false;
671
+ entry.enabled = true;
672
+ this.emit("skill:enabled", entry);
673
+ this.publishMessage("skill:enabled", entry);
674
+ return true;
675
+ }
676
+ /**
677
+ * Disable a skill
678
+ *
679
+ * @param id - Skill ID
680
+ * @returns True if disabled
681
+ */
682
+ disable(id) {
683
+ const entry = this.skills.get(id);
684
+ if (!entry || !entry.enabled)
685
+ return false;
686
+ entry.enabled = false;
687
+ this.emit("skill:disabled", entry);
688
+ this.publishMessage("skill:disabled", entry);
689
+ return true;
690
+ }
691
+ /**
692
+ * Toggle skill enabled state
693
+ *
694
+ * @param id - Skill ID
695
+ * @returns New enabled state
696
+ */
697
+ toggle(id) {
698
+ const entry = this.skills.get(id);
699
+ if (!entry)
700
+ return false;
701
+ entry.enabled = !entry.enabled;
702
+ const event = entry.enabled ? "skill:enabled" : "skill:disabled";
703
+ this.emit(event, entry);
704
+ this.publishMessage(event, entry);
705
+ return entry.enabled;
706
+ }
707
+ /**
708
+ * Check if a skill exists
709
+ *
710
+ * @param id - Skill ID
711
+ * @returns True if skill exists
712
+ */
713
+ has(id) {
714
+ return this.skills.has(id);
715
+ }
716
+ /**
717
+ * Check if a skill is enabled
718
+ *
719
+ * @param id - Skill ID
720
+ * @returns True if enabled, false if disabled or not found
721
+ */
722
+ isEnabled(id) {
723
+ return this.skills.get(id)?.enabled ?? false;
724
+ }
725
+ /**
726
+ * Get all skill IDs
727
+ *
728
+ * @returns Array of skill IDs
729
+ */
730
+ getIds() {
731
+ return Array.from(this.skills.keys());
732
+ }
733
+ /**
734
+ * Get all entries
735
+ *
736
+ * @returns Array of all entries
737
+ */
738
+ getAll() {
739
+ return Array.from(this.skills.values());
740
+ }
741
+ /**
742
+ * Get enabled entries
743
+ *
744
+ * @returns Array of enabled entries
745
+ */
746
+ getEnabled() {
747
+ return this.lookup({ enabled: true });
748
+ }
749
+ /**
750
+ * Get registry statistics
751
+ *
752
+ * @returns Registry statistics
753
+ */
754
+ getStats() {
755
+ const all = this.getAll();
756
+ const enabled = this.getEnabled();
757
+ const byCategory = {
758
+ dev: 0,
759
+ git: 0,
760
+ review: 0,
761
+ testing: 0,
762
+ docs: 0,
763
+ devops: 0,
764
+ planning: 0,
765
+ debugging: 0,
766
+ custom: 0
767
+ };
768
+ const bySource = { builtin: 0, user: 0, marketplace: 0 };
769
+ let totalTokens = 0;
770
+ let lastRegistered = 0;
771
+ let lastModified = 0;
772
+ for (const entry of all) {
773
+ byCategory[entry.metadata.category]++;
774
+ bySource[entry.source]++;
775
+ totalTokens += entry.estimatedTokens;
776
+ if (entry.registeredAt > lastRegistered)
777
+ lastRegistered = entry.registeredAt;
778
+ if (entry.modifiedAt > lastModified)
779
+ lastModified = entry.modifiedAt;
780
+ }
781
+ return {
782
+ totalSkills: all.length,
783
+ enabledSkills: enabled.length,
784
+ disabledSkills: all.length - enabled.length,
785
+ byCategory,
786
+ bySource,
787
+ totalTokens,
788
+ lastRegistered: lastRegistered > 0 ? this.getById(this.getEntriesSortedBy("registeredAt")[0]?.id || "")?.id : void 0,
789
+ lastModified: lastModified > 0 ? this.getById(this.getEntriesSortedBy("modifiedAt")[0]?.id || "")?.id : void 0
790
+ };
791
+ }
792
+ /**
793
+ * Get dependent skills
794
+ *
795
+ * @param id - Skill ID
796
+ * @returns Array of dependent skill IDs
797
+ */
798
+ getDependents(id) {
799
+ return Array.from(this.skills.get(id)?.dependents || []);
800
+ }
801
+ /**
802
+ * Get skill dependencies
803
+ *
804
+ * @param id - Skill ID
805
+ * @returns Array of dependency IDs
806
+ */
807
+ getDependencies(id) {
808
+ return this.skills.get(id)?.dependencies || [];
809
+ }
810
+ /**
811
+ * Check for missing dependencies
812
+ *
813
+ * @param id - Skill ID
814
+ * @returns Array of missing dependency IDs
815
+ */
816
+ getMissingDependencies(id) {
817
+ const deps = this.getDependencies(id);
818
+ return deps.filter((dep) => !this.has(dep));
819
+ }
820
+ /**
821
+ * Validate all dependencies
822
+ *
823
+ * @returns Map of skill ID to missing dependencies
824
+ */
825
+ validateDependencies() {
826
+ const missing = /* @__PURE__ */ new Map();
827
+ Array.from(this.skills.entries()).forEach(([id, entry]) => {
828
+ const missingDeps = entry.dependencies.filter((dep) => !this.has(dep));
829
+ if (missingDeps.length > 0) {
830
+ missing.set(id, missingDeps);
831
+ }
832
+ });
833
+ return missing;
834
+ }
835
+ /**
836
+ * Clear all skills from registry
837
+ */
838
+ clear() {
839
+ this.skills.clear();
840
+ this.filePathIndex.clear();
841
+ this.triggerIndex.clear();
842
+ this.emit("registry:cleared");
843
+ this.publishMessage("registry:cleared", {});
844
+ }
845
+ /**
846
+ * Get the size of the registry
847
+ *
848
+ * @returns Number of registered skills
849
+ */
850
+ size() {
851
+ return this.skills.size;
852
+ }
853
+ // ==========================================================================
854
+ // Private Methods
855
+ // ==========================================================================
856
+ /**
857
+ * Extract dependencies from skill metadata
858
+ */
859
+ extractDependencies(metadata) {
860
+ const deps = [];
861
+ if (metadata.agents) {
862
+ deps.push(...metadata.agents);
863
+ }
864
+ if (metadata.related_skills) {
865
+ deps.push(...metadata.related_skills);
866
+ }
867
+ return deps;
868
+ }
869
+ /**
870
+ * Update trigger index
871
+ */
872
+ updateTriggerIndex(id, triggers) {
873
+ Array.from(this.triggerIndex.entries()).forEach(([trigger, skillIds]) => {
874
+ skillIds.delete(id);
875
+ if (skillIds.size === 0)
876
+ this.triggerIndex.delete(trigger);
877
+ });
878
+ for (const trigger of triggers) {
879
+ if (!this.triggerIndex.has(trigger)) {
880
+ this.triggerIndex.set(trigger, /* @__PURE__ */ new Set());
881
+ }
882
+ this.triggerIndex.get(trigger).add(id);
883
+ }
884
+ }
885
+ /**
886
+ * Update dependency graph
887
+ */
888
+ updateDependencyGraph(id, dependencies) {
889
+ Array.from(this.skills.entries()).forEach(([_depId, entry]) => {
890
+ if (entry.dependencies.includes(id)) {
891
+ entry.dependents.delete(id);
892
+ }
893
+ });
894
+ for (const dep of dependencies) {
895
+ const depEntry = this.skills.get(dep);
896
+ if (depEntry) {
897
+ depEntry.dependents.add(id);
898
+ }
899
+ }
900
+ }
901
+ /**
902
+ * Estimate token count for a skill
903
+ */
904
+ estimateTokens(skill) {
905
+ const contentTokens = Math.ceil(skill.content.length / 4);
906
+ const metadataTokens = Math.ceil(JSON.stringify(skill.metadata).length / 4);
907
+ return contentTokens + metadataTokens;
908
+ }
909
+ /**
910
+ * Get entries sorted by a field
911
+ */
912
+ getEntriesSortedBy(field) {
913
+ return Array.from(this.skills.values()).sort((a, b) => b[field] - a[field]);
914
+ }
915
+ /**
916
+ * Publish message to event bus
917
+ */
918
+ publishMessage(type, payload) {
919
+ this.messageBus.publish(
920
+ type,
921
+ "coordinator",
922
+ "all",
923
+ `Skill registry event: ${type}`,
924
+ payload,
925
+ { priority: "normal" }
926
+ ).catch(console.error);
927
+ }
928
+ }
929
+ let registryInstance = null;
930
+ function getSkillRegistry() {
931
+ if (!registryInstance) {
932
+ registryInstance = new SkillRegistry();
933
+ }
934
+ return registryInstance;
935
+ }
16
936
 
17
937
  class ProgressTracker extends EventEmitter {
18
938
  config;
@@ -1304,7 +2224,7 @@ const promptUserQuestion = async (question) => {
1304
2224
  return null;
1305
2225
  }
1306
2226
  try {
1307
- const inquirer = (await import('./index3.mjs').then(function (n) { return n.c; })).default;
2227
+ const inquirer = (await import('./index4.mjs').then(function (n) { return n.c; })).default;
1308
2228
  const choices = question.options.map((option) => ({
1309
2229
  name: option.description ? `${option.label} \u2014 ${option.description}` : option.label,
1310
2230
  value: option.value
@@ -1879,6 +2799,11 @@ class AutoExecutor extends EventEmitter {
1879
2799
  const executionId = `exec-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
1880
2800
  const startedAt = Date.now();
1881
2801
  this.emit("execution:started", { input: userInput });
2802
+ this.emitCommandHook("command-start", {
2803
+ executionId,
2804
+ inputLength: userInput.length,
2805
+ source: "auto-executor"
2806
+ });
1882
2807
  this.config.telemetry.record({
1883
2808
  executionId,
1884
2809
  phase: "execution",
@@ -1904,6 +2829,13 @@ class AutoExecutor extends EventEmitter {
1904
2829
  complexity: routeResult.intent.complexity
1905
2830
  }
1906
2831
  });
2832
+ this.emitCommandHook("command-telemetry", {
2833
+ executionId,
2834
+ phase: "intent",
2835
+ action: "route",
2836
+ route: routeResult.route,
2837
+ confidence: routeResult.intent.confidence
2838
+ });
1907
2839
  const elicitationResult = await this.resolveRouteWithElicitation(
1908
2840
  routeResult.route,
1909
2841
  routeResult.intent,
@@ -2039,6 +2971,12 @@ class AutoExecutor extends EventEmitter {
2039
2971
  complexity: intent.complexity
2040
2972
  }
2041
2973
  });
2974
+ this.emitCommandHook("command-telemetry", {
2975
+ executionId,
2976
+ phase: "route",
2977
+ action: route,
2978
+ durationMs: routeDuration
2979
+ });
2042
2980
  const totalDuration = Date.now() - startedAt;
2043
2981
  this.metricsCollector.recordResponseTime("auto-executor", totalDuration);
2044
2982
  this.metricsCollector.recordTaskCompletion("auto-executor", true, totalDuration);
@@ -2055,6 +2993,13 @@ class AutoExecutor extends EventEmitter {
2055
2993
  mcpToolsUsed: mcpToolsUsed.length
2056
2994
  }
2057
2995
  });
2996
+ this.emitCommandHook("command-complete", {
2997
+ executionId,
2998
+ success: true,
2999
+ route,
3000
+ durationMs: totalDuration,
3001
+ mcpToolsUsed: mcpToolsUsed.length
3002
+ });
2058
3003
  result.insights = this.buildExecutionInsights({
2059
3004
  initialRoute: routeResult.route,
2060
3005
  resolvedRoute: route,
@@ -2082,6 +3027,12 @@ class AutoExecutor extends EventEmitter {
2082
3027
  error: errorMessage
2083
3028
  }
2084
3029
  });
3030
+ this.emitCommandHook("command-complete", {
3031
+ executionId,
3032
+ success: false,
3033
+ durationMs: totalDuration,
3034
+ error: errorMessage
3035
+ });
2085
3036
  this.emit("execution:failed", { error, input: userInput });
2086
3037
  throw error;
2087
3038
  }
@@ -2552,6 +3503,9 @@ class AutoExecutor extends EventEmitter {
2552
3503
  getTelemetryEvents(limit = 50) {
2553
3504
  return this.config.telemetry.getRecent(limit);
2554
3505
  }
3506
+ clearTelemetry() {
3507
+ this.config.telemetry.clear();
3508
+ }
2555
3509
  getErrorMessage(error) {
2556
3510
  if (error instanceof Error) {
2557
3511
  return error.message;
@@ -2566,6 +3520,9 @@ class AutoExecutor extends EventEmitter {
2566
3520
  console.log(`[AutoExecutor] ${message}`);
2567
3521
  }
2568
3522
  }
3523
+ emitCommandHook(event, data) {
3524
+ void emitCommandHookEvent(event, data);
3525
+ }
2569
3526
  }
2570
3527
  let globalExecutor = null;
2571
3528
  function getGlobalAutoExecutor(config) {
@@ -2674,6 +3631,7 @@ class CliInterceptor extends EventEmitter {
2674
3631
  autoExecute: config.autoExecute !== void 0 ? config.autoExecute : true,
2675
3632
  showIntent: config.showIntent !== void 0 ? config.showIntent : true,
2676
3633
  bypassKeywords: config.bypassKeywords || [],
3634
+ ccjkOwnedSlashPrefixes: config.ccjkOwnedSlashPrefixes || ["/ccjk", "/ccjk:", "/plugin", "/plugins", "/skill"],
2677
3635
  verbose: config.verbose !== void 0 ? config.verbose : false
2678
3636
  };
2679
3637
  }
@@ -2690,6 +3648,7 @@ class CliInterceptor extends EventEmitter {
2690
3648
  this.emit("intercept:started", { input: userInput });
2691
3649
  const bypassCheck = this.shouldBypass(userInput);
2692
3650
  if (bypassCheck.bypass) {
3651
+ await this.handleBypassedCommand(userInput, bypassCheck.reason);
2693
3652
  this.emit("intercept:bypassed", { input: userInput, reason: bypassCheck.reason });
2694
3653
  return {
2695
3654
  intercepted: false,
@@ -2720,6 +3679,12 @@ class CliInterceptor extends EventEmitter {
2720
3679
  */
2721
3680
  shouldBypass(input) {
2722
3681
  const normalized = input.trim().toLowerCase();
3682
+ if (normalized.startsWith("/")) {
3683
+ const isCcjkOwned = this.config.ccjkOwnedSlashPrefixes.some((prefix) => normalized.startsWith(prefix));
3684
+ if (!isCcjkOwned) {
3685
+ return { bypass: true, reason: "Native slash command passthrough" };
3686
+ }
3687
+ }
2723
3688
  if (this.systemCommands.some((cmd) => normalized.startsWith(cmd))) {
2724
3689
  return { bypass: true, reason: "System command" };
2725
3690
  }
@@ -2742,6 +3707,31 @@ class CliInterceptor extends EventEmitter {
2742
3707
  console.log(" System will automatically handle: skills, agents, MCP tools\n");
2743
3708
  console.log(" Smart mode: ambiguity checks + capability-ranked tool selection + telemetry\n");
2744
3709
  }
3710
+ async handleBypassedCommand(input, reason) {
3711
+ const normalized = input.trim().toLowerCase();
3712
+ const command = this.extractCommandName(normalized);
3713
+ if (normalized.startsWith("/clear")) {
3714
+ this.autoExecutor.clearTelemetry();
3715
+ contextLoader.clearCache();
3716
+ getSkillRegistry().clear();
3717
+ await emitCommandHookEvent("command-clear", {
3718
+ command,
3719
+ cleared: ["telemetry", "context-cache", "skill-registry"]
3720
+ });
3721
+ }
3722
+ if (normalized.startsWith("/")) {
3723
+ await emitCommandHookEvent("command-bypass", {
3724
+ command,
3725
+ reason
3726
+ });
3727
+ }
3728
+ }
3729
+ extractCommandName(input) {
3730
+ if (!input.startsWith("/")) {
3731
+ return "";
3732
+ }
3733
+ return input.split(/\s+/)[0];
3734
+ }
2745
3735
  /**
2746
3736
  * Enable interceptor
2747
3737
  */
@@ -2885,9 +3875,9 @@ class BrainCliHook extends EventEmitter {
2885
3875
  if (this.initialized) {
2886
3876
  return;
2887
3877
  }
2888
- const { getGlobalStateManager } = await import('./convoy-manager.mjs').then(function (n) { return n.b; });
3878
+ const { getGlobalStateManager } = await import('./convoy-manager.mjs').then(function (n) { return n.d; });
2889
3879
  const { getGlobalMailboxManager } = await Promise.resolve().then(function () { return persistentMailbox; });
2890
- const { getGlobalConvoyManager } = await import('./convoy-manager.mjs').then(function (n) { return n.c; });
3880
+ const { getGlobalConvoyManager } = await import('./convoy-manager.mjs').then(function (n) { return n.e; });
2891
3881
  const stateManager = getGlobalStateManager();
2892
3882
  const mailboxManager = getGlobalMailboxManager();
2893
3883
  const convoyManager = getGlobalConvoyManager();
@@ -3042,7 +4032,7 @@ ${"=".repeat(60)}`);
3042
4032
  */
3043
4033
  async buildAdditionalContext() {
3044
4034
  try {
3045
- const { loadContextAtDepth } = await import('./context-loader.mjs');
4035
+ const { loadContextAtDepth } = await import('./convoy-manager.mjs').then(function (n) { return n.b; });
3046
4036
  const ctx = await loadContextAtDepth("L0");
3047
4037
  if (ctx.totalTokens > 0) {
3048
4038
  return `[Brain Context: ${ctx.layers.size} layers, ~${ctx.totalTokens} tokens, depth=${ctx.depth}]`;