@vibecheckai/cli 3.2.6 → 3.3.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.
- package/bin/registry.js +192 -5
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +280 -6
- package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
- package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
- package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
- package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
- package/bin/runners/lib/agent-firewall/logger.js +141 -0
- package/bin/runners/lib/agent-firewall/policy/loader.js +312 -4
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +113 -1
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +133 -6
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
- package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
- package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
- package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
- package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
- package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
- package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
- package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +321 -0
- package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
- package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
- package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
- package/bin/runners/lib/analyzers.js +81 -18
- package/bin/runners/lib/authority-badge.js +425 -0
- package/bin/runners/lib/cli-output.js +7 -1
- package/bin/runners/lib/error-handler.js +16 -9
- package/bin/runners/lib/exit-codes.js +275 -0
- package/bin/runners/lib/global-flags.js +37 -0
- package/bin/runners/lib/help-formatter.js +413 -0
- package/bin/runners/lib/logger.js +38 -0
- package/bin/runners/lib/unified-cli-output.js +604 -0
- package/bin/runners/lib/upsell.js +148 -0
- package/bin/runners/runApprove.js +1200 -0
- package/bin/runners/runAuth.js +324 -95
- package/bin/runners/runCheckpoint.js +39 -21
- package/bin/runners/runClassify.js +859 -0
- package/bin/runners/runContext.js +136 -24
- package/bin/runners/runDoctor.js +108 -68
- package/bin/runners/runFix.js +6 -5
- package/bin/runners/runGuard.js +212 -118
- package/bin/runners/runInit.js +3 -2
- package/bin/runners/runMcp.js +130 -52
- package/bin/runners/runPolish.js +43 -20
- package/bin/runners/runProve.js +1 -2
- package/bin/runners/runReport.js +3 -2
- package/bin/runners/runScan.js +63 -44
- package/bin/runners/runShip.js +3 -4
- package/bin/runners/runValidate.js +19 -2
- package/bin/runners/runWatch.js +104 -53
- package/bin/vibecheck.js +106 -19
- package/mcp-server/HARDENING_SUMMARY.md +299 -0
- package/mcp-server/agent-firewall-interceptor.js +367 -31
- package/mcp-server/authority-tools.js +569 -0
- package/mcp-server/conductor/conflict-resolver.js +588 -0
- package/mcp-server/conductor/execution-planner.js +544 -0
- package/mcp-server/conductor/index.js +377 -0
- package/mcp-server/conductor/lock-manager.js +615 -0
- package/mcp-server/conductor/request-queue.js +550 -0
- package/mcp-server/conductor/session-manager.js +500 -0
- package/mcp-server/conductor/tools.js +510 -0
- package/mcp-server/index.js +1149 -243
- package/mcp-server/lib/{api-client.js → api-client.cjs} +40 -4
- package/mcp-server/lib/logger.cjs +30 -0
- package/mcp-server/logger.js +173 -0
- package/mcp-server/package.json +2 -2
- package/mcp-server/premium-tools.js +2 -2
- package/mcp-server/tier-auth.js +245 -35
- package/mcp-server/truth-firewall-tools.js +145 -15
- package/mcp-server/vibecheck-tools.js +2 -2
- package/package.json +2 -3
- package/mcp-server/index.old.js +0 -4137
- package/mcp-server/package-lock.json +0 -165
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vibecheck CLI Help Formatter - World-Class Help System
|
|
3
|
+
*
|
|
4
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
* Provides consistent, beautiful, and informative help text across all commands.
|
|
6
|
+
* Features:
|
|
7
|
+
* - Consistent visual formatting
|
|
8
|
+
* - Rich examples with explanations
|
|
9
|
+
* - Tier badges and upgrade hints
|
|
10
|
+
* - Related commands section
|
|
11
|
+
* - Shell completion hints
|
|
12
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
"use strict";
|
|
16
|
+
|
|
17
|
+
const { ansi, colors, icons, BOX, WIDTH } = require("./terminal-ui");
|
|
18
|
+
|
|
19
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
20
|
+
// CONSTANTS
|
|
21
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
22
|
+
|
|
23
|
+
const HELP_WIDTH = 76;
|
|
24
|
+
const INDENT = " ";
|
|
25
|
+
const SECTION_INDENT = " ";
|
|
26
|
+
|
|
27
|
+
// Tier badges
|
|
28
|
+
const TIER_BADGES = {
|
|
29
|
+
free: `${ansi.green}[FREE]${ansi.reset}`,
|
|
30
|
+
starter: `${ansi.cyan}[STARTER]${ansi.reset}`,
|
|
31
|
+
pro: `${ansi.magenta}[PRO]${ansi.reset}`,
|
|
32
|
+
enterprise: `${ansi.yellow}[ENTERPRISE]${ansi.reset}`,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
36
|
+
// HELP SECTION BUILDERS
|
|
37
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Format a section header
|
|
41
|
+
*/
|
|
42
|
+
function formatSectionHeader(title, icon = "") {
|
|
43
|
+
const iconStr = icon ? `${icon} ` : "";
|
|
44
|
+
return `\n${INDENT}${ansi.bold}${iconStr}${title}${ansi.reset}\n`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Format a description paragraph
|
|
49
|
+
*/
|
|
50
|
+
function formatDescription(text) {
|
|
51
|
+
if (!text) return "";
|
|
52
|
+
const lines = wrapText(text, HELP_WIDTH - 4);
|
|
53
|
+
return lines.map(line => `${INDENT}${ansi.dim}${line}${ansi.reset}`).join("\n") + "\n";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Format a usage line
|
|
58
|
+
*/
|
|
59
|
+
function formatUsage(command, args = "", options = "[options]") {
|
|
60
|
+
const parts = [`vibecheck ${command}`];
|
|
61
|
+
if (args) parts.push(args);
|
|
62
|
+
if (options) parts.push(options);
|
|
63
|
+
return `${INDENT}${ansi.cyan}${parts.join(" ")}${ansi.reset}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Format aliases
|
|
68
|
+
*/
|
|
69
|
+
function formatAliases(aliases) {
|
|
70
|
+
if (!aliases || aliases.length === 0) return "";
|
|
71
|
+
return `${INDENT}${ansi.dim}Aliases: ${aliases.join(", ")}${ansi.reset}\n`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Format an option/flag
|
|
76
|
+
*/
|
|
77
|
+
function formatOption(flag, description, meta = {}) {
|
|
78
|
+
const { tier, default: defaultVal, required, short } = meta;
|
|
79
|
+
|
|
80
|
+
let flagStr = `${colors.accent}${flag}${ansi.reset}`;
|
|
81
|
+
if (short) {
|
|
82
|
+
flagStr = `${colors.accent}${short}${ansi.reset}, ${flagStr}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let line = `${SECTION_INDENT}${flagStr.padEnd(28)}`;
|
|
86
|
+
line += description;
|
|
87
|
+
|
|
88
|
+
if (tier && tier !== "free") {
|
|
89
|
+
line += ` ${TIER_BADGES[tier]}`;
|
|
90
|
+
}
|
|
91
|
+
if (defaultVal !== undefined) {
|
|
92
|
+
line += ` ${ansi.dim}(default: ${defaultVal})${ansi.reset}`;
|
|
93
|
+
}
|
|
94
|
+
if (required) {
|
|
95
|
+
line += ` ${ansi.yellow}(required)${ansi.reset}`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return line;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Format a group of options
|
|
103
|
+
*/
|
|
104
|
+
function formatOptionGroup(title, options) {
|
|
105
|
+
const lines = [formatSectionHeader(title)];
|
|
106
|
+
for (const opt of options) {
|
|
107
|
+
lines.push(formatOption(opt.flag, opt.description, opt));
|
|
108
|
+
}
|
|
109
|
+
return lines.join("\n");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Format an example
|
|
114
|
+
*/
|
|
115
|
+
function formatExample(command, description, explanation = "") {
|
|
116
|
+
let result = `${SECTION_INDENT}${ansi.dim}#${ansi.reset} ${description}\n`;
|
|
117
|
+
result += `${SECTION_INDENT}${ansi.cyan}${command}${ansi.reset}`;
|
|
118
|
+
if (explanation) {
|
|
119
|
+
result += `\n${SECTION_INDENT}${ansi.dim}${explanation}${ansi.reset}`;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Format examples section
|
|
126
|
+
*/
|
|
127
|
+
function formatExamples(examples) {
|
|
128
|
+
const lines = [formatSectionHeader("EXAMPLES", "💡")];
|
|
129
|
+
for (let i = 0; i < examples.length; i++) {
|
|
130
|
+
const ex = examples[i];
|
|
131
|
+
lines.push(formatExample(ex.command, ex.description, ex.explanation));
|
|
132
|
+
if (i < examples.length - 1) lines.push(""); // spacing between examples
|
|
133
|
+
}
|
|
134
|
+
return lines.join("\n");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Format related commands
|
|
139
|
+
*/
|
|
140
|
+
function formatRelated(commands) {
|
|
141
|
+
if (!commands || commands.length === 0) return "";
|
|
142
|
+
|
|
143
|
+
const lines = [formatSectionHeader("RELATED COMMANDS", "🔗")];
|
|
144
|
+
for (const cmd of commands) {
|
|
145
|
+
const tierBadge = cmd.tier && cmd.tier !== "free" ? ` ${TIER_BADGES[cmd.tier]}` : "";
|
|
146
|
+
lines.push(`${SECTION_INDENT}${ansi.cyan}vibecheck ${cmd.name}${ansi.reset}${tierBadge}`);
|
|
147
|
+
lines.push(`${SECTION_INDENT}${ansi.dim}${cmd.description}${ansi.reset}`);
|
|
148
|
+
lines.push("");
|
|
149
|
+
}
|
|
150
|
+
return lines.join("\n");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Format workflow section (multi-step guide)
|
|
155
|
+
*/
|
|
156
|
+
function formatWorkflow(steps) {
|
|
157
|
+
if (!steps || steps.length === 0) return "";
|
|
158
|
+
|
|
159
|
+
const lines = [formatSectionHeader("WORKFLOW", "📋")];
|
|
160
|
+
for (let i = 0; i < steps.length; i++) {
|
|
161
|
+
const step = steps[i];
|
|
162
|
+
const num = `${i + 1}.`;
|
|
163
|
+
lines.push(`${SECTION_INDENT}${ansi.bold}${num}${ansi.reset} ${step.title}`);
|
|
164
|
+
lines.push(`${SECTION_INDENT} ${ansi.cyan}${step.command}${ansi.reset}`);
|
|
165
|
+
if (step.note) {
|
|
166
|
+
lines.push(`${SECTION_INDENT} ${ansi.dim}${step.note}${ansi.reset}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return lines.join("\n");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Format output section (what the command produces)
|
|
174
|
+
*/
|
|
175
|
+
function formatOutput(outputs) {
|
|
176
|
+
if (!outputs || outputs.length === 0) return "";
|
|
177
|
+
|
|
178
|
+
const lines = [formatSectionHeader("OUTPUT", "📄")];
|
|
179
|
+
for (const out of outputs) {
|
|
180
|
+
lines.push(`${SECTION_INDENT}${ansi.cyan}${out.path}${ansi.reset}`);
|
|
181
|
+
lines.push(`${SECTION_INDENT}${ansi.dim}${out.description}${ansi.reset}`);
|
|
182
|
+
lines.push("");
|
|
183
|
+
}
|
|
184
|
+
return lines.join("\n");
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Format environment variables section
|
|
189
|
+
*/
|
|
190
|
+
function formatEnvVars(vars) {
|
|
191
|
+
if (!vars || vars.length === 0) return "";
|
|
192
|
+
|
|
193
|
+
const lines = [formatSectionHeader("ENVIRONMENT VARIABLES", "🌍")];
|
|
194
|
+
for (const v of vars) {
|
|
195
|
+
lines.push(`${SECTION_INDENT}${ansi.yellow}${v.name}${ansi.reset}`);
|
|
196
|
+
lines.push(`${SECTION_INDENT}${ansi.dim}${v.description}${ansi.reset}`);
|
|
197
|
+
if (v.default) {
|
|
198
|
+
lines.push(`${SECTION_INDENT}${ansi.dim}Default: ${v.default}${ansi.reset}`);
|
|
199
|
+
}
|
|
200
|
+
lines.push("");
|
|
201
|
+
}
|
|
202
|
+
return lines.join("\n");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Format footer with links and hints
|
|
207
|
+
*/
|
|
208
|
+
function formatFooter(command, options = {}) {
|
|
209
|
+
const { docsUrl, tier, upgradeHint } = options;
|
|
210
|
+
|
|
211
|
+
const lines = ["", `${INDENT}${ansi.dim}${"─".repeat(HELP_WIDTH - 4)}${ansi.reset}`];
|
|
212
|
+
|
|
213
|
+
// Tier info
|
|
214
|
+
if (tier && tier !== "free") {
|
|
215
|
+
lines.push(`${INDENT}${ansi.dim}This command requires ${TIER_BADGES[tier]} tier or higher.${ansi.reset}`);
|
|
216
|
+
if (upgradeHint) {
|
|
217
|
+
lines.push(`${INDENT}${ansi.dim}${upgradeHint}${ansi.reset}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Docs link
|
|
222
|
+
if (docsUrl) {
|
|
223
|
+
lines.push(`${INDENT}${ansi.dim}Documentation: ${ansi.underline}${docsUrl}${ansi.reset}`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Global help hint
|
|
227
|
+
lines.push(`${INDENT}${ansi.dim}Run 'vibecheck --help' for all commands.${ansi.reset}`);
|
|
228
|
+
lines.push("");
|
|
229
|
+
|
|
230
|
+
return lines.join("\n");
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
234
|
+
// UTILITY FUNCTIONS
|
|
235
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Wrap text to fit within width
|
|
239
|
+
*/
|
|
240
|
+
function wrapText(text, width) {
|
|
241
|
+
const words = text.split(/\s+/);
|
|
242
|
+
const lines = [];
|
|
243
|
+
let currentLine = "";
|
|
244
|
+
|
|
245
|
+
for (const word of words) {
|
|
246
|
+
if (currentLine.length + word.length + 1 > width) {
|
|
247
|
+
if (currentLine) lines.push(currentLine);
|
|
248
|
+
currentLine = word;
|
|
249
|
+
} else {
|
|
250
|
+
currentLine = currentLine ? `${currentLine} ${word}` : word;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (currentLine) lines.push(currentLine);
|
|
254
|
+
|
|
255
|
+
return lines;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Strip ANSI codes for length calculation
|
|
260
|
+
*/
|
|
261
|
+
function stripAnsi(str) {
|
|
262
|
+
return str.replace(/\x1b\[\d+m/g, "").replace(/\x1b\[38;2;\d+;\d+;\d+m/g, "");
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
266
|
+
// MAIN HELP BUILDER
|
|
267
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Build complete help text for a command
|
|
271
|
+
*
|
|
272
|
+
* @param {object} config - Help configuration
|
|
273
|
+
* @param {string} config.name - Command name
|
|
274
|
+
* @param {string[]} config.aliases - Command aliases
|
|
275
|
+
* @param {string} config.description - Short description
|
|
276
|
+
* @param {string} config.longDescription - Detailed description
|
|
277
|
+
* @param {string} config.tier - Required tier (free, starter, pro)
|
|
278
|
+
* @param {string} config.usage - Usage pattern (e.g., "[path] [options]")
|
|
279
|
+
* @param {object[]} config.options - Array of option definitions
|
|
280
|
+
* @param {object[]} config.examples - Array of example definitions
|
|
281
|
+
* @param {object[]} config.related - Array of related command definitions
|
|
282
|
+
* @param {object[]} config.workflow - Array of workflow steps
|
|
283
|
+
* @param {object[]} config.outputs - Array of output file definitions
|
|
284
|
+
* @param {object[]} config.envVars - Array of environment variable definitions
|
|
285
|
+
* @param {string} config.docsUrl - Documentation URL
|
|
286
|
+
* @param {function} config.banner - Optional banner function
|
|
287
|
+
* @returns {string} Complete formatted help text
|
|
288
|
+
*/
|
|
289
|
+
function buildHelp(config) {
|
|
290
|
+
const parts = [];
|
|
291
|
+
|
|
292
|
+
// Banner (optional)
|
|
293
|
+
if (config.banner) {
|
|
294
|
+
parts.push(config.banner());
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Usage
|
|
298
|
+
parts.push(formatSectionHeader("USAGE"));
|
|
299
|
+
parts.push(formatUsage(config.name, config.usage || "[options]"));
|
|
300
|
+
parts.push("");
|
|
301
|
+
|
|
302
|
+
// Aliases
|
|
303
|
+
if (config.aliases && config.aliases.length > 0) {
|
|
304
|
+
parts.push(formatAliases(config.aliases));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Description
|
|
308
|
+
if (config.longDescription || config.description) {
|
|
309
|
+
parts.push(formatSectionHeader("DESCRIPTION"));
|
|
310
|
+
parts.push(formatDescription(config.longDescription || config.description));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Options (grouped)
|
|
314
|
+
if (config.options && config.options.length > 0) {
|
|
315
|
+
// Group options by category
|
|
316
|
+
const groups = {};
|
|
317
|
+
for (const opt of config.options) {
|
|
318
|
+
const group = opt.group || "OPTIONS";
|
|
319
|
+
if (!groups[group]) groups[group] = [];
|
|
320
|
+
groups[group].push(opt);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
for (const [groupName, groupOpts] of Object.entries(groups)) {
|
|
324
|
+
parts.push(formatOptionGroup(groupName, groupOpts));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Examples
|
|
329
|
+
if (config.examples && config.examples.length > 0) {
|
|
330
|
+
parts.push(formatExamples(config.examples));
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Workflow
|
|
334
|
+
if (config.workflow && config.workflow.length > 0) {
|
|
335
|
+
parts.push(formatWorkflow(config.workflow));
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Output
|
|
339
|
+
if (config.outputs && config.outputs.length > 0) {
|
|
340
|
+
parts.push(formatOutput(config.outputs));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Environment variables
|
|
344
|
+
if (config.envVars && config.envVars.length > 0) {
|
|
345
|
+
parts.push(formatEnvVars(config.envVars));
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Related commands
|
|
349
|
+
if (config.related && config.related.length > 0) {
|
|
350
|
+
parts.push(formatRelated(config.related));
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Footer
|
|
354
|
+
parts.push(formatFooter(config.name, {
|
|
355
|
+
tier: config.tier,
|
|
356
|
+
docsUrl: config.docsUrl,
|
|
357
|
+
upgradeHint: config.tier !== "free" ? "Upgrade at: https://vibecheckai.dev/pricing" : null,
|
|
358
|
+
}));
|
|
359
|
+
|
|
360
|
+
return parts.join("\n");
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
364
|
+
// QUICK HELPERS FOR COMMON PATTERNS
|
|
365
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Global options that apply to most commands
|
|
369
|
+
*/
|
|
370
|
+
const GLOBAL_OPTIONS = [
|
|
371
|
+
{ flag: "--help, -h", description: "Show this help", group: "GLOBAL OPTIONS" },
|
|
372
|
+
{ flag: "--json", description: "Output as JSON (machine-readable)", group: "GLOBAL OPTIONS" },
|
|
373
|
+
{ flag: "--quiet, -q", description: "Suppress non-essential output", group: "GLOBAL OPTIONS" },
|
|
374
|
+
{ flag: "--verbose", description: "Show detailed output", group: "GLOBAL OPTIONS" },
|
|
375
|
+
{ flag: "--no-banner", description: "Hide the banner", group: "GLOBAL OPTIONS" },
|
|
376
|
+
{ flag: "--ci", description: "CI mode (implies --quiet --no-banner)", group: "GLOBAL OPTIONS" },
|
|
377
|
+
{ flag: "--path, -p <dir>", description: "Run in specified directory", group: "GLOBAL OPTIONS" },
|
|
378
|
+
{ flag: "--offline", description: "Run in offline mode (no API)", group: "GLOBAL OPTIONS" },
|
|
379
|
+
];
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Add global options to a command's options array
|
|
383
|
+
*/
|
|
384
|
+
function withGlobalOptions(options) {
|
|
385
|
+
return [...options, ...GLOBAL_OPTIONS];
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
389
|
+
// EXPORTS
|
|
390
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
391
|
+
|
|
392
|
+
module.exports = {
|
|
393
|
+
buildHelp,
|
|
394
|
+
formatSectionHeader,
|
|
395
|
+
formatDescription,
|
|
396
|
+
formatUsage,
|
|
397
|
+
formatAliases,
|
|
398
|
+
formatOption,
|
|
399
|
+
formatOptionGroup,
|
|
400
|
+
formatExample,
|
|
401
|
+
formatExamples,
|
|
402
|
+
formatRelated,
|
|
403
|
+
formatWorkflow,
|
|
404
|
+
formatOutput,
|
|
405
|
+
formatEnvVars,
|
|
406
|
+
formatFooter,
|
|
407
|
+
wrapText,
|
|
408
|
+
stripAnsi,
|
|
409
|
+
withGlobalOptions,
|
|
410
|
+
GLOBAL_OPTIONS,
|
|
411
|
+
TIER_BADGES,
|
|
412
|
+
HELP_WIDTH,
|
|
413
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple Logger Stub
|
|
3
|
+
*
|
|
4
|
+
* Provides a minimal logger interface for modules that need it.
|
|
5
|
+
* Respects VIBECHECK_DEBUG and VIBECHECK_QUIET environment variables.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
const isDebug = process.env.VIBECHECK_DEBUG === "true" || process.env.DEBUG;
|
|
11
|
+
const isQuiet = process.env.VIBECHECK_QUIET === "true";
|
|
12
|
+
|
|
13
|
+
const logger = {
|
|
14
|
+
debug: (...args) => {
|
|
15
|
+
if (isDebug && !isQuiet) {
|
|
16
|
+
console.debug("[DEBUG]", ...args);
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
info: (...args) => {
|
|
20
|
+
if (!isQuiet) {
|
|
21
|
+
console.info("[INFO]", ...args);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
warn: (...args) => {
|
|
25
|
+
console.warn("[WARN]", ...args);
|
|
26
|
+
},
|
|
27
|
+
error: (...args) => {
|
|
28
|
+
console.error("[ERROR]", ...args);
|
|
29
|
+
},
|
|
30
|
+
// Alias for compatibility
|
|
31
|
+
log: (...args) => {
|
|
32
|
+
if (!isQuiet) {
|
|
33
|
+
console.log(...args);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
module.exports = { logger };
|