@agile-vibe-coding/avc 0.1.0 → 0.2.3
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/README.md +2 -0
- package/cli/agent-loader.js +21 -0
- package/cli/agents/agent-selector.md +129 -0
- package/cli/agents/architecture-recommender.md +418 -0
- package/cli/agents/database-deep-dive.md +470 -0
- package/cli/agents/database-recommender.md +634 -0
- package/cli/agents/doc-distributor.md +176 -0
- package/cli/agents/documentation-updater.md +203 -0
- package/cli/agents/epic-story-decomposer.md +280 -0
- package/cli/agents/feature-context-generator.md +91 -0
- package/cli/agents/gap-checker-epic.md +52 -0
- package/cli/agents/impact-checker-story.md +51 -0
- package/cli/agents/migration-guide-generator.md +305 -0
- package/cli/agents/mission-scope-generator.md +79 -0
- package/cli/agents/mission-scope-validator.md +112 -0
- package/cli/agents/project-context-extractor.md +107 -0
- package/cli/agents/project-documentation-creator.json +226 -0
- package/cli/agents/project-documentation-creator.md +595 -0
- package/cli/agents/question-prefiller.md +269 -0
- package/cli/agents/refiner-epic.md +39 -0
- package/cli/agents/refiner-story.md +42 -0
- package/cli/agents/solver-epic-api.json +15 -0
- package/cli/agents/solver-epic-api.md +39 -0
- package/cli/agents/solver-epic-backend.json +15 -0
- package/cli/agents/solver-epic-backend.md +39 -0
- package/cli/agents/solver-epic-cloud.json +15 -0
- package/cli/agents/solver-epic-cloud.md +39 -0
- package/cli/agents/solver-epic-data.json +15 -0
- package/cli/agents/solver-epic-data.md +39 -0
- package/cli/agents/solver-epic-database.json +15 -0
- package/cli/agents/solver-epic-database.md +39 -0
- package/cli/agents/solver-epic-developer.json +15 -0
- package/cli/agents/solver-epic-developer.md +39 -0
- package/cli/agents/solver-epic-devops.json +15 -0
- package/cli/agents/solver-epic-devops.md +39 -0
- package/cli/agents/solver-epic-frontend.json +15 -0
- package/cli/agents/solver-epic-frontend.md +39 -0
- package/cli/agents/solver-epic-mobile.json +15 -0
- package/cli/agents/solver-epic-mobile.md +39 -0
- package/cli/agents/solver-epic-qa.json +15 -0
- package/cli/agents/solver-epic-qa.md +39 -0
- package/cli/agents/solver-epic-security.json +15 -0
- package/cli/agents/solver-epic-security.md +39 -0
- package/cli/agents/solver-epic-solution-architect.json +15 -0
- package/cli/agents/solver-epic-solution-architect.md +39 -0
- package/cli/agents/solver-epic-test-architect.json +15 -0
- package/cli/agents/solver-epic-test-architect.md +39 -0
- package/cli/agents/solver-epic-ui.json +15 -0
- package/cli/agents/solver-epic-ui.md +39 -0
- package/cli/agents/solver-epic-ux.json +15 -0
- package/cli/agents/solver-epic-ux.md +39 -0
- package/cli/agents/solver-story-api.json +15 -0
- package/cli/agents/solver-story-api.md +39 -0
- package/cli/agents/solver-story-backend.json +15 -0
- package/cli/agents/solver-story-backend.md +39 -0
- package/cli/agents/solver-story-cloud.json +15 -0
- package/cli/agents/solver-story-cloud.md +39 -0
- package/cli/agents/solver-story-data.json +15 -0
- package/cli/agents/solver-story-data.md +39 -0
- package/cli/agents/solver-story-database.json +15 -0
- package/cli/agents/solver-story-database.md +39 -0
- package/cli/agents/solver-story-developer.json +15 -0
- package/cli/agents/solver-story-developer.md +39 -0
- package/cli/agents/solver-story-devops.json +15 -0
- package/cli/agents/solver-story-devops.md +39 -0
- package/cli/agents/solver-story-frontend.json +15 -0
- package/cli/agents/solver-story-frontend.md +39 -0
- package/cli/agents/solver-story-mobile.json +15 -0
- package/cli/agents/solver-story-mobile.md +39 -0
- package/cli/agents/solver-story-qa.json +15 -0
- package/cli/agents/solver-story-qa.md +39 -0
- package/cli/agents/solver-story-security.json +15 -0
- package/cli/agents/solver-story-security.md +39 -0
- package/cli/agents/solver-story-solution-architect.json +15 -0
- package/cli/agents/solver-story-solution-architect.md +39 -0
- package/cli/agents/solver-story-test-architect.json +15 -0
- package/cli/agents/solver-story-test-architect.md +39 -0
- package/cli/agents/solver-story-ui.json +15 -0
- package/cli/agents/solver-story-ui.md +39 -0
- package/cli/agents/solver-story-ux.json +15 -0
- package/cli/agents/solver-story-ux.md +39 -0
- package/cli/agents/story-doc-enricher.md +133 -0
- package/cli/agents/suggestion-business-analyst.md +88 -0
- package/cli/agents/suggestion-deployment-architect.md +263 -0
- package/cli/agents/suggestion-product-manager.md +129 -0
- package/cli/agents/suggestion-security-specialist.md +156 -0
- package/cli/agents/suggestion-technical-architect.md +269 -0
- package/cli/agents/suggestion-ux-researcher.md +93 -0
- package/cli/agents/task-subtask-decomposer.md +188 -0
- package/cli/agents/validator-documentation.json +152 -0
- package/cli/agents/validator-documentation.md +453 -0
- package/cli/agents/validator-epic-api.json +93 -0
- package/cli/agents/validator-epic-api.md +137 -0
- package/cli/agents/validator-epic-backend.json +93 -0
- package/cli/agents/validator-epic-backend.md +130 -0
- package/cli/agents/validator-epic-cloud.json +93 -0
- package/cli/agents/validator-epic-cloud.md +137 -0
- package/cli/agents/validator-epic-data.json +93 -0
- package/cli/agents/validator-epic-data.md +130 -0
- package/cli/agents/validator-epic-database.json +93 -0
- package/cli/agents/validator-epic-database.md +137 -0
- package/cli/agents/validator-epic-developer.json +74 -0
- package/cli/agents/validator-epic-developer.md +153 -0
- package/cli/agents/validator-epic-devops.json +74 -0
- package/cli/agents/validator-epic-devops.md +153 -0
- package/cli/agents/validator-epic-frontend.json +74 -0
- package/cli/agents/validator-epic-frontend.md +153 -0
- package/cli/agents/validator-epic-mobile.json +93 -0
- package/cli/agents/validator-epic-mobile.md +130 -0
- package/cli/agents/validator-epic-qa.json +93 -0
- package/cli/agents/validator-epic-qa.md +130 -0
- package/cli/agents/validator-epic-security.json +74 -0
- package/cli/agents/validator-epic-security.md +154 -0
- package/cli/agents/validator-epic-solution-architect.json +74 -0
- package/cli/agents/validator-epic-solution-architect.md +156 -0
- package/cli/agents/validator-epic-test-architect.json +93 -0
- package/cli/agents/validator-epic-test-architect.md +130 -0
- package/cli/agents/validator-epic-ui.json +93 -0
- package/cli/agents/validator-epic-ui.md +130 -0
- package/cli/agents/validator-epic-ux.json +93 -0
- package/cli/agents/validator-epic-ux.md +130 -0
- package/cli/agents/validator-selector.md +211 -0
- package/cli/agents/validator-story-api.json +104 -0
- package/cli/agents/validator-story-api.md +152 -0
- package/cli/agents/validator-story-backend.json +104 -0
- package/cli/agents/validator-story-backend.md +152 -0
- package/cli/agents/validator-story-cloud.json +104 -0
- package/cli/agents/validator-story-cloud.md +152 -0
- package/cli/agents/validator-story-data.json +104 -0
- package/cli/agents/validator-story-data.md +152 -0
- package/cli/agents/validator-story-database.json +104 -0
- package/cli/agents/validator-story-database.md +152 -0
- package/cli/agents/validator-story-developer.json +104 -0
- package/cli/agents/validator-story-developer.md +152 -0
- package/cli/agents/validator-story-devops.json +104 -0
- package/cli/agents/validator-story-devops.md +152 -0
- package/cli/agents/validator-story-frontend.json +104 -0
- package/cli/agents/validator-story-frontend.md +152 -0
- package/cli/agents/validator-story-mobile.json +104 -0
- package/cli/agents/validator-story-mobile.md +152 -0
- package/cli/agents/validator-story-qa.json +104 -0
- package/cli/agents/validator-story-qa.md +152 -0
- package/cli/agents/validator-story-security.json +104 -0
- package/cli/agents/validator-story-security.md +152 -0
- package/cli/agents/validator-story-solution-architect.json +104 -0
- package/cli/agents/validator-story-solution-architect.md +152 -0
- package/cli/agents/validator-story-test-architect.json +104 -0
- package/cli/agents/validator-story-test-architect.md +152 -0
- package/cli/agents/validator-story-ui.json +104 -0
- package/cli/agents/validator-story-ui.md +152 -0
- package/cli/agents/validator-story-ux.json +104 -0
- package/cli/agents/validator-story-ux.md +152 -0
- package/cli/ansi-colors.js +21 -0
- package/cli/build-docs.js +298 -0
- package/cli/ceremony-history.js +369 -0
- package/cli/command-logger.js +245 -0
- package/cli/components/static-output.js +63 -0
- package/cli/console-output-manager.js +94 -0
- package/cli/docs-sync.js +306 -0
- package/cli/epic-story-validator.js +1174 -0
- package/cli/evaluation-prompts.js +1008 -0
- package/cli/execution-context.js +195 -0
- package/cli/generate-summary-table.js +340 -0
- package/cli/index.js +3 -25
- package/cli/init-model-config.js +697 -0
- package/cli/init.js +1765 -100
- package/cli/kanban-server-manager.js +228 -0
- package/cli/llm-claude.js +109 -0
- package/cli/llm-gemini.js +115 -0
- package/cli/llm-mock.js +233 -0
- package/cli/llm-openai.js +233 -0
- package/cli/llm-provider.js +300 -0
- package/cli/llm-token-limits.js +102 -0
- package/cli/llm-verifier.js +454 -0
- package/cli/logger.js +32 -5
- package/cli/message-constants.js +58 -0
- package/cli/message-manager.js +334 -0
- package/cli/message-types.js +96 -0
- package/cli/messaging-api.js +297 -0
- package/cli/model-pricing.js +169 -0
- package/cli/model-query-engine.js +468 -0
- package/cli/model-recommendation-analyzer.js +495 -0
- package/cli/model-selector.js +269 -0
- package/cli/output-buffer.js +107 -0
- package/cli/process-manager.js +332 -0
- package/cli/repl-ink.js +5840 -504
- package/cli/repl-old.js +4 -4
- package/cli/seed-processor.js +792 -0
- package/cli/sprint-planning-processor.js +1813 -0
- package/cli/template-processor.js +2306 -108
- package/cli/templates/project.md +25 -8
- package/cli/templates/vitepress-config.mts.template +34 -0
- package/cli/token-tracker.js +520 -0
- package/cli/tools/generate-story-validators.js +317 -0
- package/cli/tools/generate-validators.js +669 -0
- package/cli/update-checker.js +19 -17
- package/cli/update-notifier.js +4 -4
- package/cli/validation-router.js +605 -0
- package/cli/verification-tracker.js +563 -0
- package/kanban/README.md +386 -0
- package/kanban/client/README.md +205 -0
- package/kanban/client/components.json +20 -0
- package/kanban/client/dist/assets/index-CiD8PS2e.js +306 -0
- package/kanban/client/dist/assets/index-nLh0m82Q.css +1 -0
- package/kanban/client/dist/index.html +16 -0
- package/kanban/client/dist/vite.svg +1 -0
- package/kanban/client/index.html +15 -0
- package/kanban/client/package-lock.json +9442 -0
- package/kanban/client/package.json +44 -0
- package/kanban/client/postcss.config.js +6 -0
- package/kanban/client/public/vite.svg +1 -0
- package/kanban/client/src/App.jsx +622 -0
- package/kanban/client/src/components/ProjectFileEditorPopup.jsx +117 -0
- package/kanban/client/src/components/ceremony/AskArchPopup.jsx +416 -0
- package/kanban/client/src/components/ceremony/AskModelPopup.jsx +616 -0
- package/kanban/client/src/components/ceremony/CeremonyWorkflowModal.jsx +946 -0
- package/kanban/client/src/components/ceremony/EpicStorySelectionModal.jsx +254 -0
- package/kanban/client/src/components/ceremony/SponsorCallModal.jsx +619 -0
- package/kanban/client/src/components/ceremony/SprintPlanningModal.jsx +704 -0
- package/kanban/client/src/components/ceremony/steps/ArchitectureStep.jsx +150 -0
- package/kanban/client/src/components/ceremony/steps/CompleteStep.jsx +154 -0
- package/kanban/client/src/components/ceremony/steps/DatabaseStep.jsx +202 -0
- package/kanban/client/src/components/ceremony/steps/DeploymentStep.jsx +123 -0
- package/kanban/client/src/components/ceremony/steps/MissionStep.jsx +106 -0
- package/kanban/client/src/components/ceremony/steps/ReviewAnswersStep.jsx +125 -0
- package/kanban/client/src/components/ceremony/steps/RunningStep.jsx +228 -0
- package/kanban/client/src/components/kanban/CardDetailModal.jsx +559 -0
- package/kanban/client/src/components/kanban/EpicSection.jsx +146 -0
- package/kanban/client/src/components/kanban/FilterToolbar.jsx +222 -0
- package/kanban/client/src/components/kanban/GroupingSelector.jsx +57 -0
- package/kanban/client/src/components/kanban/KanbanBoard.jsx +211 -0
- package/kanban/client/src/components/kanban/KanbanCard.jsx +138 -0
- package/kanban/client/src/components/kanban/KanbanColumn.jsx +90 -0
- package/kanban/client/src/components/kanban/RefineWorkItemPopup.jsx +789 -0
- package/kanban/client/src/components/layout/LoadingScreen.jsx +82 -0
- package/kanban/client/src/components/process/ProcessMonitorBar.jsx +80 -0
- package/kanban/client/src/components/settings/AgentEditorPopup.jsx +171 -0
- package/kanban/client/src/components/settings/AgentsTab.jsx +353 -0
- package/kanban/client/src/components/settings/ApiKeysTab.jsx +113 -0
- package/kanban/client/src/components/settings/CeremonyModelsTab.jsx +98 -0
- package/kanban/client/src/components/settings/CostThresholdsTab.jsx +94 -0
- package/kanban/client/src/components/settings/ModelPricingTab.jsx +204 -0
- package/kanban/client/src/components/settings/ServersTab.jsx +121 -0
- package/kanban/client/src/components/settings/SettingsModal.jsx +84 -0
- package/kanban/client/src/components/stats/CostModal.jsx +353 -0
- package/kanban/client/src/components/ui/badge.jsx +27 -0
- package/kanban/client/src/components/ui/dialog.jsx +121 -0
- package/kanban/client/src/components/ui/tabs.jsx +85 -0
- package/kanban/client/src/hooks/__tests__/useGrouping.test.js +232 -0
- package/kanban/client/src/hooks/useGrouping.js +118 -0
- package/kanban/client/src/hooks/useWebSocket.js +120 -0
- package/kanban/client/src/lib/__tests__/api.test.js +196 -0
- package/kanban/client/src/lib/__tests__/status-grouping.test.js +94 -0
- package/kanban/client/src/lib/api.js +401 -0
- package/kanban/client/src/lib/status-grouping.js +144 -0
- package/kanban/client/src/lib/utils.js +11 -0
- package/kanban/client/src/main.jsx +10 -0
- package/kanban/client/src/store/__tests__/kanbanStore.test.js +164 -0
- package/kanban/client/src/store/ceremonyStore.js +172 -0
- package/kanban/client/src/store/filterStore.js +201 -0
- package/kanban/client/src/store/kanbanStore.js +115 -0
- package/kanban/client/src/store/processStore.js +65 -0
- package/kanban/client/src/store/sprintPlanningStore.js +33 -0
- package/kanban/client/src/styles/globals.css +59 -0
- package/kanban/client/tailwind.config.js +77 -0
- package/kanban/client/vite.config.js +28 -0
- package/kanban/client/vitest.config.js +28 -0
- package/kanban/dev-start.sh +47 -0
- package/kanban/package.json +12 -0
- package/kanban/server/index.js +516 -0
- package/kanban/server/routes/ceremony.js +305 -0
- package/kanban/server/routes/costs.js +157 -0
- package/kanban/server/routes/processes.js +50 -0
- package/kanban/server/routes/settings.js +303 -0
- package/kanban/server/routes/websocket.js +276 -0
- package/kanban/server/routes/work-items.js +347 -0
- package/kanban/server/services/CeremonyService.js +1190 -0
- package/kanban/server/services/FileSystemScanner.js +95 -0
- package/kanban/server/services/FileWatcher.js +144 -0
- package/kanban/server/services/HierarchyBuilder.js +196 -0
- package/kanban/server/services/ProcessRegistry.js +122 -0
- package/kanban/server/services/WorkItemReader.js +123 -0
- package/kanban/server/services/WorkItemRefineService.js +510 -0
- package/kanban/server/start.js +49 -0
- package/kanban/server/utils/kanban-logger.js +132 -0
- package/kanban/server/utils/markdown.js +91 -0
- package/kanban/server/utils/status-grouping.js +107 -0
- package/kanban/server/workers/sponsor-call-worker.js +84 -0
- package/kanban/server/workers/sprint-planning-worker.js +130 -0
- package/package.json +34 -7
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageManager - Centralized message handling system
|
|
3
|
+
*
|
|
4
|
+
* Singleton that manages all console output through execution contexts.
|
|
5
|
+
* Prevents ghost messages by tracking command lifecycle and cancelling
|
|
6
|
+
* messages from previous runs.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { MessageType } from './message-types.js';
|
|
10
|
+
import { ExecutionContext } from './execution-context.js';
|
|
11
|
+
import { outputBuffer } from './output-buffer.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* MessageManager singleton class
|
|
15
|
+
*/
|
|
16
|
+
class MessageManager {
|
|
17
|
+
constructor() {
|
|
18
|
+
if (MessageManager.instance) {
|
|
19
|
+
return MessageManager.instance;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
this.currentContext = null;
|
|
23
|
+
this.contextHistory = [];
|
|
24
|
+
this.maxHistorySize = 10;
|
|
25
|
+
this.executingMessageCallback = null;
|
|
26
|
+
this.executingSubstepCallback = null;
|
|
27
|
+
|
|
28
|
+
MessageManager.instance = this;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Set executing message callback (from React state setter)
|
|
33
|
+
* @param {Function} callback - setExecutingMessage function
|
|
34
|
+
*/
|
|
35
|
+
setExecutingMessageCallback(callback) {
|
|
36
|
+
this.executingMessageCallback = callback;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Set executing substep callback (from React state setter)
|
|
41
|
+
* @param {Function} callback - setExecutingSubstep function
|
|
42
|
+
*/
|
|
43
|
+
setExecutingSubstepCallback(callback) {
|
|
44
|
+
this.executingSubstepCallback = callback;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Start a new execution context for a command
|
|
49
|
+
* @param {string} commandName - Name of the command
|
|
50
|
+
* @returns {ExecutionContext} New execution context
|
|
51
|
+
*/
|
|
52
|
+
startExecution(commandName) {
|
|
53
|
+
// Cancel previous context if active
|
|
54
|
+
if (this.currentContext && this.currentContext.isActive()) {
|
|
55
|
+
this.currentContext.cancel();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Create new context
|
|
59
|
+
this.currentContext = new ExecutionContext(commandName);
|
|
60
|
+
|
|
61
|
+
// Add to history
|
|
62
|
+
this.contextHistory.push(this.currentContext);
|
|
63
|
+
if (this.contextHistory.length > this.maxHistorySize) {
|
|
64
|
+
this.contextHistory.shift();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Insert visual separator between commands in the Static output
|
|
68
|
+
outputBuffer.clear();
|
|
69
|
+
|
|
70
|
+
return this.currentContext;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* End the current execution context
|
|
75
|
+
*/
|
|
76
|
+
endExecution() {
|
|
77
|
+
if (this.currentContext) {
|
|
78
|
+
this.currentContext.complete();
|
|
79
|
+
this.currentContext = null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Clear progress indicators
|
|
83
|
+
if (this.executingMessageCallback) {
|
|
84
|
+
this.executingMessageCallback('');
|
|
85
|
+
}
|
|
86
|
+
if (this.executingSubstepCallback) {
|
|
87
|
+
this.executingSubstepCallback('');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Cancel the current execution context
|
|
93
|
+
*/
|
|
94
|
+
cancelExecution() {
|
|
95
|
+
if (this.currentContext) {
|
|
96
|
+
this.currentContext.cancel();
|
|
97
|
+
this.currentContext = null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Clear progress indicators
|
|
101
|
+
if (this.executingMessageCallback) {
|
|
102
|
+
this.executingMessageCallback('');
|
|
103
|
+
}
|
|
104
|
+
if (this.executingSubstepCallback) {
|
|
105
|
+
this.executingSubstepCallback('');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get current execution context
|
|
111
|
+
* @returns {ExecutionContext|null} Current context or null
|
|
112
|
+
*/
|
|
113
|
+
getCurrentContext() {
|
|
114
|
+
return this.currentContext;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Send a message through the current context
|
|
119
|
+
* @param {string} type - MessageType
|
|
120
|
+
* @param {string} content - Message content
|
|
121
|
+
* @param {Object} options - Additional options
|
|
122
|
+
*/
|
|
123
|
+
send(type, content, options = {}) {
|
|
124
|
+
// Validate message type
|
|
125
|
+
if (!Object.values(MessageType).includes(type)) {
|
|
126
|
+
console.error(`Invalid message type: ${type}`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Ignore if no active context
|
|
131
|
+
if (!this.currentContext || !this.currentContext.isActive()) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Handle different message types
|
|
136
|
+
switch (type) {
|
|
137
|
+
case MessageType.COMMAND_START:
|
|
138
|
+
this._handleCommandStart(content);
|
|
139
|
+
break;
|
|
140
|
+
|
|
141
|
+
case MessageType.CEREMONY_HEADER:
|
|
142
|
+
this._handleCeremonyHeader(content);
|
|
143
|
+
break;
|
|
144
|
+
|
|
145
|
+
case MessageType.PROGRESS:
|
|
146
|
+
this._handleProgress(content);
|
|
147
|
+
break;
|
|
148
|
+
|
|
149
|
+
case MessageType.SUBSTEP:
|
|
150
|
+
this._handleSubstep(content);
|
|
151
|
+
break;
|
|
152
|
+
|
|
153
|
+
case MessageType.USER_OUTPUT:
|
|
154
|
+
this._handleUserOutput(content);
|
|
155
|
+
break;
|
|
156
|
+
|
|
157
|
+
case MessageType.ERROR:
|
|
158
|
+
this._handleError(content);
|
|
159
|
+
break;
|
|
160
|
+
|
|
161
|
+
case MessageType.WARNING:
|
|
162
|
+
this._handleWarning(content);
|
|
163
|
+
break;
|
|
164
|
+
|
|
165
|
+
case MessageType.SUCCESS:
|
|
166
|
+
this._handleSuccess(content);
|
|
167
|
+
break;
|
|
168
|
+
|
|
169
|
+
case MessageType.INFO:
|
|
170
|
+
this._handleInfo(content);
|
|
171
|
+
break;
|
|
172
|
+
|
|
173
|
+
case MessageType.DEBUG:
|
|
174
|
+
this._handleDebug(content, options);
|
|
175
|
+
break;
|
|
176
|
+
|
|
177
|
+
default:
|
|
178
|
+
this._handleUserOutput(content);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Handle COMMAND_START message
|
|
184
|
+
* @private
|
|
185
|
+
*/
|
|
186
|
+
_handleCommandStart(content) {
|
|
187
|
+
// Clear output buffer (already done in startExecution)
|
|
188
|
+
// This is a marker message type, no output needed
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Handle CEREMONY_HEADER message
|
|
193
|
+
* @private
|
|
194
|
+
*/
|
|
195
|
+
_handleCeremonyHeader(content) {
|
|
196
|
+
outputBuffer.append(content);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Handle PROGRESS message
|
|
201
|
+
* @private
|
|
202
|
+
*/
|
|
203
|
+
_handleProgress(content) {
|
|
204
|
+
if (this.currentContext) {
|
|
205
|
+
this.currentContext.setExecutingMessage(content);
|
|
206
|
+
}
|
|
207
|
+
if (this.executingMessageCallback) {
|
|
208
|
+
this.executingMessageCallback(content);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Handle SUBSTEP message
|
|
214
|
+
* @private
|
|
215
|
+
*/
|
|
216
|
+
_handleSubstep(content) {
|
|
217
|
+
if (this.currentContext) {
|
|
218
|
+
this.currentContext.setExecutingSubstep(content);
|
|
219
|
+
}
|
|
220
|
+
if (this.executingSubstepCallback) {
|
|
221
|
+
this.executingSubstepCallback(content);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Handle USER_OUTPUT message
|
|
227
|
+
* @private
|
|
228
|
+
*/
|
|
229
|
+
_handleUserOutput(content) {
|
|
230
|
+
// Empty string means "blank line" — outputBuffer ignores falsy values,
|
|
231
|
+
// so convert '' to '\n' to produce the intended visual gap.
|
|
232
|
+
outputBuffer.append(content === '' ? '\n' : content);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Handle ERROR message
|
|
237
|
+
* @private
|
|
238
|
+
*/
|
|
239
|
+
_handleError(content) {
|
|
240
|
+
outputBuffer.append(`ERROR: ${content}`, 'ERROR');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Handle WARNING message
|
|
245
|
+
* @private
|
|
246
|
+
*/
|
|
247
|
+
_handleWarning(content) {
|
|
248
|
+
outputBuffer.append(`WARNING: ${content}`, 'WARNING');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Handle SUCCESS message
|
|
253
|
+
* @private
|
|
254
|
+
*/
|
|
255
|
+
_handleSuccess(content) {
|
|
256
|
+
outputBuffer.append(`SUCCESS: ${content}`, 'SUCCESS');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Handle INFO message
|
|
261
|
+
* @private
|
|
262
|
+
*/
|
|
263
|
+
_handleInfo(content) {
|
|
264
|
+
outputBuffer.append(`INFO: ${content}`, 'INFO');
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Handle DEBUG message
|
|
269
|
+
* @private
|
|
270
|
+
*/
|
|
271
|
+
_handleDebug(content, options = {}) {
|
|
272
|
+
// Debug messages only go to console.log, not main output
|
|
273
|
+
const timestamp = new Date().toISOString();
|
|
274
|
+
if (options.data) {
|
|
275
|
+
console.log(`[DEBUG][${timestamp}] ${content}`, JSON.stringify(options.data, null, 2));
|
|
276
|
+
} else {
|
|
277
|
+
console.log(`[DEBUG][${timestamp}] ${content}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Clear progress indicators
|
|
283
|
+
*/
|
|
284
|
+
clearProgress() {
|
|
285
|
+
if (this.currentContext) {
|
|
286
|
+
this.currentContext.clearExecutingMessage();
|
|
287
|
+
this.currentContext.clearExecutingSubstep();
|
|
288
|
+
}
|
|
289
|
+
if (this.executingMessageCallback) {
|
|
290
|
+
this.executingMessageCallback('');
|
|
291
|
+
}
|
|
292
|
+
if (this.executingSubstepCallback) {
|
|
293
|
+
this.executingSubstepCallback('');
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Get execution context history
|
|
299
|
+
* @returns {Array} Array of execution contexts
|
|
300
|
+
*/
|
|
301
|
+
getHistory() {
|
|
302
|
+
return [...this.contextHistory];
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Get manager state for debugging
|
|
307
|
+
* @returns {Object} Manager state
|
|
308
|
+
*/
|
|
309
|
+
toJSON() {
|
|
310
|
+
return {
|
|
311
|
+
hasCurrentContext: !!this.currentContext,
|
|
312
|
+
currentContext: this.currentContext ? this.currentContext.toJSON() : null,
|
|
313
|
+
historySize: this.contextHistory.length,
|
|
314
|
+
hasCallbacks: {
|
|
315
|
+
executingMessage: !!this.executingMessageCallback,
|
|
316
|
+
executingSubstep: !!this.executingSubstepCallback
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Reset manager (for testing)
|
|
323
|
+
*/
|
|
324
|
+
reset() {
|
|
325
|
+
if (this.currentContext) {
|
|
326
|
+
this.currentContext.cancel();
|
|
327
|
+
}
|
|
328
|
+
this.currentContext = null;
|
|
329
|
+
this.contextHistory = [];
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Export singleton instance
|
|
334
|
+
export const messageManager = new MessageManager();
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message Types for MessageManager
|
|
3
|
+
*
|
|
4
|
+
* Defines different types of messages that can be sent through the messaging system.
|
|
5
|
+
* Each type can be handled differently (formatting, logging, display).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const MessageType = {
|
|
9
|
+
/**
|
|
10
|
+
* Command start - marks the beginning of a command execution
|
|
11
|
+
* Typically clears the output buffer
|
|
12
|
+
*/
|
|
13
|
+
COMMAND_START: 'COMMAND_START',
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Ceremony header - displays ceremony title and documentation URL
|
|
17
|
+
* Format: 🎯 Title\n📖 URL
|
|
18
|
+
*/
|
|
19
|
+
CEREMONY_HEADER: 'CEREMONY_HEADER',
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Progress indicator - shows ongoing operation status
|
|
23
|
+
* These go to executingMessage state, not main output
|
|
24
|
+
*/
|
|
25
|
+
PROGRESS: 'PROGRESS',
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Substep progress - shows detailed progress within an operation
|
|
29
|
+
* These go to executingSubstep state, not main output
|
|
30
|
+
*/
|
|
31
|
+
SUBSTEP: 'SUBSTEP',
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* User output - main content shown to user
|
|
35
|
+
* Standard output messages
|
|
36
|
+
*/
|
|
37
|
+
USER_OUTPUT: 'USER_OUTPUT',
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Error message - displays errors to user
|
|
41
|
+
* Automatically formatted with ERROR: prefix in red bold
|
|
42
|
+
*/
|
|
43
|
+
ERROR: 'ERROR',
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Warning message - displays warnings to user
|
|
47
|
+
* Automatically formatted with WARNING: prefix in yellow bold
|
|
48
|
+
*/
|
|
49
|
+
WARNING: 'WARNING',
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Success message - displays success confirmation
|
|
53
|
+
* Automatically formatted with SUCCESS: prefix in green bold
|
|
54
|
+
*/
|
|
55
|
+
SUCCESS: 'SUCCESS',
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Debug message - development/troubleshooting info
|
|
59
|
+
* Not shown in main output, only console.log
|
|
60
|
+
*/
|
|
61
|
+
DEBUG: 'DEBUG',
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Info message - informational content
|
|
65
|
+
* Automatically formatted with INFO: prefix in cyan
|
|
66
|
+
*/
|
|
67
|
+
INFO: 'INFO'
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check if a message type is valid
|
|
72
|
+
* @param {string} type - Message type to validate
|
|
73
|
+
* @returns {boolean} True if valid
|
|
74
|
+
*/
|
|
75
|
+
export function isValidMessageType(type) {
|
|
76
|
+
return Object.values(MessageType).includes(type);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get default formatting for a message type
|
|
81
|
+
* @param {string} type - Message type
|
|
82
|
+
* @returns {object} Format configuration with prefix, color, and bold flag
|
|
83
|
+
*/
|
|
84
|
+
export function getMessageFormat(type) {
|
|
85
|
+
const formats = {
|
|
86
|
+
[MessageType.ERROR]: { prefix: 'ERROR: ', color: 'red', bold: true },
|
|
87
|
+
[MessageType.WARNING]: { prefix: 'WARNING: ', color: 'yellow', bold: true },
|
|
88
|
+
[MessageType.SUCCESS]: { prefix: 'SUCCESS: ', color: 'green', bold: true },
|
|
89
|
+
[MessageType.INFO]: { prefix: 'INFO: ', color: 'cyan', bold: false },
|
|
90
|
+
[MessageType.CEREMONY_HEADER]: { prefix: '', color: 'cyan', bold: true },
|
|
91
|
+
[MessageType.USER_OUTPUT]: { prefix: '', color: 'white', bold: false },
|
|
92
|
+
[MessageType.DEBUG]: { prefix: '[DEBUG] ', color: 'gray', bold: false }
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return formats[type] || { prefix: '', color: 'white', bold: false };
|
|
96
|
+
}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Messaging API - Simple interface for command message handling
|
|
3
|
+
*
|
|
4
|
+
* Provides convenient methods for commands to send messages through
|
|
5
|
+
* the MessageManager without directly importing it.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { messageManager } from './message-manager.js';
|
|
9
|
+
import { MessageType } from './message-types.js';
|
|
10
|
+
import { boldCyan, gray, cyan } from './ansi-colors.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Track sent ceremony headers to prevent duplication
|
|
14
|
+
* Cleared on each startCommand() call
|
|
15
|
+
*/
|
|
16
|
+
let ceremonySent = new Set();
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Start a new command execution context
|
|
20
|
+
* Should be called at the beginning of every command
|
|
21
|
+
*
|
|
22
|
+
* @param {string} commandName - Name of the command (e.g., 'sponsor-call')
|
|
23
|
+
* @returns {ExecutionContext} New execution context
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* import { startCommand, endCommand } from './messaging-api.js';
|
|
27
|
+
*
|
|
28
|
+
* async function sponsorCallCommand() {
|
|
29
|
+
* startCommand('sponsor-call');
|
|
30
|
+
* try {
|
|
31
|
+
* // ... command logic
|
|
32
|
+
* } finally {
|
|
33
|
+
* endCommand();
|
|
34
|
+
* }
|
|
35
|
+
* }
|
|
36
|
+
*/
|
|
37
|
+
export function startCommand(commandName) {
|
|
38
|
+
// Clear ceremony header tracking for new command
|
|
39
|
+
ceremonySent.clear();
|
|
40
|
+
return messageManager.startExecution(commandName);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* End the current command execution context
|
|
45
|
+
* Should be called in finally block to ensure cleanup
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* try {
|
|
49
|
+
* // ... command logic
|
|
50
|
+
* } finally {
|
|
51
|
+
* endCommand();
|
|
52
|
+
* }
|
|
53
|
+
*/
|
|
54
|
+
export function endCommand() {
|
|
55
|
+
messageManager.endExecution();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Cancel the current command execution context
|
|
60
|
+
* Used when user interrupts or restarts command
|
|
61
|
+
*/
|
|
62
|
+
export function cancelCommand() {
|
|
63
|
+
messageManager.cancelExecution();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Send a ceremony header (title + documentation URL)
|
|
68
|
+
* Automatically prevents duplicate headers within same command execution
|
|
69
|
+
*
|
|
70
|
+
* @param {string} title - Ceremony title (without emoji)
|
|
71
|
+
* @param {string} url - Documentation URL
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* sendCeremonyHeader('Sponsor Call Ceremony', 'https://agilevibecoding.org/ceremonies/sponsor-call');
|
|
75
|
+
*/
|
|
76
|
+
export function sendCeremonyHeader(title, url) {
|
|
77
|
+
const key = `${title}|${url}`;
|
|
78
|
+
|
|
79
|
+
// Prevent duplicate ceremony headers
|
|
80
|
+
if (ceremonySent.has(key)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
ceremonySent.add(key);
|
|
85
|
+
const content = `${boldCyan(title)}\n${gray('Documentation:')} ${cyan(url)}`;
|
|
86
|
+
messageManager.send(MessageType.CEREMONY_HEADER, content);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Send a progress message (shows in executing state)
|
|
91
|
+
*
|
|
92
|
+
* @param {string} message - Progress message
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* sendProgress('Analyzing database requirements...');
|
|
96
|
+
*/
|
|
97
|
+
export function sendProgress(message) {
|
|
98
|
+
messageManager.send(MessageType.PROGRESS, message);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Send a substep message (detailed progress)
|
|
103
|
+
*
|
|
104
|
+
* @param {string} message - Substep message
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* sendSubstep('Calling Claude API...');
|
|
108
|
+
*/
|
|
109
|
+
export function sendSubstep(message) {
|
|
110
|
+
messageManager.send(MessageType.SUBSTEP, message);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Send user output (main content)
|
|
115
|
+
*
|
|
116
|
+
* @param {string} content - Content to display
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* sendOutput('Mission statement: Build a task manager\n');
|
|
120
|
+
*/
|
|
121
|
+
export function sendOutput(content) {
|
|
122
|
+
messageManager.send(MessageType.USER_OUTPUT, content);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Send an error message
|
|
127
|
+
*
|
|
128
|
+
* @param {string} message - Error message
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* sendError('Failed to load configuration file');
|
|
132
|
+
*/
|
|
133
|
+
export function sendError(message) {
|
|
134
|
+
messageManager.send(MessageType.ERROR, message);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Send a warning message
|
|
139
|
+
*
|
|
140
|
+
* @param {string} message - Warning message
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* sendWarning('API rate limit approaching');
|
|
144
|
+
*/
|
|
145
|
+
export function sendWarning(message) {
|
|
146
|
+
messageManager.send(MessageType.WARNING, message);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Send a success message
|
|
151
|
+
*
|
|
152
|
+
* @param {string} message - Success message
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* sendSuccess('Documentation generated successfully');
|
|
156
|
+
*/
|
|
157
|
+
export function sendSuccess(message) {
|
|
158
|
+
messageManager.send(MessageType.SUCCESS, message);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Send an info message
|
|
163
|
+
*
|
|
164
|
+
* @param {string} message - Info message
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* sendInfo('Using Claude provider for LLM operations');
|
|
168
|
+
*/
|
|
169
|
+
export function sendInfo(message) {
|
|
170
|
+
messageManager.send(MessageType.INFO, message);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Send a debug message (only to console.log)
|
|
175
|
+
*
|
|
176
|
+
* @param {string} message - Debug message
|
|
177
|
+
* @param {Object} data - Optional data to log
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* sendDebug('Processing questionnaire', { currentIndex: 2, total: 6 });
|
|
181
|
+
*/
|
|
182
|
+
export function sendDebug(message, data = null) {
|
|
183
|
+
messageManager.send(MessageType.DEBUG, message, { data });
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Clear progress indicators
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* clearProgress();
|
|
191
|
+
*/
|
|
192
|
+
export function clearProgress() {
|
|
193
|
+
messageManager.clearProgress();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Get current execution context
|
|
198
|
+
*
|
|
199
|
+
* @returns {ExecutionContext|null} Current context or null
|
|
200
|
+
*/
|
|
201
|
+
export function getCurrentContext() {
|
|
202
|
+
return messageManager.getCurrentContext();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Check if current context is active
|
|
207
|
+
*
|
|
208
|
+
* @returns {boolean} True if active context exists
|
|
209
|
+
*/
|
|
210
|
+
export function isContextActive() {
|
|
211
|
+
const context = messageManager.getCurrentContext();
|
|
212
|
+
return context ? context.isActive() : false;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Register callbacks from React state
|
|
217
|
+
* Called once during REPL initialization
|
|
218
|
+
*
|
|
219
|
+
* @param {Object} callbacks - Callback functions
|
|
220
|
+
* @param {Function} callbacks.setExecutingMessage - setExecutingMessage React state setter
|
|
221
|
+
* @param {Function} callbacks.setExecutingSubstep - setExecutingSubstep React state setter
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* // In repl-ink.js
|
|
225
|
+
* useEffect(() => {
|
|
226
|
+
* registerCallbacks({
|
|
227
|
+
* setExecutingMessage,
|
|
228
|
+
* setExecutingSubstep
|
|
229
|
+
* });
|
|
230
|
+
* }, []);
|
|
231
|
+
*/
|
|
232
|
+
export function registerCallbacks(callbacks) {
|
|
233
|
+
if (callbacks.setExecutingMessage) {
|
|
234
|
+
messageManager.setExecutingMessageCallback(callbacks.setExecutingMessage);
|
|
235
|
+
}
|
|
236
|
+
if (callbacks.setExecutingSubstep) {
|
|
237
|
+
messageManager.setExecutingSubstepCallback(callbacks.setExecutingSubstep);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Helper: Send formatted section header (cyan bold)
|
|
243
|
+
*
|
|
244
|
+
* @param {string} title - Section title
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* sendSectionHeader('Database Options Comparison');
|
|
248
|
+
*/
|
|
249
|
+
export function sendSectionHeader(title) {
|
|
250
|
+
sendOutput(`\n${title}\n\n`);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Helper: Send formatted list item
|
|
255
|
+
*
|
|
256
|
+
* @param {string} item - List item text
|
|
257
|
+
* @param {number} indent - Indentation level (default: 0)
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* sendListItem('PostgreSQL - ACID compliant');
|
|
261
|
+
* sendListItem('Supports complex queries', 1);
|
|
262
|
+
*/
|
|
263
|
+
export function sendListItem(item, indent = 0) {
|
|
264
|
+
const spacing = ' '.repeat(indent);
|
|
265
|
+
sendOutput(`${spacing}- ${item}\n`);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Helper: Send indented content
|
|
270
|
+
*
|
|
271
|
+
* @param {string} content - Content to indent
|
|
272
|
+
* @param {number} level - Indentation level (0-3, each level = 2 spaces)
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* sendIndented('Details about the option', 1);
|
|
276
|
+
* sendIndented('Nested information', 2);
|
|
277
|
+
*/
|
|
278
|
+
export function sendIndented(content, level = 0) {
|
|
279
|
+
const spacing = ' '.repeat(level);
|
|
280
|
+
sendOutput(`${spacing}${content}`);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Helper: Send newline
|
|
285
|
+
*/
|
|
286
|
+
export function sendNewline() {
|
|
287
|
+
sendOutput('\n');
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Helper: Send multiple newlines
|
|
292
|
+
*
|
|
293
|
+
* @param {number} count - Number of newlines (default: 2)
|
|
294
|
+
*/
|
|
295
|
+
export function sendNewlines(count = 2) {
|
|
296
|
+
sendOutput('\n'.repeat(count));
|
|
297
|
+
}
|