@cleocode/core 2026.3.43 → 2026.3.45

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 (183) hide show
  1. package/dist/admin/export-tasks.d.ts.map +1 -1
  2. package/dist/admin/import-tasks.d.ts +10 -2
  3. package/dist/admin/import-tasks.d.ts.map +1 -1
  4. package/dist/agents/agent-schema.d.ts +358 -0
  5. package/dist/agents/agent-schema.d.ts.map +1 -0
  6. package/dist/agents/capacity.d.ts +57 -0
  7. package/dist/agents/capacity.d.ts.map +1 -0
  8. package/dist/agents/index.d.ts +17 -0
  9. package/dist/agents/index.d.ts.map +1 -0
  10. package/dist/agents/registry.d.ts +115 -0
  11. package/dist/agents/registry.d.ts.map +1 -0
  12. package/dist/agents/retry.d.ts +83 -0
  13. package/dist/agents/retry.d.ts.map +1 -0
  14. package/dist/hooks/index.d.ts +4 -1
  15. package/dist/hooks/index.d.ts.map +1 -1
  16. package/dist/hooks/payload-schemas.d.ts +214 -0
  17. package/dist/hooks/payload-schemas.d.ts.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +16937 -2371
  21. package/dist/index.js.map +4 -4
  22. package/dist/inject/index.d.ts.map +1 -1
  23. package/dist/intelligence/impact.d.ts +51 -0
  24. package/dist/intelligence/impact.d.ts.map +1 -0
  25. package/dist/intelligence/index.d.ts +15 -0
  26. package/dist/intelligence/index.d.ts.map +1 -0
  27. package/dist/intelligence/patterns.d.ts +66 -0
  28. package/dist/intelligence/patterns.d.ts.map +1 -0
  29. package/dist/intelligence/prediction.d.ts +51 -0
  30. package/dist/intelligence/prediction.d.ts.map +1 -0
  31. package/dist/intelligence/types.d.ts +221 -0
  32. package/dist/intelligence/types.d.ts.map +1 -0
  33. package/dist/internal.d.ts +12 -1
  34. package/dist/internal.d.ts.map +1 -1
  35. package/dist/issue/template-parser.d.ts +8 -2
  36. package/dist/issue/template-parser.d.ts.map +1 -1
  37. package/dist/lifecycle/pipeline.d.ts +2 -2
  38. package/dist/lifecycle/pipeline.d.ts.map +1 -1
  39. package/dist/lifecycle/state-machine.d.ts +1 -1
  40. package/dist/lifecycle/state-machine.d.ts.map +1 -1
  41. package/dist/memory/brain-lifecycle.d.ts.map +1 -1
  42. package/dist/memory/brain-retrieval.d.ts.map +1 -1
  43. package/dist/memory/brain-row-types.d.ts +40 -6
  44. package/dist/memory/brain-row-types.d.ts.map +1 -1
  45. package/dist/memory/brain-search.d.ts.map +1 -1
  46. package/dist/memory/brain-similarity.d.ts.map +1 -1
  47. package/dist/memory/claude-mem-migration.d.ts.map +1 -1
  48. package/dist/nexus/discover.d.ts.map +1 -1
  49. package/dist/nexus/index.d.ts +2 -0
  50. package/dist/nexus/index.d.ts.map +1 -1
  51. package/dist/nexus/transfer-types.d.ts +123 -0
  52. package/dist/nexus/transfer-types.d.ts.map +1 -0
  53. package/dist/nexus/transfer.d.ts +31 -0
  54. package/dist/nexus/transfer.d.ts.map +1 -0
  55. package/dist/orchestration/bootstrap.d.ts.map +1 -1
  56. package/dist/orchestration/skill-ops.d.ts +4 -4
  57. package/dist/orchestration/skill-ops.d.ts.map +1 -1
  58. package/dist/otel/index.d.ts +1 -1
  59. package/dist/otel/index.d.ts.map +1 -1
  60. package/dist/sessions/briefing.d.ts.map +1 -1
  61. package/dist/sessions/handoff.d.ts.map +1 -1
  62. package/dist/sessions/index.d.ts +1 -1
  63. package/dist/sessions/index.d.ts.map +1 -1
  64. package/dist/sessions/types.d.ts +8 -42
  65. package/dist/sessions/types.d.ts.map +1 -1
  66. package/dist/signaldock/signaldock-transport.d.ts +1 -1
  67. package/dist/signaldock/signaldock-transport.d.ts.map +1 -1
  68. package/dist/skills/injection/subagent.d.ts +3 -3
  69. package/dist/skills/injection/subagent.d.ts.map +1 -1
  70. package/dist/skills/manifests/contribution.d.ts +2 -2
  71. package/dist/skills/manifests/contribution.d.ts.map +1 -1
  72. package/dist/skills/orchestrator/spawn.d.ts +6 -6
  73. package/dist/skills/orchestrator/spawn.d.ts.map +1 -1
  74. package/dist/skills/orchestrator/startup.d.ts +1 -1
  75. package/dist/skills/orchestrator/startup.d.ts.map +1 -1
  76. package/dist/skills/orchestrator/validator.d.ts +2 -2
  77. package/dist/skills/orchestrator/validator.d.ts.map +1 -1
  78. package/dist/skills/precedence-types.d.ts +24 -1
  79. package/dist/skills/precedence-types.d.ts.map +1 -1
  80. package/dist/skills/types.d.ts +70 -4
  81. package/dist/skills/types.d.ts.map +1 -1
  82. package/dist/store/brain-sqlite.d.ts +4 -1
  83. package/dist/store/brain-sqlite.d.ts.map +1 -1
  84. package/dist/store/export.d.ts +5 -4
  85. package/dist/store/export.d.ts.map +1 -1
  86. package/dist/store/nexus-sqlite.d.ts +4 -1
  87. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  88. package/dist/store/sqlite.d.ts +4 -1
  89. package/dist/store/sqlite.d.ts.map +1 -1
  90. package/dist/store/tasks-schema.d.ts +14 -4
  91. package/dist/store/tasks-schema.d.ts.map +1 -1
  92. package/dist/store/typed-query.d.ts +12 -0
  93. package/dist/store/typed-query.d.ts.map +1 -0
  94. package/dist/store/validation-schemas.d.ts +2423 -50
  95. package/dist/store/validation-schemas.d.ts.map +1 -1
  96. package/dist/system/inject-generate.d.ts.map +1 -1
  97. package/dist/validation/doctor/checks.d.ts +5 -0
  98. package/dist/validation/doctor/checks.d.ts.map +1 -1
  99. package/dist/validation/engine.d.ts +10 -10
  100. package/dist/validation/engine.d.ts.map +1 -1
  101. package/dist/validation/index.d.ts +6 -2
  102. package/dist/validation/index.d.ts.map +1 -1
  103. package/dist/validation/protocol-common.d.ts +10 -2
  104. package/dist/validation/protocol-common.d.ts.map +1 -1
  105. package/migrations/drizzle-tasks/20260320013731_wave0-schema-hardening/migration.sql +84 -0
  106. package/migrations/drizzle-tasks/20260320013731_wave0-schema-hardening/snapshot.json +4060 -0
  107. package/migrations/drizzle-tasks/20260320020000_agent-dimension/migration.sql +35 -0
  108. package/migrations/drizzle-tasks/20260320020000_agent-dimension/snapshot.json +4312 -0
  109. package/package.json +2 -2
  110. package/src/admin/export-tasks.ts +2 -5
  111. package/src/admin/import-tasks.ts +53 -29
  112. package/src/agents/__tests__/capacity.test.ts +219 -0
  113. package/src/agents/__tests__/registry.test.ts +457 -0
  114. package/src/agents/__tests__/retry.test.ts +289 -0
  115. package/src/agents/agent-schema.ts +107 -0
  116. package/src/agents/capacity.ts +151 -0
  117. package/src/agents/index.ts +68 -0
  118. package/src/agents/registry.ts +449 -0
  119. package/src/agents/retry.ts +255 -0
  120. package/src/hooks/index.ts +20 -1
  121. package/src/hooks/payload-schemas.ts +199 -0
  122. package/src/index.ts +69 -0
  123. package/src/inject/index.ts +14 -14
  124. package/src/intelligence/__tests__/impact.test.ts +453 -0
  125. package/src/intelligence/__tests__/patterns.test.ts +450 -0
  126. package/src/intelligence/__tests__/prediction.test.ts +418 -0
  127. package/src/intelligence/impact.ts +638 -0
  128. package/src/intelligence/index.ts +47 -0
  129. package/src/intelligence/patterns.ts +621 -0
  130. package/src/intelligence/prediction.ts +621 -0
  131. package/src/intelligence/types.ts +273 -0
  132. package/src/internal.ts +89 -2
  133. package/src/issue/template-parser.ts +65 -4
  134. package/src/lifecycle/pipeline.ts +14 -7
  135. package/src/lifecycle/state-machine.ts +6 -2
  136. package/src/memory/brain-lifecycle.ts +5 -11
  137. package/src/memory/brain-retrieval.ts +44 -38
  138. package/src/memory/brain-row-types.ts +43 -6
  139. package/src/memory/brain-search.ts +53 -32
  140. package/src/memory/brain-similarity.ts +9 -8
  141. package/src/memory/claude-mem-migration.ts +4 -3
  142. package/src/nexus/__tests__/nexus-e2e.test.ts +1481 -0
  143. package/src/nexus/__tests__/transfer.test.ts +446 -0
  144. package/src/nexus/discover.ts +1 -0
  145. package/src/nexus/index.ts +14 -0
  146. package/src/nexus/transfer-types.ts +129 -0
  147. package/src/nexus/transfer.ts +314 -0
  148. package/src/orchestration/bootstrap.ts +11 -17
  149. package/src/orchestration/skill-ops.ts +52 -32
  150. package/src/otel/index.ts +48 -4
  151. package/src/sessions/__tests__/briefing.test.ts +31 -2
  152. package/src/sessions/briefing.ts +27 -42
  153. package/src/sessions/handoff.ts +52 -86
  154. package/src/sessions/index.ts +5 -1
  155. package/src/sessions/types.ts +9 -43
  156. package/src/signaldock/signaldock-transport.ts +5 -2
  157. package/src/skills/injection/subagent.ts +10 -16
  158. package/src/skills/manifests/contribution.ts +5 -13
  159. package/src/skills/orchestrator/__tests__/spawn-tier.test.ts +44 -30
  160. package/src/skills/orchestrator/spawn.ts +18 -31
  161. package/src/skills/orchestrator/startup.ts +78 -65
  162. package/src/skills/orchestrator/validator.ts +26 -31
  163. package/src/skills/precedence-types.ts +24 -1
  164. package/src/skills/types.ts +72 -5
  165. package/src/store/__tests__/test-db-helper.d.ts +4 -4
  166. package/src/store/__tests__/test-db-helper.js +5 -16
  167. package/src/store/__tests__/test-db-helper.ts +5 -18
  168. package/src/store/brain-sqlite.ts +7 -3
  169. package/src/store/chain-schema.ts +1 -1
  170. package/src/store/export.ts +22 -12
  171. package/src/store/nexus-sqlite.ts +7 -3
  172. package/src/store/sqlite.ts +9 -3
  173. package/src/store/tasks-schema.ts +65 -8
  174. package/src/store/typed-query.ts +17 -0
  175. package/src/store/validation-schemas.ts +347 -23
  176. package/src/system/inject-generate.ts +9 -23
  177. package/src/validation/doctor/checks.ts +24 -2
  178. package/src/validation/engine.ts +11 -11
  179. package/src/validation/index.ts +131 -3
  180. package/src/validation/protocol-common.ts +54 -3
  181. package/dist/tasks/reparent.d.ts +0 -38
  182. package/dist/tasks/reparent.d.ts.map +0 -1
  183. package/src/tasks/reparent.ts +0 -134
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Type definitions for the CLEO Intelligence dimension.
3
+ *
4
+ * Covers quality prediction (risk scoring, validation outcome prediction),
5
+ * pattern extraction (automatic detection, matching, storage), and
6
+ * impact analysis (blast radius, change prediction).
7
+ *
8
+ * @task Wave3A
9
+ * @epic T5149
10
+ * @module intelligence
11
+ */
12
+
13
+ import type { BrainLearningRow, BrainPatternRow } from '../store/brain-schema.js';
14
+
15
+ // ============================================================================
16
+ // Risk Scoring Types
17
+ // ============================================================================
18
+
19
+ /**
20
+ * A single factor contributing to a task's overall risk score.
21
+ *
22
+ * Each factor has a weight (how much it matters) and a value (current level, 0-1).
23
+ * The weighted sum of all factors produces the aggregate risk score.
24
+ */
25
+ export interface RiskFactor {
26
+ /** Human-readable factor name (e.g., "complexity", "blocking_risk"). */
27
+ name: string;
28
+ /** How much this factor contributes to the total score (0-1). */
29
+ weight: number;
30
+ /** Current measured value for this factor (0-1, where 1 = highest risk). */
31
+ value: number;
32
+ /** Explanation of why this factor has its current value. */
33
+ description: string;
34
+ }
35
+
36
+ /**
37
+ * Complete risk assessment for a single task.
38
+ *
39
+ * Returned by {@link calculateTaskRisk}. The `riskScore` is the weighted
40
+ * aggregate of all {@link RiskFactor} entries in `factors`.
41
+ */
42
+ export interface RiskAssessment {
43
+ /** The task ID this assessment applies to. */
44
+ taskId: string;
45
+ /** Aggregate risk score (0-1, where 1 = highest risk). */
46
+ riskScore: number;
47
+ /** Confidence in the assessment (0-1). Higher when more data is available. */
48
+ confidence: number;
49
+ /** Individual risk factors that contributed to the score. */
50
+ factors: RiskFactor[];
51
+ /** Human-readable recommendation based on the risk level. */
52
+ recommendation: string;
53
+ }
54
+
55
+ /**
56
+ * Predicted outcome for a lifecycle validation gate.
57
+ *
58
+ * Returned by {@link predictValidationOutcome}. Combines historical
59
+ * pattern data with the task's current state to estimate pass likelihood.
60
+ */
61
+ export interface ValidationPrediction {
62
+ /** The task ID being evaluated. */
63
+ taskId: string;
64
+ /** The lifecycle stage being predicted (e.g., "specification", "implementation"). */
65
+ stage: string;
66
+ /** Probability of passing the gate (0-1). */
67
+ passLikelihood: number;
68
+ /** Known blockers that may prevent passing. */
69
+ blockers: string[];
70
+ /** Actionable suggestions to improve pass likelihood. */
71
+ suggestions: string[];
72
+ }
73
+
74
+ // ============================================================================
75
+ // Pattern Extraction Types
76
+ // ============================================================================
77
+
78
+ /**
79
+ * A pattern automatically detected from historical brain/task data.
80
+ *
81
+ * Detected patterns may be stored in the existing brain_patterns table
82
+ * if they meet frequency and confidence thresholds.
83
+ */
84
+ export interface DetectedPattern {
85
+ /** Pattern type classification. */
86
+ type: 'workflow' | 'blocker' | 'success' | 'failure' | 'optimization';
87
+ /** Human-readable pattern description. */
88
+ pattern: string;
89
+ /** Context in which the pattern was observed. */
90
+ context: string;
91
+ /** How many times this pattern was observed. */
92
+ frequency: number;
93
+ /** Success rate when this pattern appears (0-1, null if unknown). */
94
+ successRate: number | null;
95
+ /** Estimated impact level. */
96
+ impact: 'low' | 'medium' | 'high';
97
+ /** If this is an anti-pattern, describe the negative behavior. */
98
+ antiPattern: string | null;
99
+ /** Recommended mitigation for anti-patterns. */
100
+ mitigation: string | null;
101
+ /** Example task IDs or descriptions where this pattern occurred. */
102
+ examples: string[];
103
+ /** Confidence in this pattern's validity (0-1). */
104
+ confidence: number;
105
+ }
106
+
107
+ /**
108
+ * Result of matching a task against known patterns from brain_patterns.
109
+ *
110
+ * Includes the original pattern row and a relevance score indicating
111
+ * how strongly the pattern applies to the target task.
112
+ */
113
+ export interface PatternMatch {
114
+ /** The matched brain_patterns row. */
115
+ pattern: BrainPatternRow;
116
+ /** How relevant this pattern is to the target task (0-1). */
117
+ relevanceScore: number;
118
+ /** Why this pattern was matched. */
119
+ matchReason: string;
120
+ /** Whether this is an anti-pattern match (warns about potential issues). */
121
+ isAntiPattern: boolean;
122
+ }
123
+
124
+ /**
125
+ * Options for pattern extraction from historical data.
126
+ */
127
+ export interface PatternExtractionOptions {
128
+ /** Minimum number of occurrences to consider something a pattern. Default: 2. */
129
+ minFrequency?: number;
130
+ /** Minimum confidence threshold (0-1). Default: 0.3. */
131
+ minConfidence?: number;
132
+ /** Maximum number of patterns to return. Default: 50. */
133
+ limit?: number;
134
+ /** Filter by pattern type. */
135
+ type?: DetectedPattern['type'];
136
+ }
137
+
138
+ /**
139
+ * Result of updating pattern statistics after an outcome.
140
+ */
141
+ export interface PatternStatsUpdate {
142
+ /** The pattern ID that was updated. */
143
+ patternId: string;
144
+ /** New frequency value. */
145
+ newFrequency: number;
146
+ /** New success rate (0-1). */
147
+ newSuccessRate: number | null;
148
+ /** Whether the outcome was successful. */
149
+ outcomeSuccess: boolean;
150
+ }
151
+
152
+ /**
153
+ * Summary of applicable learnings for a task, used in prediction.
154
+ */
155
+ export interface LearningContext {
156
+ /** Learnings that apply to this task's context. */
157
+ applicable: BrainLearningRow[];
158
+ /** Average confidence of applicable learnings. */
159
+ averageConfidence: number;
160
+ /** Count of actionable learnings. */
161
+ actionableCount: number;
162
+ }
163
+
164
+ // ============================================================================
165
+ // Impact Assessment
166
+ // ============================================================================
167
+
168
+ /**
169
+ * Full impact assessment for a task within its dependency graph.
170
+ *
171
+ * Captures direct dependents, transitive dependents, lifecycle pipeline
172
+ * effects, blocked work counts, and critical path membership.
173
+ */
174
+ export interface ImpactAssessment {
175
+ /** The task being assessed. */
176
+ taskId: string;
177
+
178
+ /** Tasks that directly depend on this task. */
179
+ directDependents: string[];
180
+
181
+ /** All downstream tasks (direct + transitive). */
182
+ transitiveDependents: string[];
183
+
184
+ /** Epic IDs whose lifecycle pipelines are affected. */
185
+ affectedPipelines: string[];
186
+
187
+ /** Count of tasks that would be blocked if this task is not completed. */
188
+ blockedWorkCount: number;
189
+
190
+ /** Whether this task lies on the project's critical path. */
191
+ isOnCriticalPath: boolean;
192
+
193
+ /** Quantified scope of the impact. */
194
+ blastRadius: BlastRadius;
195
+ }
196
+
197
+ // ============================================================================
198
+ // Change Impact
199
+ // ============================================================================
200
+
201
+ /** The type of change being analyzed. */
202
+ export type ChangeType = 'cancel' | 'block' | 'complete' | 'reprioritize';
203
+
204
+ /**
205
+ * Predicted downstream effects of a specific change to a task.
206
+ *
207
+ * Models what happens when a task is cancelled, blocked, completed,
208
+ * or reprioritized -- including cascading status changes and
209
+ * recommendations.
210
+ */
211
+ export interface ChangeImpact {
212
+ /** The task being changed. */
213
+ taskId: string;
214
+
215
+ /** The type of change being analyzed. */
216
+ changeType: ChangeType;
217
+
218
+ /** Tasks affected by this change, with predicted new status. */
219
+ affectedTasks: AffectedTask[];
220
+
221
+ /** Maximum depth of cascading effects in the dependency graph. */
222
+ cascadeDepth: number;
223
+
224
+ /** Human-readable recommendation based on the analysis. */
225
+ recommendation: string;
226
+ }
227
+
228
+ /**
229
+ * A single task affected by a change, with its predicted new state.
230
+ */
231
+ export interface AffectedTask {
232
+ /** Task ID. */
233
+ id: string;
234
+
235
+ /** Task title. */
236
+ title: string;
237
+
238
+ /** Current status before the change. */
239
+ currentStatus: string;
240
+
241
+ /** Predicted new status after the change (if it would change). */
242
+ newStatus?: string;
243
+
244
+ /** Why this task is affected. */
245
+ reason: string;
246
+ }
247
+
248
+ // ============================================================================
249
+ // Blast Radius
250
+ // ============================================================================
251
+
252
+ /** Severity classification for blast radius. */
253
+ export type BlastRadiusSeverity = 'isolated' | 'moderate' | 'widespread' | 'critical';
254
+
255
+ /**
256
+ * Quantified scope of a task's impact across the project.
257
+ */
258
+ export interface BlastRadius {
259
+ /** Number of direct dependents. */
260
+ directCount: number;
261
+
262
+ /** Number of transitive dependents (full downstream tree). */
263
+ transitiveCount: number;
264
+
265
+ /** Number of distinct epics affected. */
266
+ epicCount: number;
267
+
268
+ /** Percentage of the total project impacted (0-100). */
269
+ projectPercentage: number;
270
+
271
+ /** Classification of impact severity. */
272
+ severity: BlastRadiusSeverity;
273
+ }
package/src/internal.ts CHANGED
@@ -27,7 +27,7 @@ export { exportTasksPackage } from './admin/export-tasks.js';
27
27
  // Admin
