@devran-ai/kit 4.1.0

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 (231) hide show
  1. package/.agent/CheatSheet.md +350 -0
  2. package/.agent/README.md +76 -0
  3. package/.agent/agents/README.md +155 -0
  4. package/.agent/agents/architect.md +185 -0
  5. package/.agent/agents/backend-specialist.md +276 -0
  6. package/.agent/agents/build-error-resolver.md +207 -0
  7. package/.agent/agents/code-reviewer.md +162 -0
  8. package/.agent/agents/database-architect.md +138 -0
  9. package/.agent/agents/devops-engineer.md +144 -0
  10. package/.agent/agents/doc-updater.md +229 -0
  11. package/.agent/agents/e2e-runner.md +145 -0
  12. package/.agent/agents/explorer-agent.md +143 -0
  13. package/.agent/agents/frontend-specialist.md +144 -0
  14. package/.agent/agents/go-reviewer.md +128 -0
  15. package/.agent/agents/knowledge-agent.md +197 -0
  16. package/.agent/agents/mobile-developer.md +150 -0
  17. package/.agent/agents/performance-optimizer.md +175 -0
  18. package/.agent/agents/planner.md +133 -0
  19. package/.agent/agents/pr-reviewer.md +148 -0
  20. package/.agent/agents/python-reviewer.md +123 -0
  21. package/.agent/agents/refactor-cleaner.md +201 -0
  22. package/.agent/agents/reliability-engineer.md +156 -0
  23. package/.agent/agents/security-reviewer.md +141 -0
  24. package/.agent/agents/sprint-orchestrator.md +124 -0
  25. package/.agent/agents/tdd-guide.md +179 -0
  26. package/.agent/agents/typescript-reviewer.md +110 -0
  27. package/.agent/checklists/README.md +102 -0
  28. package/.agent/checklists/pre-commit.md +93 -0
  29. package/.agent/checklists/session-end.md +99 -0
  30. package/.agent/checklists/session-start.md +102 -0
  31. package/.agent/checklists/task-complete.md +81 -0
  32. package/.agent/commands/README.md +130 -0
  33. package/.agent/commands/adr.md +29 -0
  34. package/.agent/commands/ask.md +28 -0
  35. package/.agent/commands/build.md +30 -0
  36. package/.agent/commands/changelog.md +40 -0
  37. package/.agent/commands/checkpoint.md +28 -0
  38. package/.agent/commands/code-review.md +65 -0
  39. package/.agent/commands/compact.md +28 -0
  40. package/.agent/commands/cook.md +30 -0
  41. package/.agent/commands/db.md +30 -0
  42. package/.agent/commands/debug.md +31 -0
  43. package/.agent/commands/deploy.md +37 -0
  44. package/.agent/commands/design.md +29 -0
  45. package/.agent/commands/doc.md +30 -0
  46. package/.agent/commands/eval.md +30 -0
  47. package/.agent/commands/fix.md +32 -0
  48. package/.agent/commands/git.md +32 -0
  49. package/.agent/commands/help.md +273 -0
  50. package/.agent/commands/implement.md +30 -0
  51. package/.agent/commands/integrate.md +32 -0
  52. package/.agent/commands/learn.md +29 -0
  53. package/.agent/commands/perf.md +31 -0
  54. package/.agent/commands/plan.md +56 -0
  55. package/.agent/commands/pr-describe.md +65 -0
  56. package/.agent/commands/pr-fix.md +45 -0
  57. package/.agent/commands/pr-merge.md +45 -0
  58. package/.agent/commands/pr-review.md +50 -0
  59. package/.agent/commands/pr-split.md +54 -0
  60. package/.agent/commands/pr-status.md +56 -0
  61. package/.agent/commands/pr.md +58 -0
  62. package/.agent/commands/refactor.md +32 -0
  63. package/.agent/commands/research.md +28 -0
  64. package/.agent/commands/scout.md +30 -0
  65. package/.agent/commands/security-scan.md +33 -0
  66. package/.agent/commands/setup.md +31 -0
  67. package/.agent/commands/status.md +59 -0
  68. package/.agent/commands/tdd.md +73 -0
  69. package/.agent/commands/verify.md +58 -0
  70. package/.agent/contexts/brainstorm.md +26 -0
  71. package/.agent/contexts/debug.md +28 -0
  72. package/.agent/contexts/implement.md +29 -0
  73. package/.agent/contexts/plan-quality-log.md +30 -0
  74. package/.agent/contexts/review.md +27 -0
  75. package/.agent/contexts/ship.md +28 -0
  76. package/.agent/decisions/001-trust-grade-governance.md +46 -0
  77. package/.agent/decisions/002-cross-ide-generation.md +15 -0
  78. package/.agent/engine/identity.json +4 -0
  79. package/.agent/engine/loading-rules.json +193 -0
  80. package/.agent/engine/marketplace-index.json +29 -0
  81. package/.agent/engine/mcp-servers/filesystem.json +9 -0
  82. package/.agent/engine/mcp-servers/github.json +11 -0
  83. package/.agent/engine/mcp-servers/postgres.json +11 -0
  84. package/.agent/engine/mcp-servers/supabase.json +11 -0
  85. package/.agent/engine/mcp-servers/vercel.json +11 -0
  86. package/.agent/engine/reliability-config.json +14 -0
  87. package/.agent/engine/sdlc-map.json +50 -0
  88. package/.agent/engine/workflow-state.json +167 -0
  89. package/.agent/hooks/README.md +101 -0
  90. package/.agent/hooks/hooks.json +104 -0
  91. package/.agent/hooks/templates/session-end.md +110 -0
  92. package/.agent/hooks/templates/session-start.md +95 -0
  93. package/.agent/manifest.json +466 -0
  94. package/.agent/rules/agent-upgrade-policy.md +56 -0
  95. package/.agent/rules/architecture.md +111 -0
  96. package/.agent/rules/coding-style.md +75 -0
  97. package/.agent/rules/documentation.md +74 -0
  98. package/.agent/rules/git-workflow.md +140 -0
  99. package/.agent/rules/quality-gate.md +117 -0
  100. package/.agent/rules/security.md +67 -0
  101. package/.agent/rules/sprint-tracking.md +103 -0
  102. package/.agent/rules/testing.md +80 -0
  103. package/.agent/rules/workflow-standards.md +30 -0
  104. package/.agent/rules.md +293 -0
  105. package/.agent/session-context.md +69 -0
  106. package/.agent/session-state.json +27 -0
  107. package/.agent/skills/README.md +135 -0
  108. package/.agent/skills/api-patterns/SKILL.md +117 -0
  109. package/.agent/skills/app-builder/SKILL.md +202 -0
  110. package/.agent/skills/architecture/SKILL.md +101 -0
  111. package/.agent/skills/behavioral-modes/SKILL.md +295 -0
  112. package/.agent/skills/brainstorming/SKILL.md +156 -0
  113. package/.agent/skills/clean-code/SKILL.md +142 -0
  114. package/.agent/skills/context-budget/SKILL.md +78 -0
  115. package/.agent/skills/continuous-learning/SKILL.md +145 -0
  116. package/.agent/skills/database-design/SKILL.md +303 -0
  117. package/.agent/skills/debugging-strategies/SKILL.md +158 -0
  118. package/.agent/skills/deployment-procedures/SKILL.md +191 -0
  119. package/.agent/skills/docker-patterns/SKILL.md +161 -0
  120. package/.agent/skills/eval-harness/SKILL.md +89 -0
  121. package/.agent/skills/frontend-patterns/SKILL.md +141 -0
  122. package/.agent/skills/git-workflow/SKILL.md +159 -0
  123. package/.agent/skills/i18n-localization/SKILL.md +191 -0
  124. package/.agent/skills/intelligent-routing/SKILL.md +180 -0
  125. package/.agent/skills/mcp-integration/SKILL.md +240 -0
  126. package/.agent/skills/mobile-design/SKILL.md +191 -0
  127. package/.agent/skills/nodejs-patterns/SKILL.md +164 -0
  128. package/.agent/skills/parallel-agents/SKILL.md +200 -0
  129. package/.agent/skills/performance-profiling/SKILL.md +134 -0
  130. package/.agent/skills/plan-validation/SKILL.md +192 -0
  131. package/.agent/skills/plan-writing/SKILL.md +183 -0
  132. package/.agent/skills/plan-writing/domain-enhancers.md +184 -0
  133. package/.agent/skills/plan-writing/plan-retrospective.md +116 -0
  134. package/.agent/skills/plan-writing/plan-schema.md +119 -0
  135. package/.agent/skills/pr-toolkit/SKILL.md +174 -0
  136. package/.agent/skills/production-readiness/SKILL.md +126 -0
  137. package/.agent/skills/security-practices/SKILL.md +109 -0
  138. package/.agent/skills/shell-conventions/SKILL.md +92 -0
  139. package/.agent/skills/strategic-compact/SKILL.md +62 -0
  140. package/.agent/skills/testing-patterns/SKILL.md +141 -0
  141. package/.agent/skills/typescript-expert/SKILL.md +160 -0
  142. package/.agent/skills/ui-ux-pro-max/SKILL.md +137 -0
  143. package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
  144. package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
  145. package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -0
  146. package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
  147. package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
  148. package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  149. package/.agent/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  150. package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  151. package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  152. package/.agent/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  153. package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  154. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  155. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  156. package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  157. package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  158. package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  159. package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  160. package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  161. package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  162. package/.agent/skills/ui-ux-pro-max/data/styles.csv +68 -0
  163. package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
  164. package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  165. package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  166. package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  167. package/.agent/skills/ui-ux-pro-max/scripts/core.py +253 -0
  168. package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  169. package/.agent/skills/ui-ux-pro-max/scripts/search.py +114 -0
  170. package/.agent/skills/verification-loop/SKILL.md +89 -0
  171. package/.agent/skills/webapp-testing/SKILL.md +175 -0
  172. package/.agent/templates/adr-template.md +32 -0
  173. package/.agent/templates/bug-report.md +37 -0
  174. package/.agent/templates/feature-request.md +32 -0
  175. package/.agent/workflows/README.md +101 -0
  176. package/.agent/workflows/brainstorm.md +86 -0
  177. package/.agent/workflows/create.md +85 -0
  178. package/.agent/workflows/debug.md +83 -0
  179. package/.agent/workflows/deploy.md +114 -0
  180. package/.agent/workflows/enhance.md +85 -0
  181. package/.agent/workflows/orchestrate.md +106 -0
  182. package/.agent/workflows/plan.md +105 -0
  183. package/.agent/workflows/pr-fix.md +163 -0
  184. package/.agent/workflows/pr-merge.md +117 -0
  185. package/.agent/workflows/pr-review.md +178 -0
  186. package/.agent/workflows/pr-split.md +118 -0
  187. package/.agent/workflows/pr.md +184 -0
  188. package/.agent/workflows/preflight.md +107 -0
  189. package/.agent/workflows/preview.md +95 -0
  190. package/.agent/workflows/quality-gate.md +103 -0
  191. package/.agent/workflows/retrospective.md +100 -0
  192. package/.agent/workflows/review.md +104 -0
  193. package/.agent/workflows/status.md +89 -0
  194. package/.agent/workflows/test.md +98 -0
  195. package/.agent/workflows/ui-ux-pro-max.md +93 -0
  196. package/.agent/workflows/upgrade.md +97 -0
  197. package/LICENSE +21 -0
  198. package/README.md +218 -0
  199. package/bin/kit.js +773 -0
  200. package/lib/agent-registry.js +228 -0
  201. package/lib/agent-reputation.js +343 -0
  202. package/lib/circuit-breaker.js +195 -0
  203. package/lib/cli-commands.js +322 -0
  204. package/lib/config-validator.js +274 -0
  205. package/lib/conflict-detector.js +252 -0
  206. package/lib/constants.js +47 -0
  207. package/lib/engineering-manager.js +336 -0
  208. package/lib/error-budget.js +370 -0
  209. package/lib/hook-system.js +256 -0
  210. package/lib/ide-generator.js +434 -0
  211. package/lib/identity.js +240 -0
  212. package/lib/io.js +146 -0
  213. package/lib/learning-engine.js +163 -0
  214. package/lib/loading-engine.js +421 -0
  215. package/lib/logger.js +118 -0
  216. package/lib/marketplace.js +321 -0
  217. package/lib/plugin-system.js +604 -0
  218. package/lib/plugin-verifier.js +197 -0
  219. package/lib/rate-limiter.js +113 -0
  220. package/lib/security-scanner.js +312 -0
  221. package/lib/self-healing.js +468 -0
  222. package/lib/session-manager.js +264 -0
  223. package/lib/skill-sandbox.js +244 -0
  224. package/lib/task-governance.js +522 -0
  225. package/lib/task-model.js +332 -0
  226. package/lib/updater.js +240 -0
  227. package/lib/verify.js +279 -0
  228. package/lib/workflow-engine.js +373 -0
  229. package/lib/workflow-events.js +166 -0
  230. package/lib/workflow-persistence.js +160 -0
  231. package/package.json +57 -0
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Devran AI Kit — Circuit Breaker
3
+ *
4
+ * Implements the circuit breaker pattern for protecting external
5
+ * operations (git clones, network requests) from cascading failures.
6
+ *
7
+ * States: CLOSED (normal) → OPEN (failing) → HALF_OPEN (testing recovery)
8
+ *
9
+ * @module lib/circuit-breaker
10
+ * @author Emre Dursun
11
+ * @since v3.2.0
12
+ */
13
+
14
+ 'use strict';
15
+
16
+ /** @typedef {'CLOSED' | 'OPEN' | 'HALF_OPEN'} CircuitState */
17
+
18
+ /**
19
+ * @typedef {object} CircuitBreakerOptions
20
+ * @property {number} [failureThreshold=3] - Failures before opening circuit
21
+ * @property {number} [resetTimeoutMs=60000] - Time before attempting recovery (ms)
22
+ * @property {number} [halfOpenMaxAttempts=1] - Max attempts in half-open state
23
+ */
24
+
25
+ /**
26
+ * @typedef {object} CircuitBreakerState
27
+ * @property {CircuitState} state - Current circuit state
28
+ * @property {number} failureCount - Consecutive failure count
29
+ * @property {number} successCount - Consecutive success count in half-open
30
+ * @property {number | null} lastFailureTime - Timestamp of last failure
31
+ * @property {number} totalFailures - Lifetime failure count
32
+ * @property {number} totalSuccesses - Lifetime success count
33
+ */
34
+
35
+ /**
36
+ * Creates a new circuit breaker instance.
37
+ *
38
+ * @param {string} name - Circuit breaker name for identification
39
+ * @param {CircuitBreakerOptions} [options] - Configuration options
40
+ * @returns {{ execute: Function, getState: Function, reset: Function }}
41
+ */
42
+ function createCircuitBreaker(name, options = {}) {
43
+ const failureThreshold = options.failureThreshold || 3;
44
+ const resetTimeoutMs = options.resetTimeoutMs || 60000;
45
+ const halfOpenMaxAttempts = options.halfOpenMaxAttempts || 1;
46
+
47
+ /** @type {CircuitBreakerState} */
48
+ const state = {
49
+ state: 'CLOSED',
50
+ failureCount: 0,
51
+ successCount: 0,
52
+ lastFailureTime: null,
53
+ totalFailures: 0,
54
+ totalSuccesses: 0,
55
+ };
56
+
57
+ /**
58
+ * Checks if the circuit should transition from OPEN to HALF_OPEN.
59
+ *
60
+ * @returns {boolean}
61
+ */
62
+ function shouldAttemptReset() {
63
+ if (state.state !== 'OPEN' || state.lastFailureTime === null) {
64
+ return false;
65
+ }
66
+ return (Date.now() - state.lastFailureTime) >= resetTimeoutMs;
67
+ }
68
+
69
+ /**
70
+ * Records a successful operation.
71
+ *
72
+ * @returns {void}
73
+ */
74
+ function onSuccess() {
75
+ state.totalSuccesses += 1;
76
+
77
+ if (state.state === 'HALF_OPEN') {
78
+ state.successCount += 1;
79
+ if (state.successCount >= halfOpenMaxAttempts) {
80
+ state.state = 'CLOSED';
81
+ state.failureCount = 0;
82
+ state.successCount = 0;
83
+ state.lastFailureTime = null;
84
+ }
85
+ } else {
86
+ state.failureCount = 0;
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Records a failed operation.
92
+ *
93
+ * @returns {void}
94
+ */
95
+ function onFailure() {
96
+ state.totalFailures += 1;
97
+ state.failureCount += 1;
98
+ state.lastFailureTime = Date.now();
99
+
100
+ if (state.state === 'HALF_OPEN') {
101
+ state.state = 'OPEN';
102
+ state.successCount = 0;
103
+ } else if (state.failureCount >= failureThreshold) {
104
+ state.state = 'OPEN';
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Executes an operation through the circuit breaker.
110
+ *
111
+ * @param {Function} operation - Async or sync operation to execute
112
+ * @returns {*} Result of the operation
113
+ * @throws {Error} If circuit is open or operation fails
114
+ */
115
+ function execute(operation) {
116
+ if (state.state === 'OPEN') {
117
+ if (shouldAttemptReset()) {
118
+ state.state = 'HALF_OPEN';
119
+ state.successCount = 0;
120
+ } else {
121
+ throw new Error(
122
+ `Circuit breaker "${name}" is OPEN — operation rejected. ` +
123
+ `${state.failureCount} consecutive failures. ` +
124
+ `Will retry after ${Math.ceil((resetTimeoutMs - (Date.now() - state.lastFailureTime)) / 1000)}s.`
125
+ );
126
+ }
127
+ }
128
+
129
+ try {
130
+ const result = operation();
131
+ onSuccess();
132
+ return result;
133
+ } catch (error) {
134
+ onFailure();
135
+ throw error;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Executes an asynchronous operation through the circuit breaker.
141
+ * Properly tracks Promise resolution/rejection for state management.
142
+ *
143
+ * @param {Function} operation - Async operation to execute (must return a Promise)
144
+ * @returns {Promise<*>} Result of the operation
145
+ * @throws {Error} If circuit is open or operation fails
146
+ */
147
+ async function executeAsync(operation) {
148
+ if (state.state === 'OPEN') {
149
+ if (shouldAttemptReset()) {
150
+ state.state = 'HALF_OPEN';
151
+ state.successCount = 0;
152
+ } else {
153
+ throw new Error(
154
+ `Circuit breaker "${name}" is OPEN — operation rejected. ` +
155
+ `${state.failureCount} consecutive failures. ` +
156
+ `Will retry after ${Math.ceil((resetTimeoutMs - (Date.now() - state.lastFailureTime)) / 1000)}s.`
157
+ );
158
+ }
159
+ }
160
+
161
+ try {
162
+ const result = await operation();
163
+ onSuccess();
164
+ return result;
165
+ } catch (error) {
166
+ onFailure();
167
+ throw error;
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Returns a snapshot of the circuit breaker state.
173
+ *
174
+ * @returns {CircuitBreakerState & { name: string }}
175
+ */
176
+ function getState() {
177
+ return { name, ...state };
178
+ }
179
+
180
+ /**
181
+ * Resets the circuit breaker to CLOSED state.
182
+ *
183
+ * @returns {void}
184
+ */
185
+ function reset() {
186
+ state.state = 'CLOSED';
187
+ state.failureCount = 0;
188
+ state.successCount = 0;
189
+ state.lastFailureTime = null;
190
+ }
191
+
192
+ return { execute, executeAsync, getState, reset };
193
+ }
194
+
195
+ module.exports = { createCircuitBreaker };
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Devran AI Kit — CLI Command Handlers (Phase 4)
3
+ *
4
+ * Extracted command handlers to keep bin/kit.js under 800 lines.
5
+ * Handles: `market`, `heal`, and dashboard sections.
6
+ *
7
+ * @module lib/cli-commands
8
+ * @author Emre Dursun
9
+ * @since v3.0.0
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const { AGENT_DIR, ENGINE_DIR } = require('./constants');
17
+
18
+ // ANSI colors (shared with kit.js)
19
+ const colors = {
20
+ reset: '\x1b[0m',
21
+ bright: '\x1b[1m',
22
+ green: '\x1b[32m',
23
+ blue: '\x1b[34m',
24
+ yellow: '\x1b[33m',
25
+ red: '\x1b[31m',
26
+ cyan: '\x1b[36m',
27
+ };
28
+
29
+ /**
30
+ * Marketplace CLI handler.
31
+ *
32
+ * @param {string} projectRoot - Root directory
33
+ * @param {string} subCommand - Sub-command: search, info, install, update
34
+ * @param {string} [argument] - Argument for the sub-command
35
+ * @param {object} [options] - CLI options
36
+ * @returns {void}
37
+ */
38
+ function marketCommand(projectRoot, subCommand, argument, options = {}) {
39
+ const marketplace = require('./marketplace');
40
+
41
+ switch (subCommand) {
42
+ case 'search': {
43
+ if (!argument) {
44
+ console.log(`${colors.yellow}Usage: kit market search <query>${colors.reset}`);
45
+ return;
46
+ }
47
+ const results = marketplace.searchMarket(projectRoot, argument);
48
+ console.log(`\n${colors.bright}${colors.blue}═══ Marketplace Search: "${argument}" ═══${colors.reset}\n`);
49
+ if (results.length === 0) {
50
+ console.log(` No plugins found matching "${argument}"`);
51
+ } else {
52
+ for (const entry of results) {
53
+ console.log(` ${colors.green}${entry.name}${colors.reset} v${entry.version}`);
54
+ console.log(` ${entry.description}`);
55
+ console.log(` Tags: ${(entry.tags || []).join(', ')}`);
56
+ console.log('');
57
+ }
58
+ }
59
+ console.log(` ${results.length} result(s)\n`);
60
+ break;
61
+ }
62
+
63
+ case 'info': {
64
+ if (!argument) {
65
+ console.log(`${colors.yellow}Usage: kit market info <plugin-name>${colors.reset}`);
66
+ return;
67
+ }
68
+ const info = marketplace.getMarketInfo(projectRoot, argument);
69
+ if (!info) {
70
+ console.log(`${colors.red}Plugin not found: ${argument}${colors.reset}`);
71
+ return;
72
+ }
73
+ console.log(`\n${colors.bright}${colors.blue}═══ Plugin: ${info.name} ═══${colors.reset}\n`);
74
+ console.log(` Version: ${info.version}`);
75
+ console.log(` Author: ${info.author}`);
76
+ console.log(` Description: ${info.description}`);
77
+ console.log(` Repository: ${info.repository}`);
78
+ console.log(` Tags: ${(info.tags || []).join(', ')}\n`);
79
+ break;
80
+ }
81
+
82
+ case 'install': {
83
+ if (!argument) {
84
+ console.log(`${colors.yellow}Usage: kit market install <plugin-name>${colors.reset}`);
85
+ return;
86
+ }
87
+ console.log(`${colors.cyan}Installing ${argument}...${colors.reset}`);
88
+ const result = marketplace.installFromMarket(projectRoot, argument);
89
+ if (result.success) {
90
+ console.log(`${colors.green}✓ ${result.message}${colors.reset}`);
91
+ } else {
92
+ console.log(`${colors.red}✗ ${result.message}${colors.reset}`);
93
+ }
94
+ break;
95
+ }
96
+
97
+ case 'update': {
98
+ const force = options.force || false;
99
+ const result = marketplace.updateRegistryIndex(projectRoot, { force });
100
+ if (result.updated) {
101
+ console.log(`${colors.green}✓ Registry updated (${result.entryCount} entries)${colors.reset}`);
102
+ } else {
103
+ console.log(`${colors.yellow}Registry is fresh (${result.entryCount} entries). Use --force to update.${colors.reset}`);
104
+ }
105
+ break;
106
+ }
107
+
108
+ default:
109
+ console.log(`${colors.yellow}Usage: kit market <search|info|install|update> [arg]${colors.reset}`);
110
+ break;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Self-healing CLI handler.
116
+ *
117
+ * @param {string} projectRoot - Root directory
118
+ * @param {object} [options] - CLI options
119
+ * @param {string} [options.file] - Path to CI log file
120
+ * @param {boolean} [options.apply] - Apply patches (default: dry-run)
121
+ * @returns {void}
122
+ */
123
+ function healCommand(projectRoot, options = {}) {
124
+ const selfHealing = require('./self-healing');
125
+ let ciOutput = '';
126
+
127
+ // Input source (E-3): file > stdin > last-saved
128
+ if (options.file) {
129
+ const filePath = path.resolve(options.file);
130
+ if (!fs.existsSync(filePath)) {
131
+ console.log(`${colors.red}✗ CI log file not found: ${filePath}${colors.reset}`);
132
+ process.exit(1);
133
+ }
134
+ ciOutput = fs.readFileSync(filePath, 'utf-8');
135
+ } else {
136
+ // Try last-saved CI output
137
+ const lastCiPath = path.join(projectRoot, AGENT_DIR, ENGINE_DIR, 'last-ci-output.txt');
138
+ if (fs.existsSync(lastCiPath)) {
139
+ ciOutput = fs.readFileSync(lastCiPath, 'utf-8');
140
+ } else {
141
+ console.log(`${colors.yellow}No CI output found. Use: kit heal --file <path>${colors.reset}`);
142
+ return;
143
+ }
144
+ }
145
+
146
+ console.log(`\n${colors.bright}${colors.blue}═══ Self-Healing Pipeline ═══${colors.reset}\n`);
147
+
148
+ // Detect failures
149
+ const failures = selfHealing.detectFailure(ciOutput);
150
+
151
+ if (failures.length === 0) {
152
+ console.log(` ${colors.green}✓ No failures detected — pipeline is healthy${colors.reset}\n`);
153
+ return;
154
+ }
155
+
156
+ console.log(` ${colors.red}${failures.length} failure(s) detected${colors.reset}\n`);
157
+
158
+ // Diagnose and generate patches
159
+ for (const failure of failures) {
160
+ const diagnosis = selfHealing.diagnoseFailure(failure);
161
+ console.log(` ${colors.yellow}[${failure.type.toUpperCase()}]${colors.reset} ${failure.message}`);
162
+ console.log(` Diagnosis: ${diagnosis.category} — ${diagnosis.explanation}`);
163
+
164
+ if (diagnosis.autoFixable) {
165
+ const patch = selfHealing.generateFixPatch(failure, diagnosis);
166
+ if (patch) {
167
+ const dryRun = !options.apply;
168
+ const result = selfHealing.applyFixWithConfirmation(projectRoot, patch, { dryRun });
169
+ console.log(` Patch ${patch.patchId}: ${dryRun ? 'DRY RUN' : result.applied ? 'APPLIED' : 'FAILED'}`);
170
+ }
171
+ } else {
172
+ console.log(` ${colors.cyan}→ Manual review required${colors.reset}`);
173
+ }
174
+ console.log('');
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Dashboard sections for Phase 4 features.
180
+ * Called by statusCommand() in kit.js.
181
+ *
182
+ * @param {string} projectRoot - Root directory
183
+ * @returns {void}
184
+ */
185
+ function renderDashboardSections(projectRoot) {
186
+ // ═══ Reputation ═══
187
+ try {
188
+ const reputation = require('./agent-reputation');
189
+ const rankings = reputation.getRankings(projectRoot);
190
+
191
+ console.log(`\n${colors.bright}${colors.cyan}═══ Reputation ═══${colors.reset}`);
192
+
193
+ if (rankings.length === 0) {
194
+ console.log(' No reputation data yet');
195
+ } else {
196
+ for (const agent of rankings.slice(0, 5)) {
197
+ const trend = agent.trend;
198
+ console.log(` ${colors.green}${agent.agent}${colors.reset} — Score: ${agent.score} ${trend} | Reliability: ${agent.reliability}%`);
199
+ }
200
+ }
201
+ } catch {
202
+ // Reputation module not available — silently skip
203
+ }
204
+
205
+ // ═══ Sprint ═══
206
+ try {
207
+ const engMgr = require('./engineering-manager');
208
+ const metrics = engMgr.getSprintMetrics(projectRoot);
209
+
210
+ console.log(`\n${colors.bright}${colors.cyan}═══ Sprint ═══${colors.reset}`);
211
+ console.log(` Total Sprints: ${metrics.totalSprints}`);
212
+ console.log(` Active Sprint: ${metrics.activeSprint ? metrics.activeSprint.name : 'none'}`);
213
+ console.log(` Velocity: ${metrics.velocity} tasks/sprint`);
214
+ } catch {
215
+ // Module not available — silently skip
216
+ }
217
+
218
+ // ═══ Health ═══
219
+ try {
220
+ const selfHealing = require('./self-healing');
221
+ const report = selfHealing.getHealingReport(projectRoot);
222
+
223
+ console.log(`\n${colors.bright}${colors.cyan}═══ Health ═══${colors.reset}`);
224
+ console.log(` Total Heals: ${report.totalHeals}`);
225
+ console.log(` Success Rate: ${report.successRate}%`);
226
+ console.log(` Pending Patches: ${report.pendingPatches}`);
227
+ } catch {
228
+ // Module not available — silently skip
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Health check CLI handler.
234
+ * Aggregates error budget, plugin integrity, config validation, and healing status.
235
+ *
236
+ * @param {string} projectRoot - Root directory
237
+ * @returns {{ healthy: boolean, checks: object[] }}
238
+ */
239
+ function healthCommand(projectRoot) {
240
+ const checks = [];
241
+
242
+ // Error budget health
243
+ try {
244
+ const errorBudget = require('./error-budget');
245
+ const report = errorBudget.getBudgetReport(projectRoot);
246
+ checks.push({
247
+ name: 'Error Budget',
248
+ status: report.status,
249
+ healthy: report.status !== 'EXHAUSTED',
250
+ detail: report.violations.length > 0 ? `Violations: ${report.violations.join(', ')}` : 'All rates within thresholds',
251
+ });
252
+ } catch {
253
+ checks.push({ name: 'Error Budget', status: 'SKIPPED', healthy: true, detail: 'No reliability config found' });
254
+ }
255
+
256
+ // Plugin integrity
257
+ try {
258
+ const pluginVerifier = require('./plugin-verifier');
259
+ const result = pluginVerifier.verifyAllPlugins(projectRoot);
260
+ const pluginHealthy = result.invalid.length === 0;
261
+ checks.push({
262
+ name: 'Plugin Integrity',
263
+ status: pluginHealthy ? 'PASS' : 'FAIL',
264
+ healthy: pluginHealthy,
265
+ detail: `${result.valid} valid, ${result.invalid.length} invalid, ${result.unverified.length} unverified`,
266
+ });
267
+ } catch {
268
+ checks.push({ name: 'Plugin Integrity', status: 'SKIPPED', healthy: true, detail: 'Verifier not available' });
269
+ }
270
+
271
+ // Config validation
272
+ try {
273
+ const configValidator = require('./config-validator');
274
+ const result = configValidator.validateAllConfigs(projectRoot);
275
+ const invalidCount = result.totalConfigs - result.validConfigs;
276
+ const configHealthy = invalidCount === 0;
277
+ checks.push({
278
+ name: 'Config Validation',
279
+ status: configHealthy ? 'PASS' : 'FAIL',
280
+ healthy: configHealthy,
281
+ detail: `${result.validConfigs} valid, ${invalidCount} invalid of ${result.totalConfigs} configs`,
282
+ });
283
+ } catch {
284
+ checks.push({ name: 'Config Validation', status: 'SKIPPED', healthy: true, detail: 'Validator not available' });
285
+ }
286
+
287
+ // Self-healing status
288
+ try {
289
+ const selfHealing = require('./self-healing');
290
+ const report = selfHealing.getHealingReport(projectRoot);
291
+ checks.push({
292
+ name: 'Self-Healing',
293
+ status: report.pendingPatches > 0 ? 'WARNING' : 'PASS',
294
+ healthy: true,
295
+ detail: `${report.totalHeals} heals, ${report.successRate}% success, ${report.pendingPatches} pending`,
296
+ });
297
+ } catch {
298
+ checks.push({ name: 'Self-Healing', status: 'SKIPPED', healthy: true, detail: 'Healer not available' });
299
+ }
300
+
301
+ const healthy = checks.every((c) => c.healthy);
302
+
303
+ // Render output
304
+ console.log(`\n${colors.bright}${colors.blue}═══ Health Check ═══${colors.reset}\n`);
305
+ for (const check of checks) {
306
+ const icon = check.status === 'PASS' || check.status === 'HEALTHY' ? '✓' : check.status === 'FAIL' || check.status === 'EXHAUSTED' ? '✗' : '⚠';
307
+ const color = check.healthy ? 'green' : 'red';
308
+ console.log(` ${colors[color]}${icon} ${check.name}: ${check.status}${colors.reset}`);
309
+ console.log(` ${check.detail}`);
310
+ }
311
+ console.log('');
312
+ console.log(` ${healthy ? `${colors.green}✅ All health checks passed` : `${colors.red}❌ Some health checks failed`}${colors.reset}\n`);
313
+
314
+ return { healthy, checks };
315
+ }
316
+
317
+ module.exports = {
318
+ marketCommand,
319
+ healCommand,
320
+ healthCommand,
321
+ renderDashboardSections,
322
+ };