@vibecheckai/cli 3.5.0 → 3.5.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.
- package/bin/registry.js +214 -237
- package/bin/runners/cli-utils.js +33 -2
- package/bin/runners/context/analyzer.js +52 -1
- package/bin/runners/context/generators/cursor.js +2 -49
- package/bin/runners/context/git-context.js +3 -1
- package/bin/runners/context/team-conventions.js +33 -7
- package/bin/runners/lib/analysis-core.js +25 -5
- package/bin/runners/lib/analyzers.js +431 -481
- package/bin/runners/lib/default-config.js +127 -0
- package/bin/runners/lib/doctor/modules/security.js +3 -1
- package/bin/runners/lib/engine/ast-cache.js +210 -0
- package/bin/runners/lib/engine/auth-extractor.js +211 -0
- package/bin/runners/lib/engine/billing-extractor.js +112 -0
- package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
- package/bin/runners/lib/engine/env-extractor.js +207 -0
- package/bin/runners/lib/engine/express-extractor.js +208 -0
- package/bin/runners/lib/engine/extractors.js +849 -0
- package/bin/runners/lib/engine/index.js +207 -0
- package/bin/runners/lib/engine/repo-index.js +514 -0
- package/bin/runners/lib/engine/types.js +124 -0
- package/bin/runners/lib/engines/accessibility-engine.js +18 -218
- package/bin/runners/lib/engines/api-consistency-engine.js +30 -335
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +27 -292
- package/bin/runners/lib/engines/empty-catch-engine.js +17 -127
- package/bin/runners/lib/engines/mock-data-engine.js +10 -53
- package/bin/runners/lib/engines/performance-issues-engine.js +36 -176
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +54 -382
- package/bin/runners/lib/engines/type-aware-engine.js +39 -263
- package/bin/runners/lib/engines/vibecheck-engines/index.js +13 -122
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +73 -373
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
- package/bin/runners/lib/entitlements-v2.js +73 -97
- package/bin/runners/lib/error-handler.js +44 -3
- package/bin/runners/lib/error-messages.js +289 -0
- package/bin/runners/lib/evidence-pack.js +7 -1
- package/bin/runners/lib/finding-id.js +69 -0
- package/bin/runners/lib/finding-sorter.js +89 -0
- package/bin/runners/lib/html-proof-report.js +700 -350
- package/bin/runners/lib/missions/plan.js +6 -46
- package/bin/runners/lib/missions/templates.js +0 -232
- package/bin/runners/lib/next-action.js +560 -0
- package/bin/runners/lib/prerequisites.js +149 -0
- package/bin/runners/lib/route-detection.js +137 -68
- package/bin/runners/lib/scan-output.js +91 -76
- package/bin/runners/lib/scan-runner.js +135 -0
- package/bin/runners/lib/schemas/ajv-validator.js +464 -0
- package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
- package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
- package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
- package/bin/runners/lib/schemas/run-request.schema.json +108 -0
- package/bin/runners/lib/schemas/validator.js +27 -0
- package/bin/runners/lib/schemas/verdict.schema.json +140 -0
- package/bin/runners/lib/ship-output-enterprise.js +23 -23
- package/bin/runners/lib/ship-output.js +75 -31
- package/bin/runners/lib/terminal-ui.js +6 -113
- package/bin/runners/lib/truth.js +351 -10
- package/bin/runners/lib/unified-cli-output.js +430 -603
- package/bin/runners/lib/unified-output.js +13 -9
- package/bin/runners/runAIAgent.js +10 -5
- package/bin/runners/runAgent.js +0 -3
- package/bin/runners/runAllowlist.js +389 -0
- package/bin/runners/runApprove.js +0 -33
- package/bin/runners/runAuth.js +73 -45
- package/bin/runners/runCheckpoint.js +51 -11
- package/bin/runners/runClassify.js +85 -21
- package/bin/runners/runContext.js +0 -3
- package/bin/runners/runDoctor.js +41 -28
- package/bin/runners/runEvidencePack.js +362 -0
- package/bin/runners/runFirewall.js +0 -3
- package/bin/runners/runFirewallHook.js +0 -3
- package/bin/runners/runFix.js +66 -76
- package/bin/runners/runGuard.js +18 -411
- package/bin/runners/runInit.js +113 -30
- package/bin/runners/runLabs.js +424 -0
- package/bin/runners/runMcp.js +19 -25
- package/bin/runners/runPolish.js +64 -240
- package/bin/runners/runPromptFirewall.js +12 -5
- package/bin/runners/runProve.js +57 -22
- package/bin/runners/runQuickstart.js +531 -0
- package/bin/runners/runReality.js +59 -68
- package/bin/runners/runReport.js +38 -33
- package/bin/runners/runRuntime.js +8 -5
- package/bin/runners/runScan.js +1413 -190
- package/bin/runners/runShip.js +113 -719
- package/bin/runners/runTruth.js +0 -3
- package/bin/runners/runValidate.js +13 -9
- package/bin/runners/runWatch.js +23 -14
- package/bin/scan.js +6 -1
- package/bin/vibecheck.js +204 -185
- package/mcp-server/deprecation-middleware.js +282 -0
- package/mcp-server/handlers/index.ts +15 -0
- package/mcp-server/handlers/tool-handler.ts +554 -0
- package/mcp-server/index-v1.js +698 -0
- package/mcp-server/index.js +210 -238
- package/mcp-server/lib/cache-wrapper.cjs +383 -0
- package/mcp-server/lib/error-envelope.js +138 -0
- package/mcp-server/lib/executor.ts +499 -0
- package/mcp-server/lib/index.ts +19 -0
- package/mcp-server/lib/rate-limiter.js +166 -0
- package/mcp-server/lib/sandbox.test.ts +519 -0
- package/mcp-server/lib/sandbox.ts +395 -0
- package/mcp-server/lib/types.ts +267 -0
- package/mcp-server/package.json +12 -3
- package/mcp-server/registry/tool-registry.js +794 -0
- package/mcp-server/registry/tools.json +605 -0
- package/mcp-server/registry.test.ts +334 -0
- package/mcp-server/tests/tier-gating.test.js +297 -0
- package/mcp-server/tier-auth.js +378 -45
- package/mcp-server/tools-v3.js +353 -442
- package/mcp-server/tsconfig.json +37 -0
- package/mcp-server/vibecheck-2.0-tools.js +14 -1
- package/package.json +1 -1
- package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
- package/bin/runners/lib/audit-logger.js +0 -532
- package/bin/runners/lib/authority/authorities/architecture.js +0 -364
- package/bin/runners/lib/authority/authorities/compliance.js +0 -341
- package/bin/runners/lib/authority/authorities/human.js +0 -343
- package/bin/runners/lib/authority/authorities/quality.js +0 -420
- package/bin/runners/lib/authority/authorities/security.js +0 -228
- package/bin/runners/lib/authority/index.js +0 -293
- package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
- package/bin/runners/lib/cli-charts.js +0 -368
- package/bin/runners/lib/cli-config-display.js +0 -405
- package/bin/runners/lib/cli-demo.js +0 -275
- package/bin/runners/lib/cli-errors.js +0 -438
- package/bin/runners/lib/cli-help-formatter.js +0 -439
- package/bin/runners/lib/cli-interactive-menu.js +0 -509
- package/bin/runners/lib/cli-prompts.js +0 -441
- package/bin/runners/lib/cli-scan-cards.js +0 -362
- package/bin/runners/lib/compliance-reporter.js +0 -710
- package/bin/runners/lib/conductor/index.js +0 -671
- package/bin/runners/lib/easy/README.md +0 -123
- package/bin/runners/lib/easy/index.js +0 -140
- package/bin/runners/lib/easy/interactive-wizard.js +0 -788
- package/bin/runners/lib/easy/one-click-firewall.js +0 -564
- package/bin/runners/lib/easy/zero-config-reality.js +0 -714
- package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
- package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
- package/bin/runners/lib/engines/confidence-scoring.js +0 -276
- package/bin/runners/lib/engines/context-detection.js +0 -264
- package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
- package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
- package/bin/runners/lib/engines/env-variables-engine.js +0 -458
- package/bin/runners/lib/engines/error-handling-engine.js +0 -437
- package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
- package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
- package/bin/runners/lib/engines/framework-detection.js +0 -508
- package/bin/runners/lib/engines/import-order-engine.js +0 -429
- package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
- package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
- package/bin/runners/lib/engines/orchestrator.js +0 -334
- package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
- package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
- package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
- package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
- package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
- package/bin/runners/lib/enhanced-features/index.js +0 -305
- package/bin/runners/lib/enhanced-output.js +0 -631
- package/bin/runners/lib/enterprise.js +0 -300
- package/bin/runners/lib/firewall/command-validator.js +0 -351
- package/bin/runners/lib/firewall/config.js +0 -341
- package/bin/runners/lib/firewall/content-validator.js +0 -519
- package/bin/runners/lib/firewall/index.js +0 -101
- package/bin/runners/lib/firewall/path-validator.js +0 -256
- package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
- package/bin/runners/lib/mcp-utils.js +0 -425
- package/bin/runners/lib/output/index.js +0 -1022
- package/bin/runners/lib/policy-engine.js +0 -652
- package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
- package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
- package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
- package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
- package/bin/runners/lib/polish/autofix/index.js +0 -200
- package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
- package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
- package/bin/runners/lib/polish/backend-checks.js +0 -148
- package/bin/runners/lib/polish/documentation-checks.js +0 -111
- package/bin/runners/lib/polish/frontend-checks.js +0 -168
- package/bin/runners/lib/polish/index.js +0 -71
- package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
- package/bin/runners/lib/polish/library-detection.js +0 -175
- package/bin/runners/lib/polish/performance-checks.js +0 -100
- package/bin/runners/lib/polish/security-checks.js +0 -148
- package/bin/runners/lib/polish/utils.js +0 -203
- package/bin/runners/lib/prompt-builder.js +0 -540
- package/bin/runners/lib/proof-certificate.js +0 -634
- package/bin/runners/lib/reality/accessibility-audit.js +0 -946
- package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
- package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
- package/bin/runners/lib/reality/performance-tracker.js +0 -1077
- package/bin/runners/lib/reality/scenario-generator.js +0 -1404
- package/bin/runners/lib/reality/visual-regression.js +0 -852
- package/bin/runners/lib/reality-profiler.js +0 -717
- package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
- package/bin/runners/lib/review/ai-code-review.js +0 -832
- package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
- package/bin/runners/lib/sbom-generator.js +0 -641
- package/bin/runners/lib/scan-output-enhanced.js +0 -512
- package/bin/runners/lib/security/owasp-scanner.js +0 -939
- package/bin/runners/lib/validators/contract-validator.js +0 -283
- package/bin/runners/lib/validators/dead-export-detector.js +0 -279
- package/bin/runners/lib/validators/dep-audit.js +0 -245
- package/bin/runners/lib/validators/env-validator.js +0 -319
- package/bin/runners/lib/validators/index.js +0 -120
- package/bin/runners/lib/validators/license-checker.js +0 -252
- package/bin/runners/lib/validators/route-validator.js +0 -290
- package/bin/runners/runAuthority.js +0 -528
- package/bin/runners/runConductor.js +0 -772
- package/bin/runners/runContainer.js +0 -366
- package/bin/runners/runEasy.js +0 -410
- package/bin/runners/runIaC.js +0 -372
- package/bin/runners/runVibe.js +0 -791
- package/mcp-server/tools.js +0 -495
|
@@ -1,772 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibecheck conductor - Multi-Agent Coordination
|
|
3
|
-
*
|
|
4
|
-
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
-
* ENTERPRISE EDITION - Agent Orchestration
|
|
6
|
-
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
-
*
|
|
8
|
-
* Manages multiple AI agents working on the same codebase:
|
|
9
|
-
* - Agent registration and status tracking
|
|
10
|
-
* - File locking to prevent concurrent edits
|
|
11
|
-
* - Change proposals with conflict detection
|
|
12
|
-
*
|
|
13
|
-
* Commands:
|
|
14
|
-
* vibecheck conductor status - Show coordination status
|
|
15
|
-
* vibecheck conductor register - Register a new agent
|
|
16
|
-
* vibecheck conductor unregister - Unregister an agent
|
|
17
|
-
* vibecheck conductor lock - Acquire a file lock
|
|
18
|
-
* vibecheck conductor unlock - Release a file lock
|
|
19
|
-
* vibecheck conductor propose - Submit a change proposal
|
|
20
|
-
* vibecheck conductor proposals - List proposals
|
|
21
|
-
* vibecheck conductor agents - List registered agents
|
|
22
|
-
* vibecheck conductor locks - List active locks
|
|
23
|
-
* vibecheck conductor history - Show recent events
|
|
24
|
-
* vibecheck conductor cleanup - Clean up stale state
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
"use strict";
|
|
28
|
-
|
|
29
|
-
const { Conductor } = require("./lib/conductor");
|
|
30
|
-
const { parseGlobalFlags, shouldShowBanner, isJsonMode } = require("./lib/global-flags");
|
|
31
|
-
const { EXIT } = require("./lib/exit-codes");
|
|
32
|
-
const { c, rgb, icons } = require("./lib/terminal-ui");
|
|
33
|
-
|
|
34
|
-
// Unified Output System
|
|
35
|
-
const { output } = require("./lib/output/index.js");
|
|
36
|
-
|
|
37
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
38
|
-
// TERMINAL STYLING
|
|
39
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
40
|
-
|
|
41
|
-
const colors = {
|
|
42
|
-
primary: rgb(150, 200, 255),
|
|
43
|
-
success: rgb(100, 255, 150),
|
|
44
|
-
warning: rgb(255, 200, 100),
|
|
45
|
-
error: rgb(255, 100, 100),
|
|
46
|
-
muted: rgb(120, 120, 140),
|
|
47
|
-
accent: rgb(200, 150, 255),
|
|
48
|
-
agent: rgb(100, 200, 255),
|
|
49
|
-
lock: rgb(255, 180, 100),
|
|
50
|
-
proposal: rgb(150, 255, 200),
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const ICONS = {
|
|
54
|
-
conductor: '🎭',
|
|
55
|
-
agent: '🤖',
|
|
56
|
-
lock: '🔒',
|
|
57
|
-
unlock: '🔓',
|
|
58
|
-
proposal: '📝',
|
|
59
|
-
conflict: '⚠️',
|
|
60
|
-
check: '✓',
|
|
61
|
-
cross: '✗',
|
|
62
|
-
bullet: '•',
|
|
63
|
-
arrow: '→',
|
|
64
|
-
clock: '⏱️',
|
|
65
|
-
sparkle: '✨',
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
69
|
-
// BANNER
|
|
70
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
71
|
-
|
|
72
|
-
const CONDUCTOR_BANNER = `
|
|
73
|
-
${rgb(150, 200, 255)} ██████╗ ██████╗ ███╗ ██╗██████╗ ██╗ ██╗ ██████╗████████╗ ██████╗ ██████╗ ${c.reset}
|
|
74
|
-
${rgb(130, 180, 255)} ██╔════╝██╔═══██╗████╗ ██║██╔══██╗██║ ██║██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗${c.reset}
|
|
75
|
-
${rgb(110, 160, 255)} ██║ ██║ ██║██╔██╗ ██║██║ ██║██║ ██║██║ ██║ ██║ ██║██████╔╝${c.reset}
|
|
76
|
-
${rgb(90, 140, 255)} ██║ ██║ ██║██║╚██╗██║██║ ██║██║ ██║██║ ██║ ██║ ██║██╔══██╗${c.reset}
|
|
77
|
-
${rgb(70, 120, 255)} ╚██████╗╚██████╔╝██║ ╚████║██████╔╝╚██████╔╝╚██████╗ ██║ ╚██████╔╝██║ ██║${c.reset}
|
|
78
|
-
${rgb(50, 100, 255)} ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝${c.reset}
|
|
79
|
-
`;
|
|
80
|
-
|
|
81
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
82
|
-
// OUTPUT HELPERS
|
|
83
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
84
|
-
|
|
85
|
-
function printBanner() {
|
|
86
|
-
console.log(CONDUCTOR_BANNER);
|
|
87
|
-
console.log(`${c.dim} ┌─────────────────────────────────────────────────────────────────────────┐${c.reset}`);
|
|
88
|
-
console.log(`${c.dim} │${c.reset} ${ICONS.conductor} ${c.bold}CONDUCTOR${c.reset} ${c.dim}•${c.reset} ${colors.muted}Multi-Agent Coordination${c.reset} ${c.dim}•${c.reset} ${colors.muted}Conflict Prevention${c.reset} ${c.dim}│${c.reset}`);
|
|
89
|
-
console.log(`${c.dim} └─────────────────────────────────────────────────────────────────────────┘${c.reset}`);
|
|
90
|
-
console.log();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function printHeader(text, icon = ICONS.conductor) {
|
|
94
|
-
console.log();
|
|
95
|
-
console.log(`${colors.primary}${icon} ${c.bold}${text}${c.reset}`);
|
|
96
|
-
console.log(`${c.dim}${'─'.repeat(60)}${c.reset}`);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function printSuccess(message) {
|
|
100
|
-
console.log(`${colors.success}${ICONS.check}${c.reset} ${message}`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function printError(message) {
|
|
104
|
-
console.log(`${colors.error}${ICONS.cross}${c.reset} ${message}`);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function printWarning(message) {
|
|
108
|
-
console.log(`${colors.warning}${ICONS.conflict}${c.reset} ${message}`);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function printInfo(label, value) {
|
|
112
|
-
console.log(` ${colors.muted}${label}:${c.reset} ${value}`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function formatDuration(ms) {
|
|
116
|
-
if (ms < 1000) return `${ms}ms`;
|
|
117
|
-
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
|
118
|
-
if (ms < 3600000) return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;
|
|
119
|
-
return `${Math.floor(ms / 3600000)}h ${Math.floor((ms % 3600000) / 60000)}m`;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function formatTimestamp(iso) {
|
|
123
|
-
const date = new Date(iso);
|
|
124
|
-
const now = new Date();
|
|
125
|
-
const diff = now - date;
|
|
126
|
-
|
|
127
|
-
if (diff < 60000) return "just now";
|
|
128
|
-
if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`;
|
|
129
|
-
if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`;
|
|
130
|
-
return date.toLocaleDateString();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
134
|
-
// SUBCOMMANDS
|
|
135
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Show conductor status overview
|
|
139
|
-
*/
|
|
140
|
-
async function runStatus(options) {
|
|
141
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
142
|
-
await conductor.load();
|
|
143
|
-
const status = conductor.getStatus();
|
|
144
|
-
|
|
145
|
-
if (options.json) {
|
|
146
|
-
console.log(JSON.stringify(status, null, 2));
|
|
147
|
-
return { exitCode: EXIT.OK, status };
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (shouldShowBanner(options)) {
|
|
151
|
-
printBanner();
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
printHeader("Conductor Status", ICONS.conductor);
|
|
155
|
-
|
|
156
|
-
// Agents
|
|
157
|
-
console.log();
|
|
158
|
-
console.log(` ${ICONS.agent} ${c.bold}Agents${c.reset}`);
|
|
159
|
-
printInfo(" Active", `${colors.success}${status.activeAgents}${c.reset}`);
|
|
160
|
-
printInfo(" Total", `${status.totalAgents}`);
|
|
161
|
-
|
|
162
|
-
// Locks
|
|
163
|
-
console.log();
|
|
164
|
-
console.log(` ${ICONS.lock} ${c.bold}Locks${c.reset}`);
|
|
165
|
-
printInfo(" Active", `${colors.lock}${status.activeLocks}${c.reset}`);
|
|
166
|
-
printInfo(" Total", `${status.totalLocks}`);
|
|
167
|
-
|
|
168
|
-
// Proposals
|
|
169
|
-
console.log();
|
|
170
|
-
console.log(` ${ICONS.proposal} ${c.bold}Proposals${c.reset}`);
|
|
171
|
-
printInfo(" Pending", `${colors.proposal}${status.pendingProposals}${c.reset}`);
|
|
172
|
-
printInfo(" Conflicts", status.conflictProposals > 0
|
|
173
|
-
? `${colors.warning}${status.conflictProposals}${c.reset}`
|
|
174
|
-
: `${colors.muted}0${c.reset}`);
|
|
175
|
-
printInfo(" Total", `${status.totalProposals}`);
|
|
176
|
-
|
|
177
|
-
// Metadata
|
|
178
|
-
console.log();
|
|
179
|
-
console.log(` ${ICONS.clock} ${c.bold}Timeline${c.reset}`);
|
|
180
|
-
if (status.stateCreated) {
|
|
181
|
-
printInfo(" Created", formatTimestamp(status.stateCreated));
|
|
182
|
-
}
|
|
183
|
-
if (status.lastUpdated) {
|
|
184
|
-
printInfo(" Updated", formatTimestamp(status.lastUpdated));
|
|
185
|
-
}
|
|
186
|
-
printInfo(" Events", `${status.historyCount}`);
|
|
187
|
-
|
|
188
|
-
console.log();
|
|
189
|
-
|
|
190
|
-
return { exitCode: EXIT.OK, status };
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Register a new agent
|
|
195
|
-
*/
|
|
196
|
-
async function runRegister(options) {
|
|
197
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
198
|
-
await conductor.load();
|
|
199
|
-
|
|
200
|
-
const agentInfo = {
|
|
201
|
-
name: options.name || options._[0] || `agent-${Date.now()}`,
|
|
202
|
-
type: options.type || "ai-assistant",
|
|
203
|
-
capabilities: options.capabilities ? options.capabilities.split(",") : [],
|
|
204
|
-
metadata: options.metadata ? JSON.parse(options.metadata) : {}
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const agentId = await conductor.registerAgent(agentInfo);
|
|
208
|
-
|
|
209
|
-
if (options.json) {
|
|
210
|
-
console.log(JSON.stringify({ success: true, agentId, ...agentInfo }, null, 2));
|
|
211
|
-
return { exitCode: EXIT.OK, agentId };
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
printHeader("Agent Registered", ICONS.agent);
|
|
215
|
-
printSuccess(`Agent registered successfully`);
|
|
216
|
-
console.log();
|
|
217
|
-
printInfo("Agent ID", `${colors.accent}${agentId}${c.reset}`);
|
|
218
|
-
printInfo("Name", agentInfo.name);
|
|
219
|
-
printInfo("Type", agentInfo.type);
|
|
220
|
-
console.log();
|
|
221
|
-
console.log(`${c.dim} Use this ID for lock/propose operations${c.reset}`);
|
|
222
|
-
console.log();
|
|
223
|
-
|
|
224
|
-
return { exitCode: EXIT.OK, agentId };
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Unregister an agent
|
|
229
|
-
*/
|
|
230
|
-
async function runUnregister(options) {
|
|
231
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
232
|
-
await conductor.load();
|
|
233
|
-
|
|
234
|
-
const agentId = options.agentId || options._[0];
|
|
235
|
-
|
|
236
|
-
if (!agentId) {
|
|
237
|
-
printError("Agent ID required. Use --agent-id <id> or provide as argument.");
|
|
238
|
-
return { exitCode: EXIT.ERROR };
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
const result = await conductor.unregisterAgent(agentId);
|
|
242
|
-
|
|
243
|
-
if (options.json) {
|
|
244
|
-
console.log(JSON.stringify(result, null, 2));
|
|
245
|
-
return { exitCode: result.success ? EXIT.OK : EXIT.ERROR, result };
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (result.success) {
|
|
249
|
-
printHeader("Agent Unregistered", ICONS.agent);
|
|
250
|
-
printSuccess(`Agent ${agentId} unregistered`);
|
|
251
|
-
if (result.releasedLocks.length > 0) {
|
|
252
|
-
console.log();
|
|
253
|
-
console.log(`${c.dim} Released locks:${c.reset}`);
|
|
254
|
-
for (const lock of result.releasedLocks) {
|
|
255
|
-
console.log(` ${ICONS.unlock} ${lock}`);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
} else {
|
|
259
|
-
printError(`Failed to unregister: ${result.reason}`);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
console.log();
|
|
263
|
-
return { exitCode: result.success ? EXIT.OK : EXIT.ERROR, result };
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Acquire a file lock
|
|
268
|
-
*/
|
|
269
|
-
async function runLock(options) {
|
|
270
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
271
|
-
await conductor.load();
|
|
272
|
-
|
|
273
|
-
const agentId = options.agentId || options["agent-id"];
|
|
274
|
-
const filePath = options.file || options._[0];
|
|
275
|
-
const reason = options.reason || "editing";
|
|
276
|
-
|
|
277
|
-
if (!agentId) {
|
|
278
|
-
printError("Agent ID required. Use --agent-id <id>");
|
|
279
|
-
return { exitCode: EXIT.ERROR };
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (!filePath) {
|
|
283
|
-
printError("File path required. Use --file <path> or provide as argument.");
|
|
284
|
-
return { exitCode: EXIT.ERROR };
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const result = await conductor.acquireLock(agentId, filePath, reason);
|
|
288
|
-
|
|
289
|
-
if (options.json) {
|
|
290
|
-
console.log(JSON.stringify(result, null, 2));
|
|
291
|
-
return { exitCode: result.success ? EXIT.OK : EXIT.ERROR, result };
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (result.success) {
|
|
295
|
-
printHeader("Lock Acquired", ICONS.lock);
|
|
296
|
-
printSuccess(`Lock acquired on ${filePath}`);
|
|
297
|
-
printInfo("Lock ID", result.lockId);
|
|
298
|
-
printInfo("Agent", agentId);
|
|
299
|
-
printInfo("Reason", reason);
|
|
300
|
-
} else {
|
|
301
|
-
printHeader("Lock Failed", ICONS.lock);
|
|
302
|
-
printError(`Cannot acquire lock: ${result.reason}`);
|
|
303
|
-
if (result.holder) {
|
|
304
|
-
printInfo("Current holder", result.holderName || result.holder);
|
|
305
|
-
printInfo("Holder reason", result.holderReason || "not specified");
|
|
306
|
-
printInfo("Expires in", formatDuration(result.expiresIn));
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
console.log();
|
|
311
|
-
return { exitCode: result.success ? EXIT.OK : EXIT.ERROR, result };
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Release a file lock
|
|
316
|
-
*/
|
|
317
|
-
async function runUnlock(options) {
|
|
318
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
319
|
-
await conductor.load();
|
|
320
|
-
|
|
321
|
-
const agentId = options.agentId || options["agent-id"];
|
|
322
|
-
const filePath = options.file || options._[0];
|
|
323
|
-
|
|
324
|
-
if (!agentId) {
|
|
325
|
-
printError("Agent ID required. Use --agent-id <id>");
|
|
326
|
-
return { exitCode: EXIT.ERROR };
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (!filePath) {
|
|
330
|
-
printError("File path required. Use --file <path> or provide as argument.");
|
|
331
|
-
return { exitCode: EXIT.ERROR };
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
const result = await conductor.releaseLock(agentId, filePath);
|
|
335
|
-
|
|
336
|
-
if (options.json) {
|
|
337
|
-
console.log(JSON.stringify(result, null, 2));
|
|
338
|
-
return { exitCode: result.success ? EXIT.OK : EXIT.ERROR, result };
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (result.success) {
|
|
342
|
-
printHeader("Lock Released", ICONS.unlock);
|
|
343
|
-
printSuccess(`Lock released on ${filePath}`);
|
|
344
|
-
} else {
|
|
345
|
-
printError(`Cannot release lock: ${result.reason}`);
|
|
346
|
-
if (result.holder) {
|
|
347
|
-
printInfo("Current holder", result.holder);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
console.log();
|
|
352
|
-
return { exitCode: result.success ? EXIT.OK : EXIT.ERROR, result };
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Submit a change proposal
|
|
357
|
-
*/
|
|
358
|
-
async function runPropose(options) {
|
|
359
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
360
|
-
await conductor.load();
|
|
361
|
-
|
|
362
|
-
const agentId = options.agentId || options["agent-id"];
|
|
363
|
-
const description = options.description || options._[0] || "";
|
|
364
|
-
const files = options.files ? options.files.split(",") : [];
|
|
365
|
-
const priority = options.priority || "normal";
|
|
366
|
-
|
|
367
|
-
if (!agentId) {
|
|
368
|
-
printError("Agent ID required. Use --agent-id <id>");
|
|
369
|
-
return { exitCode: EXIT.ERROR };
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
if (!description) {
|
|
373
|
-
printError("Description required. Use --description <text> or provide as argument.");
|
|
374
|
-
return { exitCode: EXIT.ERROR };
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const proposal = await conductor.propose(agentId, {
|
|
378
|
-
description,
|
|
379
|
-
files,
|
|
380
|
-
priority
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
if (options.json) {
|
|
384
|
-
console.log(JSON.stringify(proposal, null, 2));
|
|
385
|
-
return { exitCode: proposal.status === "conflict" ? EXIT.WARN : EXIT.OK, proposal };
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
printHeader("Proposal Created", ICONS.proposal);
|
|
389
|
-
|
|
390
|
-
if (proposal.status === "conflict") {
|
|
391
|
-
printWarning("Proposal has conflicts with existing proposals");
|
|
392
|
-
} else {
|
|
393
|
-
printSuccess("Proposal submitted successfully");
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
console.log();
|
|
397
|
-
printInfo("Proposal ID", `${colors.accent}${proposal.id}${c.reset}`);
|
|
398
|
-
printInfo("Status", proposal.status === "conflict"
|
|
399
|
-
? `${colors.warning}${proposal.status}${c.reset}`
|
|
400
|
-
: `${colors.success}${proposal.status}${c.reset}`);
|
|
401
|
-
printInfo("Description", description);
|
|
402
|
-
|
|
403
|
-
if (files.length > 0) {
|
|
404
|
-
console.log();
|
|
405
|
-
console.log(` ${c.dim}Files:${c.reset}`);
|
|
406
|
-
for (const file of files) {
|
|
407
|
-
console.log(` ${ICONS.bullet} ${file}`);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
if (proposal.conflicts && proposal.conflicts.length > 0) {
|
|
412
|
-
console.log();
|
|
413
|
-
console.log(` ${colors.warning}Conflicts:${c.reset}`);
|
|
414
|
-
for (const conflict of proposal.conflicts) {
|
|
415
|
-
console.log(` ${ICONS.conflict} Proposal ${conflict.proposalId.slice(0, 8)}... (${conflict.agentName})`);
|
|
416
|
-
console.log(` ${c.dim}Files: ${conflict.files.join(", ")}${c.reset}`);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
console.log();
|
|
421
|
-
return { exitCode: proposal.status === "conflict" ? EXIT.WARN : EXIT.OK, proposal };
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* List proposals
|
|
426
|
-
*/
|
|
427
|
-
async function runProposals(options) {
|
|
428
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
429
|
-
await conductor.load();
|
|
430
|
-
|
|
431
|
-
const filter = {};
|
|
432
|
-
if (options.status) filter.status = options.status;
|
|
433
|
-
if (options.agentId) filter.agentId = options.agentId;
|
|
434
|
-
if (options.conflicts) filter.hasConflicts = true;
|
|
435
|
-
|
|
436
|
-
const proposals = conductor.listProposals(filter);
|
|
437
|
-
|
|
438
|
-
if (options.json) {
|
|
439
|
-
console.log(JSON.stringify(proposals, null, 2));
|
|
440
|
-
return { exitCode: EXIT.OK, proposals };
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
printHeader("Proposals", ICONS.proposal);
|
|
444
|
-
|
|
445
|
-
if (proposals.length === 0) {
|
|
446
|
-
console.log(` ${c.dim}No proposals found${c.reset}`);
|
|
447
|
-
} else {
|
|
448
|
-
for (const p of proposals) {
|
|
449
|
-
const statusColor = p.status === "conflict" ? colors.warning :
|
|
450
|
-
p.status === "pending" ? colors.proposal :
|
|
451
|
-
p.status === "approved" ? colors.success : colors.muted;
|
|
452
|
-
|
|
453
|
-
console.log();
|
|
454
|
-
console.log(` ${ICONS.proposal} ${c.bold}${p.id.slice(0, 8)}...${c.reset}`);
|
|
455
|
-
printInfo(" Status", `${statusColor}${p.status}${c.reset}`);
|
|
456
|
-
printInfo(" Agent", p.agentName);
|
|
457
|
-
printInfo(" Description", p.description || "(none)");
|
|
458
|
-
printInfo(" Created", formatTimestamp(p.createdAt));
|
|
459
|
-
|
|
460
|
-
if (p.files && p.files.length > 0) {
|
|
461
|
-
printInfo(" Files", p.files.join(", "));
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
if (p.conflicts && p.conflicts.length > 0) {
|
|
465
|
-
printInfo(" Conflicts", `${colors.warning}${p.conflicts.length}${c.reset}`);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
console.log();
|
|
471
|
-
return { exitCode: EXIT.OK, proposals };
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* List registered agents
|
|
476
|
-
*/
|
|
477
|
-
async function runAgents(options) {
|
|
478
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
479
|
-
await conductor.load();
|
|
480
|
-
|
|
481
|
-
const activeOnly = options.active || false;
|
|
482
|
-
const agents = conductor.listAgents(activeOnly);
|
|
483
|
-
|
|
484
|
-
if (options.json) {
|
|
485
|
-
console.log(JSON.stringify(agents, null, 2));
|
|
486
|
-
return { exitCode: EXIT.OK, agents };
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
printHeader("Registered Agents", ICONS.agent);
|
|
490
|
-
|
|
491
|
-
if (agents.length === 0) {
|
|
492
|
-
console.log(` ${c.dim}No agents registered${c.reset}`);
|
|
493
|
-
} else {
|
|
494
|
-
for (const agent of agents) {
|
|
495
|
-
const statusColor = agent.status === "active" ? colors.success :
|
|
496
|
-
agent.status === "inactive" ? colors.warning : colors.muted;
|
|
497
|
-
|
|
498
|
-
console.log();
|
|
499
|
-
console.log(` ${ICONS.agent} ${c.bold}${agent.name}${c.reset}`);
|
|
500
|
-
printInfo(" ID", `${colors.muted}${agent.id}${c.reset}`);
|
|
501
|
-
printInfo(" Type", agent.type);
|
|
502
|
-
printInfo(" Status", `${statusColor}${agent.status}${c.reset}`);
|
|
503
|
-
printInfo(" Last seen", formatTimestamp(agent.lastSeen));
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
console.log();
|
|
508
|
-
return { exitCode: EXIT.OK, agents };
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* List active locks
|
|
513
|
-
*/
|
|
514
|
-
async function runLocks(options) {
|
|
515
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
516
|
-
await conductor.load();
|
|
517
|
-
|
|
518
|
-
const locks = conductor.listLocks();
|
|
519
|
-
|
|
520
|
-
if (options.json) {
|
|
521
|
-
console.log(JSON.stringify(locks, null, 2));
|
|
522
|
-
return { exitCode: EXIT.OK, locks };
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
printHeader("Active Locks", ICONS.lock);
|
|
526
|
-
|
|
527
|
-
const activeLocks = locks.filter(l => !l.stale);
|
|
528
|
-
const staleLocks = locks.filter(l => l.stale);
|
|
529
|
-
|
|
530
|
-
if (activeLocks.length === 0 && staleLocks.length === 0) {
|
|
531
|
-
console.log(` ${c.dim}No active locks${c.reset}`);
|
|
532
|
-
} else {
|
|
533
|
-
if (activeLocks.length > 0) {
|
|
534
|
-
console.log();
|
|
535
|
-
console.log(` ${colors.success}Active (${activeLocks.length})${c.reset}`);
|
|
536
|
-
for (const lock of activeLocks) {
|
|
537
|
-
console.log();
|
|
538
|
-
console.log(` ${ICONS.lock} ${c.bold}${lock.filePath}${c.reset}`);
|
|
539
|
-
printInfo(" Holder", lock.agentName);
|
|
540
|
-
printInfo(" Reason", lock.reason || "(none)");
|
|
541
|
-
printInfo(" Age", formatDuration(lock.lockAge));
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
if (staleLocks.length > 0) {
|
|
546
|
-
console.log();
|
|
547
|
-
console.log(` ${colors.warning}Stale (${staleLocks.length})${c.reset}`);
|
|
548
|
-
for (const lock of staleLocks) {
|
|
549
|
-
console.log();
|
|
550
|
-
console.log(` ${ICONS.unlock} ${c.dim}${lock.filePath}${c.reset}`);
|
|
551
|
-
printInfo(" Former holder", lock.agentName);
|
|
552
|
-
printInfo(" Age", `${colors.warning}${formatDuration(lock.lockAge)}${c.reset} (expired)`);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
console.log();
|
|
558
|
-
return { exitCode: EXIT.OK, locks };
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
/**
|
|
562
|
-
* Show recent history
|
|
563
|
-
*/
|
|
564
|
-
async function runHistory(options) {
|
|
565
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
566
|
-
await conductor.load();
|
|
567
|
-
|
|
568
|
-
const limit = options.limit || 20;
|
|
569
|
-
const history = conductor.getHistory(limit);
|
|
570
|
-
|
|
571
|
-
if (options.json) {
|
|
572
|
-
console.log(JSON.stringify(history, null, 2));
|
|
573
|
-
return { exitCode: EXIT.OK, history };
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
printHeader("Recent Events", ICONS.clock);
|
|
577
|
-
|
|
578
|
-
if (history.length === 0) {
|
|
579
|
-
console.log(` ${c.dim}No events recorded${c.reset}`);
|
|
580
|
-
} else {
|
|
581
|
-
for (const event of history) {
|
|
582
|
-
const icon = event.type.includes("lock") ? ICONS.lock :
|
|
583
|
-
event.type.includes("agent") ? ICONS.agent :
|
|
584
|
-
event.type.includes("proposal") ? ICONS.proposal : ICONS.bullet;
|
|
585
|
-
|
|
586
|
-
console.log();
|
|
587
|
-
console.log(` ${icon} ${c.bold}${event.type}${c.reset} ${c.dim}${formatTimestamp(event.timestamp)}${c.reset}`);
|
|
588
|
-
|
|
589
|
-
// Show relevant details based on event type
|
|
590
|
-
if (event.agentId) printInfo(" Agent", event.agentId.slice(0, 8) + "...");
|
|
591
|
-
if (event.filePath) printInfo(" File", event.filePath);
|
|
592
|
-
if (event.proposalId) printInfo(" Proposal", event.proposalId.slice(0, 8) + "...");
|
|
593
|
-
if (event.reason) printInfo(" Reason", event.reason);
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
console.log();
|
|
598
|
-
return { exitCode: EXIT.OK, history };
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
* Clean up stale state
|
|
603
|
-
*/
|
|
604
|
-
async function runCleanup(options) {
|
|
605
|
-
const conductor = new Conductor(options.projectPath || process.cwd());
|
|
606
|
-
await conductor.load();
|
|
607
|
-
|
|
608
|
-
const result = await conductor.cleanup();
|
|
609
|
-
|
|
610
|
-
if (options.json) {
|
|
611
|
-
console.log(JSON.stringify(result, null, 2));
|
|
612
|
-
return { exitCode: EXIT.OK, result };
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
printHeader("Cleanup Complete", ICONS.sparkle);
|
|
616
|
-
printInfo("Stale locks removed", result.locks);
|
|
617
|
-
printInfo("Inactive agents marked", result.agents);
|
|
618
|
-
|
|
619
|
-
console.log();
|
|
620
|
-
return { exitCode: EXIT.OK, result };
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
624
|
-
// MAIN ENTRY POINT
|
|
625
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
626
|
-
|
|
627
|
-
/**
|
|
628
|
-
* Main conductor command router
|
|
629
|
-
*/
|
|
630
|
-
async function runConductor(args = [], options = {}) {
|
|
631
|
-
const globalFlags = parseGlobalFlags(args);
|
|
632
|
-
const mergedOptions = { ...options, ...globalFlags };
|
|
633
|
-
|
|
634
|
-
// Get subcommand from args
|
|
635
|
-
const subcommand = (mergedOptions._ && mergedOptions._[0]) || args[0] || "status";
|
|
636
|
-
|
|
637
|
-
// Remove subcommand from positional args
|
|
638
|
-
if (mergedOptions._ && mergedOptions._[0] === subcommand) {
|
|
639
|
-
mergedOptions._ = mergedOptions._.slice(1);
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
// Route to appropriate subcommand
|
|
643
|
-
const commands = {
|
|
644
|
-
status: runStatus,
|
|
645
|
-
register: runRegister,
|
|
646
|
-
unregister: runUnregister,
|
|
647
|
-
lock: runLock,
|
|
648
|
-
unlock: runUnlock,
|
|
649
|
-
propose: runPropose,
|
|
650
|
-
proposals: runProposals,
|
|
651
|
-
agents: runAgents,
|
|
652
|
-
locks: runLocks,
|
|
653
|
-
history: runHistory,
|
|
654
|
-
cleanup: runCleanup,
|
|
655
|
-
help: () => runHelp(mergedOptions)
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
const handler = commands[subcommand];
|
|
659
|
-
|
|
660
|
-
if (!handler) {
|
|
661
|
-
printError(`Unknown subcommand: ${subcommand}`);
|
|
662
|
-
console.log();
|
|
663
|
-
console.log(`${c.dim}Available commands: ${Object.keys(commands).join(", ")}${c.reset}`);
|
|
664
|
-
console.log();
|
|
665
|
-
return { exitCode: EXIT.ERROR };
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
try {
|
|
669
|
-
return await handler(mergedOptions);
|
|
670
|
-
} catch (error) {
|
|
671
|
-
printError(`Error: ${error.message}`);
|
|
672
|
-
if (mergedOptions.debug) {
|
|
673
|
-
console.error(error.stack);
|
|
674
|
-
}
|
|
675
|
-
return { exitCode: EXIT.ERROR, error: error.message };
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
/**
|
|
680
|
-
* Show help
|
|
681
|
-
*/
|
|
682
|
-
function runHelp(options) {
|
|
683
|
-
if (!options.json) {
|
|
684
|
-
printBanner();
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
const help = {
|
|
688
|
-
name: "conductor",
|
|
689
|
-
description: "Multi-agent coordination for AI assistants",
|
|
690
|
-
commands: {
|
|
691
|
-
status: "Show coordination status overview",
|
|
692
|
-
register: "Register a new agent (--name, --type)",
|
|
693
|
-
unregister: "Unregister an agent (--agent-id)",
|
|
694
|
-
lock: "Acquire a file lock (--agent-id, --file, --reason)",
|
|
695
|
-
unlock: "Release a file lock (--agent-id, --file)",
|
|
696
|
-
propose: "Submit a change proposal (--agent-id, --description, --files)",
|
|
697
|
-
proposals: "List proposals (--status, --conflicts)",
|
|
698
|
-
agents: "List registered agents (--active)",
|
|
699
|
-
locks: "List active file locks",
|
|
700
|
-
history: "Show recent events (--limit)",
|
|
701
|
-
cleanup: "Clean up stale locks and agents"
|
|
702
|
-
},
|
|
703
|
-
examples: [
|
|
704
|
-
"vibecheck conductor status",
|
|
705
|
-
"vibecheck conductor register --name cursor-agent --type ai-assistant",
|
|
706
|
-
"vibecheck conductor lock --agent-id <id> --file src/app.ts --reason 'adding feature'",
|
|
707
|
-
"vibecheck conductor propose --agent-id <id> --description 'Add auth' --files 'src/auth.ts,src/middleware.ts'",
|
|
708
|
-
"vibecheck conductor proposals --status conflict"
|
|
709
|
-
]
|
|
710
|
-
};
|
|
711
|
-
|
|
712
|
-
if (options.json) {
|
|
713
|
-
console.log(JSON.stringify(help, null, 2));
|
|
714
|
-
return { exitCode: EXIT.OK };
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
console.log(`${c.bold}Commands:${c.reset}`);
|
|
718
|
-
for (const [cmd, desc] of Object.entries(help.commands)) {
|
|
719
|
-
console.log(` ${colors.primary}${cmd.padEnd(14)}${c.reset} ${desc}`);
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
console.log();
|
|
723
|
-
console.log(`${c.bold}Examples:${c.reset}`);
|
|
724
|
-
for (const example of help.examples) {
|
|
725
|
-
console.log(` ${c.dim}$${c.reset} ${example}`);
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
console.log();
|
|
729
|
-
return { exitCode: EXIT.OK };
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
// Named exports for registry
|
|
733
|
-
async function runConductorStatus(args = [], options = {}) {
|
|
734
|
-
return runStatus({ ...options, _: args });
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
async function runConductorRegister(args = [], options = {}) {
|
|
738
|
-
return runRegister({ ...options, _: args });
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
async function runConductorLock(args = [], options = {}) {
|
|
742
|
-
return runLock({ ...options, _: args });
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
async function runConductorUnlock(args = [], options = {}) {
|
|
746
|
-
return runUnlock({ ...options, _: args });
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
async function runConductorPropose(args = [], options = {}) {
|
|
750
|
-
return runPropose({ ...options, _: args });
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
module.exports = {
|
|
754
|
-
runConductor,
|
|
755
|
-
runStatus,
|
|
756
|
-
runRegister,
|
|
757
|
-
runUnregister,
|
|
758
|
-
runLock,
|
|
759
|
-
runUnlock,
|
|
760
|
-
runPropose,
|
|
761
|
-
runProposals,
|
|
762
|
-
runAgents,
|
|
763
|
-
runLocks,
|
|
764
|
-
runHistory,
|
|
765
|
-
runCleanup,
|
|
766
|
-
// Registry exports
|
|
767
|
-
runConductorStatus,
|
|
768
|
-
runConductorRegister,
|
|
769
|
-
runConductorLock,
|
|
770
|
-
runConductorUnlock,
|
|
771
|
-
runConductorPropose,
|
|
772
|
-
};
|