28
28
  export { computeHelp } from './admin/help.js';
29
29
  export { importTasks } from './admin/import.js';
30
- export { importTasksPackage } from './admin/import-tasks.js';
30
+ export { importFromPackage, importTasksPackage } from './admin/import-tasks.js';
31
31
  // ADRs
32
32
  export { findAdrs } from './adrs/find.js';
33
33
  export { listAdrs, showAdr, syncAdrsToDb, validateAllAdrs } from './adrs/index.js';
@@ -51,12 +51,47 @@ export type {
51
51
  ViolationSeverity,
52
52
  } from './compliance/protocol-rules.js';
53
53
  export { PROTOCOL_RULES } from './compliance/protocol-rules.js';
54
+ export type { PayloadValidationResult } from './hooks/payload-schemas.js';
55
+ export { validatePayload } from './hooks/payload-schemas.js';
54
56
  // Hooks
55
57
  export type { HookEvent, ProviderHookEvent } from './hooks/provider-hooks.js';
56
58
  export { isProviderHookEvent } from './hooks/types.js';
57
59
 
58
60
  // Init (additional)
59
61
  export { isAutoInitEnabled } from './init.js';
62
+ export {
63
+ analyzeChangeImpact,
64
+ analyzeTaskImpact,
65
+ calculateBlastRadius,
66
+ } from './intelligence/impact.js';
67
+ export {
68
+ extractPatternsFromHistory,
69
+ matchPatterns,
70
+ storeDetectedPattern,
71
+ updatePatternStats,
72
+ } from './intelligence/patterns.js';
73
+ export {
74
+ calculateTaskRisk,
75
+ gatherLearningContext,
76
+ predictValidationOutcome,
77
+ } from './intelligence/prediction.js';
78
+ // Intelligence — quality prediction and pattern extraction
79
+ export type {
80
+ AffectedTask,
81
+ BlastRadius,
82
+ BlastRadiusSeverity,
83
+ ChangeImpact,
84
+ ChangeType,
85
+ DetectedPattern,
86
+ ImpactAssessment,
87
+ LearningContext,
88
+ PatternExtractionOptions,
89
+ PatternMatch,
90
+ PatternStatsUpdate,
91
+ RiskAssessment,
92
+ RiskFactor,
93
+ ValidationPrediction,
94
+ } from './intelligence/types.js';
60
95
 
