@nerviq/cli 0.0.1 → 0.9.0-beta.2

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 (148) hide show
  1. package/CHANGELOG.md +181 -0
  2. package/LICENSE +21 -0
  3. package/README.md +447 -0
  4. package/bin/cli.js +749 -0
  5. package/content/case-study-template.md +91 -0
  6. package/content/claims-governance.md +37 -0
  7. package/content/claude-code/audit-repo/SKILL.md +20 -0
  8. package/content/claude-native-integration.md +60 -0
  9. package/content/devto-article.json +9 -0
  10. package/content/launch-posts.md +226 -0
  11. package/content/pilot-rollout-kit.md +30 -0
  12. package/content/release-checklist.md +31 -0
  13. package/package.json +53 -4
  14. package/src/activity.js +529 -0
  15. package/src/aider/activity.js +226 -0
  16. package/src/aider/config-parser.js +166 -0
  17. package/src/aider/context.js +158 -0
  18. package/src/aider/deep-review.js +316 -0
  19. package/src/aider/domain-packs.js +278 -0
  20. package/src/aider/freshness.js +168 -0
  21. package/src/aider/governance.js +253 -0
  22. package/src/aider/interactive.js +334 -0
  23. package/src/aider/mcp-packs.js +98 -0
  24. package/src/aider/patch.js +214 -0
  25. package/src/aider/plans.js +186 -0
  26. package/src/aider/premium.js +360 -0
  27. package/src/aider/setup.js +404 -0
  28. package/src/aider/techniques.js +1323 -0
  29. package/src/analyze.js +821 -0
  30. package/src/audit.js +1003 -0
  31. package/src/badge.js +13 -0
  32. package/src/benchmark.js +339 -0
  33. package/src/claudex-sync.json +7 -0
  34. package/src/codex/activity.js +324 -0
  35. package/src/codex/config-parser.js +183 -0
  36. package/src/codex/context.js +221 -0
  37. package/src/codex/deep-review.js +493 -0
  38. package/src/codex/domain-packs.js +372 -0
  39. package/src/codex/freshness.js +167 -0
  40. package/src/codex/governance.js +192 -0
  41. package/src/codex/interactive.js +618 -0
  42. package/src/codex/mcp-packs.js +660 -0
  43. package/src/codex/patch.js +209 -0
  44. package/src/codex/plans.js +251 -0
  45. package/src/codex/premium.js +614 -0
  46. package/src/codex/setup.js +603 -0
  47. package/src/codex/techniques.js +2649 -0
  48. package/src/context.js +272 -0
  49. package/src/copilot/activity.js +309 -0
  50. package/src/copilot/config-parser.js +226 -0
  51. package/src/copilot/context.js +197 -0
  52. package/src/copilot/deep-review.js +346 -0
  53. package/src/copilot/domain-packs.js +350 -0
  54. package/src/copilot/freshness.js +197 -0
  55. package/src/copilot/governance.js +222 -0
  56. package/src/copilot/interactive.js +406 -0
  57. package/src/copilot/mcp-packs.js +572 -0
  58. package/src/copilot/patch.js +238 -0
  59. package/src/copilot/plans.js +253 -0
  60. package/src/copilot/premium.js +450 -0
  61. package/src/copilot/setup.js +488 -0
  62. package/src/copilot/techniques.js +1822 -0
  63. package/src/cursor/activity.js +301 -0
  64. package/src/cursor/config-parser.js +265 -0
  65. package/src/cursor/context.js +236 -0
  66. package/src/cursor/deep-review.js +334 -0
  67. package/src/cursor/domain-packs.js +346 -0
  68. package/src/cursor/freshness.js +214 -0
  69. package/src/cursor/governance.js +229 -0
  70. package/src/cursor/interactive.js +391 -0
  71. package/src/cursor/mcp-packs.js +571 -0
  72. package/src/cursor/patch.js +243 -0
  73. package/src/cursor/plans.js +254 -0
  74. package/src/cursor/premium.js +468 -0
  75. package/src/cursor/setup.js +488 -0
  76. package/src/cursor/techniques.js +1786 -0
  77. package/src/deep-review.js +345 -0
  78. package/src/domain-packs.js +364 -0
  79. package/src/formatters/sarif.js +115 -0
  80. package/src/gemini/activity.js +402 -0
  81. package/src/gemini/config-parser.js +275 -0
  82. package/src/gemini/context.js +221 -0
  83. package/src/gemini/deep-review.js +559 -0
  84. package/src/gemini/domain-packs.js +371 -0
  85. package/src/gemini/freshness.js +204 -0
  86. package/src/gemini/governance.js +201 -0
  87. package/src/gemini/interactive.js +860 -0
  88. package/src/gemini/mcp-packs.js +658 -0
  89. package/src/gemini/patch.js +229 -0
  90. package/src/gemini/plans.js +269 -0
  91. package/src/gemini/premium.js +759 -0
  92. package/src/gemini/setup.js +692 -0
  93. package/src/gemini/techniques.js +2084 -0
  94. package/src/governance.js +523 -0
  95. package/src/harmony/advisor.js +383 -0
  96. package/src/harmony/audit.js +303 -0
  97. package/src/harmony/canon.js +444 -0
  98. package/src/harmony/cli.js +331 -0
  99. package/src/harmony/drift.js +401 -0
  100. package/src/harmony/governance.js +313 -0
  101. package/src/harmony/memory.js +238 -0
  102. package/src/harmony/sync.js +458 -0
  103. package/src/harmony/watch.js +336 -0
  104. package/src/index.js +256 -0
  105. package/src/insights.js +119 -0
  106. package/src/interactive.js +118 -0
  107. package/src/mcp-packs.js +597 -0
  108. package/src/opencode/activity.js +286 -0
  109. package/src/opencode/config-parser.js +109 -0
  110. package/src/opencode/context.js +247 -0
  111. package/src/opencode/deep-review.js +313 -0
  112. package/src/opencode/domain-packs.js +240 -0
  113. package/src/opencode/freshness.js +158 -0
  114. package/src/opencode/governance.js +159 -0
  115. package/src/opencode/interactive.js +392 -0
  116. package/src/opencode/mcp-packs.js +474 -0
  117. package/src/opencode/patch.js +184 -0
  118. package/src/opencode/plans.js +231 -0
  119. package/src/opencode/premium.js +413 -0
  120. package/src/opencode/setup.js +449 -0
  121. package/src/opencode/techniques.js +1713 -0
  122. package/src/plans.js +655 -0
  123. package/src/secret-patterns.js +30 -0
  124. package/src/setup.js +1274 -0
  125. package/src/synergy/adaptive.js +261 -0
  126. package/src/synergy/compensation.js +156 -0
  127. package/src/synergy/evidence.js +193 -0
  128. package/src/synergy/learning.js +184 -0
  129. package/src/synergy/patterns.js +227 -0
  130. package/src/synergy/ranking.js +83 -0
  131. package/src/synergy/report.js +163 -0
  132. package/src/synergy/routing.js +152 -0
  133. package/src/techniques.js +1354 -0
  134. package/src/watch.js +229 -0
  135. package/src/windsurf/activity.js +302 -0
  136. package/src/windsurf/config-parser.js +267 -0
  137. package/src/windsurf/context.js +249 -0
  138. package/src/windsurf/deep-review.js +337 -0
  139. package/src/windsurf/domain-packs.js +348 -0
  140. package/src/windsurf/freshness.js +215 -0
  141. package/src/windsurf/governance.js +231 -0
  142. package/src/windsurf/interactive.js +388 -0
  143. package/src/windsurf/mcp-packs.js +535 -0
  144. package/src/windsurf/patch.js +231 -0
  145. package/src/windsurf/plans.js +247 -0
  146. package/src/windsurf/premium.js +467 -0
  147. package/src/windsurf/setup.js +471 -0
  148. package/src/windsurf/techniques.js +1758 -0