61
96
  // Issue
62
97
  export { collectDiagnostics } from './issue/diagnostics.js';
@@ -563,6 +598,41 @@ export { coreTaskStats } from './tasks/task-ops.js';
563
598
  // Additional flat exports (required by @cleocode/cleo)
564
599
  // ---------------------------------------------------------------------------
565
600
 
601
+ export type {
602
+ AgentHealthReport,
603
+ AgentRecoveryResult,
604
+ CapacitySummary,
605
+ ListAgentFilters,
606
+ RegisterAgentOptions,
607
+ RetryPolicy,
608
+ RetryResult,
609
+ UpdateStatusOptions,
610
+ } from './agents/index.js';
611
+ // Agents — runtime registry, health, retry, capacity
612
+ export {
613
+ checkAgentHealth,
614
+ classifyError,
615
+ createRetryPolicy,
616
+ DEFAULT_RETRY_POLICY,
617
+ deregisterAgent,
618
+ findLeastLoadedAgent,
619
+ generateAgentId,
620
+ getAgentErrorHistory,
621
+ getAgentInstance,
622
+ getAvailableCapacity,
623
+ getCapacitySummary,
624
+ getHealthReport,
625
+ heartbeat,
626
+ incrementTasksCompleted,
627
+ isOverloaded,
628
+ listAgentInstances,
629
+ markCrashed,
630
+ recoverCrashedAgents,
631
+ registerAgent as registerAgentInstance,
632
+ updateAgentStatus,
633
+ updateCapacity,
634
+ withRetry,
635
+ } from './agents/index.js';
566
636
  // Codebase map (additional)
567
637
  export { mapCodebase } from './codebase-map/index.js';
568
638
  // Compliance (additional)
@@ -574,6 +644,18 @@ export type { BuildConfig } from './config/build-config.js';
574
644
  export { BUILD_CONFIG } from './config/build-config.js';
575
645
  // Init (additional)
576
646
  export { initCoreSkills } from './init.js';
647
+ // Memory — brain row types
648
+ export type {
649
+ BrainAnchor,
650
+ BrainConsolidationObservationRow,
651
+ BrainDecisionNode,
652
+ BrainFtsRow,
653
+ BrainIdCheckRow,
654
+ BrainKnnRow,
655
+ BrainNarrativeRow,
656
+ BrainSearchHit,
657
+ BrainTimelineNeighborRow,
658
+ } from './memory/brain-row-types.js';
577
659
  // Memory (additional)
578
660
  export { writeMemoryBridge } from './memory/memory-bridge.js';
579
661
  export type { SessionMemoryContext } from './memory/session-memory.js';
@@ -586,6 +668,12 @@ export {
586
668
  } from './nexus/discover.js';
587
669
  // Nexus — readRegistry (exported as nexusReadRegistry to avoid name clash with skills readRegistry)
588
670
  export { readRegistry as nexusReadRegistry } from './nexus/registry.js';