@@ -0,0 +1,331 @@
1
+ /**
2
+ * H9. Harmony CLI Commands
3
+ *
4
+ * Command handlers for harmony operations, to be called from bin/cli.js.
5
+ * Each function returns a formatted output string (or prints to console).
6
+ *
7
+ * Zero external dependencies - imports from sibling harmony modules and parent platform modules.
8
+ */
9
+
10
+ const path = require('path');
11
+ const { generateStrategicAdvice, PLATFORM_STRENGTHS } = require('./advisor');
12
+ const { startHarmonyWatch, buildHarmonyWatchPlan } = require('./watch');
13
+ const { saveHarmonyState, loadHarmonyState, getHarmonyHistory, recordPlatformScore } = require('./memory');
14
+ const { getHarmonyGovernanceSummary, formatHarmonyGovernanceReport } = require('./governance');
15
+
16
+ const COLORS = {
17
+ reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
18
+ green: '\x1b[32m', yellow: '\x1b[33m', red: '\x1b[31m', blue: '\x1b[36m',
19
+ magenta: '\x1b[35m',
20
+ };
21
+ const c = (text, color) => `${COLORS[color] || ''}${text}${COLORS.reset}`;
22
+
23
+ // ─── Shared helpers ───────────────────────────────────────────────────────────
24
+
25
+ function resolveDir(options) {
26
+ return path.resolve(options.dir || options.d || '.');
27
+ }
28
+
29
+ /**
30
+ * Collect audit results from all detectable platforms.
31
+ * This is a lightweight aggregation - each platform module is loaded lazily.
32
+ */
33
+ function collectPlatformAudits(dir) {
34
+ const results = [];
35
+
36
+ // Try Claude audit
37
+ try {
38
+ const { audit } = require('../audit');
39
+ const result = audit({ dir, silent: true, platform: 'claude' });
40
+ if (result) results.push({ platform: 'claude', ...result });
41
+ } catch (_e) { /* platform not available */ }
42
+
43
+ // Try Codex audit
44
+ try {
45
+ const { audit } = require('../audit');
46
+ const result = audit({ dir, silent: true, platform: 'codex' });
47
+ if (result) results.push({ platform: 'codex', ...result });
48
+ } catch (_e) { /* platform not available */ }
49
+
50
+ // Try Gemini audit
51
+ try {
52
+ const { audit } = require('../audit');
53
+ const result = audit({ dir, silent: true, platform: 'gemini' });
54
+ if (result) results.push({ platform: 'gemini', ...result });
55
+ } catch (_e) { /* platform not available */ }
56
+
57
+ // Try Copilot audit
58
+ try {
59
+ const { audit } = require('../audit');
60
+ const result = audit({ dir, silent: true, platform: 'copilot' });
61
+ if (result) results.push({ platform: 'copilot', ...result });
62
+ } catch (_e) { /* platform not available */ }
63
+
64
+ // Try Cursor audit
65
+ try {
66
+ const { audit } = require('../audit');
67
+ const result = audit({ dir, silent: true, platform: 'cursor' });
68
+ if (result) results.push({ platform: 'cursor', ...result });
69
+ } catch (_e) { /* platform not available */ }
70
+
71
+ return results;
72
+ }
73
+
74
+ // ─── Command: harmony audit ───────────────────────────────────────────────────
75
+
76
+ /**
77
+ * Run a cross-platform audit and display per-platform scores.
78
+ */
79
+ async function runHarmonyAudit(options) {
80
+ const dir = resolveDir(options);
81
+ const platformAudits = collectPlatformAudits(dir);
82
+
83
+ if (options.json) {
84
+ console.log(JSON.stringify({ dir, platforms: platformAudits }, null, 2));
85
+ return { dir, platforms: platformAudits };
86
+ }
87
+
88
+ console.log('');
89
+ console.log(c(' Harmony Cross-Platform Audit', 'bold'));
90
+ console.log(c(' ═══════════════════════════════════════', 'dim'));
91
+ console.log(c(` Directory: ${dir}`, 'dim'));
92
+ console.log('');
93
+
94
+ if (platformAudits.length === 0) {
95
+ console.log(c(' No platform configurations detected.', 'yellow'));
96
+ console.log(c(' Run "nerviq setup" to bootstrap a platform.', 'dim'));
97
+ console.log('');
98
+ return { dir, platforms: [] };
99
+ }
100
+
101
+ for (const audit of platformAudits) {
102
+ const scoreColor = audit.score >= 70 ? 'green' : audit.score >= 40 ? 'yellow' : 'red';
103
+ console.log(` ${c(audit.platform.padEnd(12), 'bold')} ${c(`${audit.score}/100`, scoreColor)} (${audit.passed || 0}/${(audit.passed || 0) + (audit.failed || 0)} checks)`);
104
+
105
+ // Record score to memory
106
+ try {
107
+ recordPlatformScore(dir, audit.platform, audit.score, { passed: audit.passed, failed: audit.failed });
108
+ } catch (_e) { /* memory write optional */ }
109
+ }
110
+
111
+ // Average score
112
+ const avgScore = Math.round(platformAudits.reduce((sum, a) => sum + (a.score || 0), 0) / platformAudits.length);
113
+ const avgColor = avgScore >= 70 ? 'green' : avgScore >= 40 ? 'yellow' : 'red';
114
+ console.log('');
115
+ console.log(` ${c('Average:', 'bold')} ${c(`${avgScore}/100`, avgColor)}`);
116
+ console.log(` ${c('Platforms:', 'bold')} ${platformAudits.length}`);
117
+ console.log('');
118
+
119
+ return { dir, platforms: platformAudits, averageScore: avgScore };
120
+ }
121
+
122
+ // ─── Command: harmony sync ────────────────────────────────────────────────────
123
+
124
+ /**
125
+ * Sync canonical model across platforms (detect drift and suggest fixes).
126
+ */
127
+ async function runHarmonySync(options) {
128
+ const dir = resolveDir(options);
129
+ const platformAudits = collectPlatformAudits(dir);
130
+
131
+ // Load or build canonical model from memory
132
+ const state = loadHarmonyState(dir);
133
+ const canonicalModel = state.canon || null;
134
+
135
+ const advice = generateStrategicAdvice(canonicalModel, platformAudits);
136
+
137
+ if (options.json) {
138
+ console.log(JSON.stringify({ dir, sync: advice.crossPlatformActions }, null, 2));
139
+ return advice.crossPlatformActions;
140
+ }
141
+
142
+ console.log('');
143
+ console.log(c(' Harmony Sync', 'bold'));
144
+ console.log(c(' ═══════════════════════════════════════', 'dim'));
145
+ console.log('');
146
+
147
+ if (advice.crossPlatformActions.length === 0) {
148
+ console.log(c(' All platforms are in sync. No actions needed.', 'green'));
149
+ console.log('');
150
+ return [];
151
+ }
152
+
153
+ for (const action of advice.crossPlatformActions) {
154
+ const prioColor = action.priority === 'high' ? 'red' : action.priority === 'medium' ? 'yellow' : 'dim';
155
+ console.log(` ${c(`[${action.priority.toUpperCase()}]`, prioColor)} ${action.action}`);
156
+ console.log(` ${c('Affected:', 'dim')} ${action.affectedPlatforms.join(', ')}`);
157
+ if (action.sourcePlatforms) {
158
+ console.log(` ${c('Source:', 'dim')} ${action.sourcePlatforms.join(', ')}`);
159
+ }
160
+ console.log('');
161
+ }
162
+
163
+ return advice.crossPlatformActions;
164
+ }
165
+
166
+ // ─── Command: harmony drift ──────────────────────────────────────────────────
167
+
168
+ /**
169
+ * Detect and display drift between platforms.
170
+ */
171
+ async function runHarmonyDrift(options) {
172
+ const dir = resolveDir(options);
173
+ const state = loadHarmonyState(dir);
174
+ const history = getHarmonyHistory(dir, options.platform ? { platform: options.platform } : undefined);
175
+
176
+ if (options.json) {
177
+ console.log(JSON.stringify({ dir, drift: history.driftHistory }, null, 2));
178
+ return history.driftHistory;
179
+ }
180
+
181
+ console.log('');
182
+ console.log(c(' Harmony Drift History', 'bold'));
183
+ console.log(c(' ═══════════════════════════════════════', 'dim'));
184
+ console.log('');
185
+
186
+ const driftEntries = history.driftHistory;
187
+
188
+ if (driftEntries.length === 0) {
189
+ console.log(c(' No drift history recorded yet.', 'dim'));
190
+ console.log(c(' Run "nerviq harmony audit" to start tracking.', 'dim'));
191
+ console.log('');
192
+ return [];
193
+ }
194
+
195
+ // Show recent drift entries (last 20)
196
+ const recent = driftEntries.slice(-20);
197
+ for (const entry of recent) {
198
+ const driftColor = entry.driftScore > 20 ? 'red' : entry.driftScore > 10 ? 'yellow' : 'green';
199
+ console.log(` ${c(entry.timestamp || 'unknown', 'dim')} ${entry.platform.padEnd(12)} drift: ${c(String(entry.driftScore), driftColor)}`);
200
+ if (entry.driftedFields && entry.driftedFields.length > 0) {
201
+ console.log(` ${c('Fields:', 'dim')} ${entry.driftedFields.join(', ')}`);
202
+ }
203
+ }
204
+ console.log('');
205
+
206
+ return driftEntries;
207
+ }
208
+
209
+ // ─── Command: harmony advise ──────────────────────────────────────────────────
210
+
211
+ /**
212
+ * Generate and display strategic advice.
213
+ */
214
+ async function runHarmonyAdvise(options) {
215
+ const dir = resolveDir(options);
216
+ const platformAudits = collectPlatformAudits(dir);
217
+ const state = loadHarmonyState(dir);
218
+ const canonicalModel = state.canon || null;
219
+
220
+ const advice = generateStrategicAdvice(canonicalModel, platformAudits);
221
+
222
+ if (options.json) {
223
+ console.log(JSON.stringify(advice, null, 2));
224
+ return advice;
225
+ }
226
+
227
+ console.log('');
228
+ console.log(c(' Harmony Strategic Advisor', 'bold'));
229
+ console.log(c(' ═══════════════════════════════════════', 'dim'));
230
+ console.log('');
231
+
232
+ // Task routing
233
+ console.log(c(' Task Routing Recommendations', 'bold'));
234
+ console.log('');
235
+ for (const route of advice.taskRouting) {
236
+ const confColor = route.confidence === 'high' ? 'green' : route.confidence === 'medium' ? 'yellow' : 'dim';
237
+ console.log(` ${c(route.taskLabel.padEnd(22), 'bold')} → ${c(route.recommendedLabel, 'blue')} ${c(`[${route.confidence}]`, confColor)}`);
238
+ console.log(` ${c(route.reasoning, 'dim')}`);
239
+ if (route.alternatives.length > 0) {
240
+ const altLabels = route.alternatives.map(a => `${a.label} (${a.score})`).join(', ');
241
+ console.log(` ${c('Alternatives:', 'dim')} ${altLabels}`);
242
+ }
243
+ console.log('');
244
+ }
245
+
246
+ // Config recommendations
247
+ if (advice.configRecommendations.length > 0) {
248
+ console.log(c(' Configuration Recommendations', 'bold'));
249
+ console.log('');
250
+ for (const rec of advice.configRecommendations) {
251
+ const impactColor = rec.impact === 'high' ? 'red' : rec.impact === 'medium' ? 'yellow' : 'dim';
252
+ console.log(` ${c(`[${rec.impact.toUpperCase()}]`, impactColor)} ${rec.platform}: ${rec.recommendation}`);
253
+ }
254
+ console.log('');
255
+ }
256
+
257
+ // Cross-platform actions
258
+ if (advice.crossPlatformActions.length > 0) {
259
+ console.log(c(' Cross-Platform Actions', 'bold'));
260
+ console.log('');
261
+ for (const action of advice.crossPlatformActions) {
262
+ const prioColor = action.priority === 'high' ? 'red' : action.priority === 'medium' ? 'yellow' : 'dim';
263
+ console.log(` ${c(`[${action.priority.toUpperCase()}]`, prioColor)} ${action.action}`);
264
+ console.log(` ${c('Platforms:', 'dim')} ${action.affectedPlatforms.join(', ')}`);
265
+ }
266
+ console.log('');
267
+ }
268
+
269
+ return advice;
270
+ }
271
+
272
+ // ─── Command: harmony watch ───────────────────────────────────────────────────
273
+
274
+ /**
275
+ * Start the harmony watch loop.
276
+ */
277
+ async function runHarmonyWatch(options) {
278
+ const dir = resolveDir(options);
279
+
280
+ await startHarmonyWatch({
281
+ dir,
282
+ debounceMs: options.debounce || 800,
283
+ onDriftDetected: (platform, details) => {
284
+ console.log(c(` DRIFT ALERT: ${platform} score dropped by ${Math.abs(details.delta)}`, 'red'));
285
+ },
286
+ onPlatformChange: (platform, file) => {
287
+ // Logged by watch module itself
288
+ },
289
+ runAudit: options.noAudit ? null : async (auditDir) => {
290
+ const audits = collectPlatformAudits(auditDir);
291
+ const result = {};
292
+ for (const audit of audits) {
293
+ result[audit.platform] = audit;
294
+ }
295
+ return result;
296
+ },
297
+ });
298
+ }
299
+
300
+ // ─── Command: harmony governance ──────────────────────────────────────────────
301
+
302
+ /**
303
+ * Display the cross-platform governance summary.
304
+ */
305
+ async function runHarmonyGovernance(options) {
306
+ const dir = resolveDir(options);
307
+ const platformAudits = collectPlatformAudits(dir);
308
+ const state = loadHarmonyState(dir);
309
+ const canonicalModel = state.canon || null;
310
+
311
+ const summary = getHarmonyGovernanceSummary(canonicalModel, platformAudits);
312
+
313
+ if (options.json) {
314
+ console.log(JSON.stringify(summary, null, 2));
315
+ return summary;
316
+ }
317
+
318
+ const report = formatHarmonyGovernanceReport(summary, options);
319
+ console.log(report);
320
+
321
+ return summary;
322
+ }
323
+
324
+ module.exports = {
325
+ runHarmonyAudit,
326
+ runHarmonySync,
327
+ runHarmonyDrift,
328
+ runHarmonyAdvise,
329
+ runHarmonyWatch,
330
+ runHarmonyGovernance,
331
+ };