671
+ // Nexus — transfer
672
+ export { executeTransfer, previewTransfer } from './nexus/transfer.js';
673
+ export type {
674
+ TransferParams,
675
+ TransferResult,
676
+ } from './nexus/transfer-types.js';
589
677
  export type { DependencyAnalysis } from './orchestration/analyze.js';
590
678
  export { analyzeDependencies as orchestrationAnalyzeDependencies } from './orchestration/analyze.js';
591
679
  export { getCriticalPath as orchestrationGetCriticalPath } from './orchestration/critical-path.js';
@@ -620,7 +708,6 @@ export { listLabels, showLabelTasks } from './tasks/labels.js';
620
708
  // Tasks — plan, labels, suggests
621
709
  export { coreTaskPlan } from './tasks/plan.js';
622
710
  export { suggestRelated } from './tasks/relates.js';
623
-
624
711
  // Verification gates — enums/classes
625
712
  export { GateStatus, VerificationGate } from './validation/operation-verification-gates.js';
626
713
 
@@ -227,12 +227,73 @@ export function cacheTemplates(templates: IssueTemplate[], cwd?: string): void {
227
227
  }
228
228
 
229
229
  /**
230
- * Validate that required labels exist (informational).
230
+ * Validate that labels referenced in issue templates are consistent.
231
+ *
232
+ * Collects all labels used across templates and checks that each label
233
+ * appears in at least one template definition. Reports any labels that
234
+ * are referenced by only one template but not defined as a known label
235
+ * across the template set. This catches typos and orphaned labels
236
+ * without requiring GitHub API access.
231
237
  */
232
- export function validateLabelsExist(_templates: IssueTemplate[]): {
238
+ export function validateLabelsExist(templates: IssueTemplate[]): {
233
239
  valid: boolean;
234
240
  missingLabels: string[];
235
241
  } {
236
- // Can't actually verify GitHub labels without API, just return the set
237
- return { valid: true, missingLabels: [] };
242
+ if (templates.length === 0) {
243
+ return { valid: true, missingLabels: [] };
244
+ }
245
+
246
+ // Build a frequency map of all labels across templates
247
+ const labelFrequency = new Map<string, number>();
248
+ for (const template of templates) {
249
+ for (const label of template.labels) {
250
+ labelFrequency.set(label, (labelFrequency.get(label) ?? 0) + 1);
251
+ }
252
+ }
253
+
254
+ // Cross-reference: each template's labels should be known across the template set.
255
+ // A label used by only one template AND not matching any known subcommand is suspicious.
256
+ const knownSubcommands = new Set(templates.map((t) => t.subcommand));
257
+ const knownNames = new Set(templates.map((t) => t.name.toLowerCase()));
258
+ const missingLabels: string[] = [];
259
+
260
+ for (const template of templates) {
261
+ for (const label of template.labels) {
262
+ // Check if the label is completely unknown: used once, and not matching
263
+ // any template subcommand or name (which would make it a valid unique label)
264
+ const freq = labelFrequency.get(label) ?? 0;
265
+ if (
266
+ freq === 1 &&
267
+ !knownSubcommands.has(label) &&
268
+ !knownNames.has(label.toLowerCase()) &&
269
+ !WELL_KNOWN_LABELS.has(label)
270
+ ) {
271
+ missingLabels.push(label);
272
+ }
273
+ }
274
+ }
275
+
276
+ return {
277
+ valid: missingLabels.length === 0,
278
+ missingLabels,
279
+ };
238
280
  }
281
+
282
+ /** Labels that are well-known in GitHub/issue trackers and always valid. */
283
+ const WELL_KNOWN_LABELS = new Set([
284
+ 'bug',
285
+ 'enhancement',
286
+ 'feature',
287
+ 'help',
288
+ 'question',
289
+ 'documentation',
290
+ 'good first issue',
291
+ 'duplicate',
292
+ 'invalid',
293
+ 'wontfix',
294
+ 'priority',
295
+ 'critical',
296
+ 'high',
297
+ 'medium',
298
+ 'low',
299
+ ]);
@@ -695,14 +695,14 @@ export async function listPipelines(options: PipelineQueryOptions = {}): Promise
695
695
  * Only valid when the pipeline is in the 'release' stage.
696
696
  *
697
697
  * @param taskId - The task ID
698
- * @param _reason - Optional completion reason (unused, for API compatibility)
698
+ * @param reason - Optional completion reason, stored in the final stage's notes
699
699
  * @throws {CleoError} If pipeline not found or not in releasable state
700
700
  * @returns Promise resolving when complete
701
701
  *
702
702
  * @task T4800
703
703
  * @task T4912 - Implemented SQLite wiring
704
704
  */
705
- export async function completePipeline(taskId: string, _reason?: string): Promise<void> {
705
+ export async function completePipeline(taskId: string, reason?: string): Promise<void> {
706
706
  const db = await getDb();
707
707
  const now = new Date();
708
708
 
@@ -719,14 +719,21 @@ export async function completePipeline(taskId: string, _reason?: string): Promis
719
719
 
720
720
  const pipeline = pipelineResult[0];
721
721
 
722
- // Mark current stage (release) as completed
722
+ // Mark current stage (release) as completed, storing completion reason in notes
723
723
  if (pipeline.currentStageId) {
724
+ const stageUpdate: Record<string, unknown> = {
725
+ status: 'completed',
726
+ completedAt: now.toISOString(),
727
+ };
728
+
729
+ if (reason) {
730
+ stageUpdate.notesJson = JSON.stringify([`Completion reason: ${reason}`]);
731
+ stageUpdate.metadataJson = JSON.stringify({ completionReason: reason });
732
+ }
733
+
724
734
  await db
725
735
  .update(schema.lifecycleStages)
726
- .set({
727
- status: 'completed',
728
- completedAt: now.toISOString(),
729
- })
736
+ .set(stageUpdate)
730
737
  .where(
731
738
  and(
732
739
  eq(schema.lifecycleStages.pipelineId, pipeline.id),
@@ -713,7 +713,7 @@ export function canSkipStage(stage: Stage): boolean {
713
713
  *
714
714
  * @task T4800
715
715
  */
716
- export function skipStage(stage: Stage, _reason: string, context: StateMachineContext): StageState {
716
+ export function skipStage(stage: Stage, reason: string, context: StateMachineContext): StageState {
717
717
  if (!canSkipStage(stage)) {
718
718
  throw new CleoError(ExitCode.LIFECYCLE_TRANSITION_INVALID, `Stage ${stage} cannot be skipped`, {
719
719
  fix: `Complete the ${stage} stage or use force flag`,
@@ -729,5 +729,9 @@ export function skipStage(stage: Stage, _reason: string, context: StateMachineCo
729
729
  );
730
730
  }
731
731
 
732
- return setStageStatus(stage, 'skipped', context);
732
+ const updatedState = setStageStatus(stage, 'skipped', context);
733
+ // Store the skip reason in the stage notes for in-memory context;
734
+ // the DB-level skip_reason column is set by recordStageProgress in lifecycle/index.ts
735
+ updatedState.notes = reason;
736
+ return updatedState;
733
737
  }
@@ -13,6 +13,8 @@
13
13
 
14
14
  import { createHash } from 'node:crypto';
15
15
  import { getBrainAccessor } from '../store/brain-accessor.js';
16
+ import { typedAll } from '../store/typed-query.js';
17
+ import type { BrainConsolidationObservationRow } from './brain-row-types.js';
16
18
 
17
19
  /** Result from applying temporal decay. */
18
20
  export interface DecayResult {
@@ -248,22 +250,14 @@ export async function consolidateMemories(
248
250
  .slice(0, 19);
249
251
 
250
252
  // Fetch old observations that are not already archived
251
- const oldObservations = nativeDb
252
- .prepare(`
253
+ const stmt = nativeDb.prepare(`
253
254
  SELECT id, type, title, narrative, project, created_at
254
255
  FROM brain_observations
255
256
  WHERE created_at < ?
256
257
  AND narrative NOT LIKE '[ARCHIVED]%'
257
258
  ORDER BY created_at DESC
258
- `)
259
- .all(cutoffDate) as Array<{
260
- id: string;
261
- type: string;
262
- title: string;
263
- narrative: string | null;
264
- project: string | null;
265
- created_at: string;
266
- }>;
259
+ `);
260
+ const oldObservations = typedAll<BrainConsolidationObservationRow>(stmt, cutoffDate);
267
261
 
268
262
  if (oldObservations.length < minClusterSize) {
269
263
  return { grouped: 0, merged: 0, archived: 0 };