@nexus-ai-nexoralabs/cli 0.1.3 → 0.1.4
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/.env.example +16 -16
- package/LICENSE +21 -21
- package/README.md +135 -106
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +9 -3
- package/dist/api/index.js.map +1 -1
- package/dist/chat/chatService.d.ts.map +1 -1
- package/dist/chat/chatService.js +22 -3
- package/dist/chat/chatService.js.map +1 -1
- package/dist/chat/conversationService.d.ts +7 -1
- package/dist/chat/conversationService.d.ts.map +1 -1
- package/dist/chat/conversationService.js +48 -15
- package/dist/chat/conversationService.js.map +1 -1
- package/dist/cli/agentRunner.d.ts.map +1 -1
- package/dist/cli/agentRunner.js +88 -8
- package/dist/cli/agentRunner.js.map +1 -1
- package/dist/cli/chatRunner.d.ts +65 -0
- package/dist/cli/chatRunner.d.ts.map +1 -0
- package/dist/cli/chatRunner.js +289 -0
- package/dist/cli/chatRunner.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/inputEngine.d.ts +10 -0
- package/dist/cli/inputEngine.d.ts.map +1 -1
- package/dist/cli/inputEngine.js +28 -1
- package/dist/cli/inputEngine.js.map +1 -1
- package/dist/cli/main.d.ts +4 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +89 -25
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/uiFormatters.d.ts +11 -1
- package/dist/cli/uiFormatters.d.ts.map +1 -1
- package/dist/cli/uiFormatters.js +253 -15
- package/dist/cli/uiFormatters.js.map +1 -1
- package/dist/intelligence/modelGateway.d.ts +1 -0
- package/dist/intelligence/modelGateway.d.ts.map +1 -1
- package/dist/intelligence/modelGateway.js +63 -6
- package/dist/intelligence/modelGateway.js.map +1 -1
- package/dist/intelligence/modelRegistry.d.ts +2 -2
- package/dist/intelligence/modelRegistry.d.ts.map +1 -1
- package/dist/intelligence/modelRegistry.js +72 -31
- package/dist/intelligence/modelRegistry.js.map +1 -1
- package/dist/intelligence/modelRouter.d.ts.map +1 -1
- package/dist/intelligence/modelRouter.js +62 -16
- package/dist/intelligence/modelRouter.js.map +1 -1
- package/dist/intelligence/providers/embeddedInferenceProvider.d.ts.map +1 -1
- package/dist/intelligence/providers/embeddedInferenceProvider.js +2224 -6
- package/dist/intelligence/providers/embeddedInferenceProvider.js.map +1 -1
- package/dist/intelligence/runtime/runtimeManager.d.ts +5 -0
- package/dist/intelligence/runtime/runtimeManager.d.ts.map +1 -1
- package/dist/intelligence/runtime/runtimeManager.js +64 -4
- package/dist/intelligence/runtime/runtimeManager.js.map +1 -1
- package/dist/orchestration/agentExecutionService.d.ts.map +1 -1
- package/dist/orchestration/agentExecutionService.js +22 -0
- package/dist/orchestration/agentExecutionService.js.map +1 -1
- package/dist/orchestration/agentTaskService.d.ts +24 -10
- package/dist/orchestration/agentTaskService.d.ts.map +1 -1
- package/dist/orchestration/agentTaskService.js +76 -13
- package/dist/orchestration/agentTaskService.js.map +1 -1
- package/dist/orchestration/codingAgentService.d.ts.map +1 -1
- package/dist/orchestration/codingAgentService.js +2 -0
- package/dist/orchestration/codingAgentService.js.map +1 -1
- package/dist/orchestration/goalCompletionVerifier.d.ts +9 -0
- package/dist/orchestration/goalCompletionVerifier.d.ts.map +1 -1
- package/dist/orchestration/goalCompletionVerifier.js +131 -9
- package/dist/orchestration/goalCompletionVerifier.js.map +1 -1
- package/dist/orchestration/index.d.ts +16 -2
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +20 -4
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/placeholderDetector.d.ts +74 -0
- package/dist/orchestration/placeholderDetector.d.ts.map +1 -0
- package/dist/orchestration/placeholderDetector.js +741 -0
- package/dist/orchestration/placeholderDetector.js.map +1 -0
- package/dist/orchestration/planner.d.ts.map +1 -1
- package/dist/orchestration/planner.js +94 -55
- package/dist/orchestration/planner.js.map +1 -1
- package/dist/orchestration/projectOrchestrator.d.ts +63 -0
- package/dist/orchestration/projectOrchestrator.d.ts.map +1 -0
- package/dist/orchestration/projectOrchestrator.js +555 -0
- package/dist/orchestration/projectOrchestrator.js.map +1 -0
- package/dist/orchestration/taskDecompositionService.d.ts +36 -0
- package/dist/orchestration/taskDecompositionService.d.ts.map +1 -0
- package/dist/orchestration/taskDecompositionService.js +367 -0
- package/dist/orchestration/taskDecompositionService.js.map +1 -0
- package/dist/orchestration/taskDecompositionTypes.d.ts +62 -0
- package/dist/orchestration/taskDecompositionTypes.d.ts.map +1 -0
- package/dist/orchestration/taskDecompositionTypes.js +5 -0
- package/dist/orchestration/taskDecompositionTypes.js.map +1 -0
- package/dist/preview/previewServer.d.ts.map +1 -1
- package/dist/preview/previewServer.js +28 -7
- package/dist/preview/previewServer.js.map +1 -1
- package/dist/preview/previewService.d.ts +32 -3
- package/dist/preview/previewService.d.ts.map +1 -1
- package/dist/preview/previewService.js +370 -108
- package/dist/preview/previewService.js.map +1 -1
- package/dist/preview/previewTypes.d.ts +1 -1
- package/dist/preview/previewTypes.d.ts.map +1 -1
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/migration.d.ts.map +1 -1
- package/dist/storage/migration.js +79 -0
- package/dist/storage/migration.js.map +1 -1
- package/dist/storage/repositories/agentTaskRepository.d.ts +13 -0
- package/dist/storage/repositories/agentTaskRepository.d.ts.map +1 -1
- package/dist/storage/repositories/agentTaskRepository.js +87 -25
- package/dist/storage/repositories/agentTaskRepository.js.map +1 -1
- package/dist/storage/repositories/conversationRepository.d.ts +5 -1
- package/dist/storage/repositories/conversationRepository.d.ts.map +1 -1
- package/dist/storage/repositories/conversationRepository.js +69 -0
- package/dist/storage/repositories/conversationRepository.js.map +1 -1
- package/dist/storage/repositories/messageRepository.d.ts +3 -0
- package/dist/storage/repositories/messageRepository.d.ts.map +1 -1
- package/dist/storage/repositories/messageRepository.js +29 -0
- package/dist/storage/repositories/messageRepository.js.map +1 -1
- package/dist/storage/repositories/taskArtifactRepository.d.ts +19 -0
- package/dist/storage/repositories/taskArtifactRepository.d.ts.map +1 -0
- package/dist/storage/repositories/taskArtifactRepository.js +82 -0
- package/dist/storage/repositories/taskArtifactRepository.js.map +1 -0
- package/dist/storage/repositories/types.d.ts +32 -0
- package/dist/storage/repositories/types.d.ts.map +1 -1
- package/dist/tools/adapters/filesystemAdapter.d.ts.map +1 -1
- package/dist/tools/adapters/filesystemAdapter.js +8 -1
- package/dist/tools/adapters/filesystemAdapter.js.map +1 -1
- package/dist/ui/public/app.js +777 -777
- package/dist/ui/public/index.html +117 -117
- package/dist/ui/public/styles.css +413 -413
- package/package.json +64 -63
package/dist/cli/main.js
CHANGED
|
@@ -4,11 +4,16 @@
|
|
|
4
4
|
* Bootstraps ApplicationApi, displays NEXUS Workstation Dashboard,
|
|
5
5
|
* and manages an interactive shell via InputEngine (paste-debounced,
|
|
6
6
|
* compose-mode-capable) with concurrency guards and safe SIGINT handling.
|
|
7
|
+
*
|
|
8
|
+
* Provides clean dual-runtime operation:
|
|
9
|
+
* - Agent Mode: Full task execution pipeline (Think -> Plan -> Approve -> Execute -> Verify)
|
|
10
|
+
* - Chat Mode: Pure conversational AI (direct ModelGateway / ChatService inference)
|
|
7
11
|
*/
|
|
8
12
|
import { loadConfig } from '../config/index.js';
|
|
9
13
|
import { ApplicationApi } from '../api/index.js';
|
|
10
14
|
import { AgentRunner } from './agentRunner.js';
|
|
11
|
-
import {
|
|
15
|
+
import { ChatRunner } from './chatRunner.js';
|
|
16
|
+
import { InputEngine, SIGNAL_ENTER_COMPOSE, SIGNAL_SEND_COMPOSE, SIGNAL_ENTER_CHAT, SIGNAL_EXIT_CHAT, } from './inputEngine.js';
|
|
12
17
|
import { renderDashboard, renderOllamaMissingBanner, colors } from './uiFormatters.js';
|
|
13
18
|
export function handleCliFlags(args = process.argv.slice(2)) {
|
|
14
19
|
if (args.includes('--version') || args.includes('-v')) {
|
|
@@ -16,22 +21,24 @@ export function handleCliFlags(args = process.argv.slice(2)) {
|
|
|
16
21
|
return true;
|
|
17
22
|
}
|
|
18
23
|
if (args.includes('--help') || args.includes('-h')) {
|
|
19
|
-
console.log(`NEXUS AI — Local-First AI Workstation CLI
|
|
20
|
-
|
|
21
|
-
Usage:
|
|
22
|
-
nexus [options]
|
|
23
|
-
|
|
24
|
-
Options:
|
|
25
|
-
-v, --version Display NEXUS AI version
|
|
26
|
-
-h, --help Display CLI help and usage
|
|
27
|
-
|
|
28
|
-
Interactive Shell Commands:
|
|
29
|
-
/
|
|
30
|
-
/
|
|
31
|
-
/
|
|
32
|
-
/
|
|
33
|
-
/
|
|
34
|
-
/
|
|
24
|
+
console.log(`NEXUS AI — Local-First AI Workstation CLI
|
|
25
|
+
|
|
26
|
+
Usage:
|
|
27
|
+
nexus [options]
|
|
28
|
+
|
|
29
|
+
Options:
|
|
30
|
+
-v, --version Display NEXUS AI version
|
|
31
|
+
-h, --help Display CLI help and usage
|
|
32
|
+
|
|
33
|
+
Interactive Shell Commands:
|
|
34
|
+
/chat Start normal AI conversation (Chat Mode)
|
|
35
|
+
/chats View conversation history
|
|
36
|
+
/help Show available in-app commands
|
|
37
|
+
/model [id] Display or switch active AI model
|
|
38
|
+
/models List all discovered models
|
|
39
|
+
/tasks List recent task history
|
|
40
|
+
/preview Launch project preview server
|
|
41
|
+
/clear Clear terminal screen
|
|
35
42
|
/exit Exit NEXUS AI Workstation`);
|
|
36
43
|
return true;
|
|
37
44
|
}
|
|
@@ -46,6 +53,7 @@ async function runCli() {
|
|
|
46
53
|
// 1. Bootstrap all subsystems
|
|
47
54
|
const healthReport = await api.bootstrap();
|
|
48
55
|
const runner = new AgentRunner(api, config.logLevel);
|
|
56
|
+
const chatRunner = new ChatRunner(api, config.logLevel);
|
|
49
57
|
// 2. Render initial Workstation Dashboard
|
|
50
58
|
const renderStartDashboard = () => renderDashboard(healthReport, config.workspaceRoot);
|
|
51
59
|
console.log(renderStartDashboard());
|
|
@@ -62,13 +70,21 @@ async function runCli() {
|
|
|
62
70
|
}
|
|
63
71
|
}
|
|
64
72
|
let isBusy = false;
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
// 4. Build InputEngine — paste-debounced, compose-mode-capable, dual-mode (Agent / Chat)
|
|
74
|
+
let engine;
|
|
75
|
+
engine = new InputEngine({
|
|
76
|
+
isAwaitingApproval: () => engine?.getCliMode() === 'agent' &&
|
|
77
|
+
!!(runner.currentTask && runner.currentTask.state === 'awaiting_approval'),
|
|
68
78
|
onInput: async (text) => {
|
|
69
|
-
// Exit commands handled before isBusy to allow clean exit at any time
|
|
70
79
|
const lower = text.toLowerCase();
|
|
80
|
+
// Global Exit commands handled before isBusy to allow clean exit at any time
|
|
71
81
|
if (lower === '/exit' || lower === '/quit' || lower === '/q') {
|
|
82
|
+
if (engine.getCliMode() === 'chat') {
|
|
83
|
+
engine.setCliMode('agent');
|
|
84
|
+
process.stdout.write(`\n${colors.brightCyan}Returned to NEXUS Agent mode.${colors.reset}\n\n`);
|
|
85
|
+
engine.refreshPrompt();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
72
88
|
console.log(`\n${runner.exitRunner()}\n`);
|
|
73
89
|
api.close();
|
|
74
90
|
engine.close();
|
|
@@ -76,27 +92,62 @@ async function runCli() {
|
|
|
76
92
|
}
|
|
77
93
|
if (lower === '/clear' || lower === '/cls') {
|
|
78
94
|
process.stdout.write('\x1bc');
|
|
79
|
-
|
|
95
|
+
if (engine.getCliMode() === 'agent') {
|
|
96
|
+
console.log(renderStartDashboard());
|
|
97
|
+
}
|
|
80
98
|
engine.refreshPrompt();
|
|
81
99
|
return;
|
|
82
100
|
}
|
|
83
101
|
if (isBusy) {
|
|
84
|
-
process.stdout.write(`\n${colors.brightYellow}
|
|
102
|
+
process.stdout.write(`\n${colors.brightYellow}Operation in progress. Please wait or press Ctrl+C to cancel.${colors.reset}\n\n`);
|
|
85
103
|
engine.refreshPrompt();
|
|
86
104
|
return;
|
|
87
105
|
}
|
|
88
106
|
isBusy = true;
|
|
89
107
|
try {
|
|
108
|
+
// ---------------------------------------------------------------------
|
|
109
|
+
// CHAT MODE DISPATCH
|
|
110
|
+
// ---------------------------------------------------------------------
|
|
111
|
+
if (engine.getCliMode() === 'chat') {
|
|
112
|
+
if (lower === '/exit-chat' || lower === '/exitchat') {
|
|
113
|
+
engine.setCliMode('agent');
|
|
114
|
+
process.stdout.write(`\n${colors.brightCyan}Returned to NEXUS Agent mode.${colors.reset}\n\n`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const response = await chatRunner.runCommand(text, { streamToStdout: true });
|
|
118
|
+
if (response === SIGNAL_EXIT_CHAT) {
|
|
119
|
+
engine.setCliMode('agent');
|
|
120
|
+
process.stdout.write(`\n${colors.brightCyan}Returned to NEXUS Agent mode.${colors.reset}\n\n`);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (response) {
|
|
124
|
+
process.stdout.write(`\n${response}\n\n`);
|
|
125
|
+
}
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// ---------------------------------------------------------------------
|
|
129
|
+
// AGENT MODE DISPATCH
|
|
130
|
+
// ---------------------------------------------------------------------
|
|
90
131
|
const response = await runner.runCommand(text);
|
|
91
132
|
// Handle compose mode signals returned by AgentRunner
|
|
92
133
|
if (response === SIGNAL_ENTER_COMPOSE) {
|
|
93
134
|
engine.enterComposeMode();
|
|
94
|
-
return;
|
|
135
|
+
return;
|
|
95
136
|
}
|
|
96
137
|
if (response === SIGNAL_SEND_COMPOSE) {
|
|
97
138
|
await engine.submitComposeBuffer();
|
|
98
139
|
return;
|
|
99
140
|
}
|
|
141
|
+
// Handle Chat Mode transitions
|
|
142
|
+
if (response === SIGNAL_ENTER_CHAT || response.startsWith(`${SIGNAL_ENTER_CHAT}:`)) {
|
|
143
|
+
const targetConvId = response.startsWith(`${SIGNAL_ENTER_CHAT}:`)
|
|
144
|
+
? response.slice(SIGNAL_ENTER_CHAT.length + 1).trim()
|
|
145
|
+
: undefined;
|
|
146
|
+
engine.setCliMode('chat');
|
|
147
|
+
const banner = await chatRunner.startOrResumeChat(targetConvId);
|
|
148
|
+
process.stdout.write(`\n${banner}\n\n`);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
100
151
|
if (response) {
|
|
101
152
|
process.stdout.write(`\n${response}\n\n`);
|
|
102
153
|
}
|
|
@@ -110,8 +161,21 @@ async function runCli() {
|
|
|
110
161
|
}
|
|
111
162
|
},
|
|
112
163
|
});
|
|
113
|
-
//
|
|
164
|
+
// 5. Safe Ctrl+C handling: cancels active generation or task if running, or exits cleanly if idle
|
|
114
165
|
engine.readline.on('SIGINT', async () => {
|
|
166
|
+
if (engine.getCliMode() === 'chat') {
|
|
167
|
+
if (chatRunner.cancelActiveGeneration()) {
|
|
168
|
+
process.stdout.write(`\n\n${colors.brightYellow}[SIGINT] Chat generation cancelled.${colors.reset}\n\n`);
|
|
169
|
+
isBusy = false;
|
|
170
|
+
engine.refreshPrompt();
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
process.stdout.write(`\n\n${colors.dim}[SIGINT] Safely closing NEXUS AI Workstation...${colors.reset}\n`);
|
|
174
|
+
api.close();
|
|
175
|
+
engine.close();
|
|
176
|
+
process.exit(0);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
115
179
|
if (runner.currentTask &&
|
|
116
180
|
['created', 'planning', 'executing', 'awaiting_approval'].includes(runner.currentTask.state)) {
|
|
117
181
|
process.stdout.write(`\n\n${colors.brightYellow}[SIGINT] Cancelling active task '${runner.currentTask.id}'...${colors.reset}\n`);
|
package/dist/cli/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ import type { SystemHealthReport } from '../api/index.js';
|
|
|
14
14
|
import type { AgentTask } from '../storage/repositories/types.js';
|
|
15
15
|
import type { AgentPlan } from '../orchestration/types.js';
|
|
16
16
|
import type { ApprovalRequest } from '../tools/approvalTypes.js';
|
|
17
|
+
import type { DecompositionPlan, ProjectOrchestrationResult } from '../orchestration/taskDecompositionTypes.js';
|
|
17
18
|
export declare const colors: {
|
|
18
19
|
reset: string;
|
|
19
20
|
bold: string;
|
|
@@ -57,21 +58,30 @@ export declare function sanitizeText(text: string): string;
|
|
|
57
58
|
export declare function drawDivider(char?: string, width?: number): string;
|
|
58
59
|
export declare function drawHeaderBanner(): string;
|
|
59
60
|
export declare function renderDashboard(report: SystemHealthReport, workspaceRoot: string): string;
|
|
61
|
+
export declare function formatRelativeTime(isoString: string): string;
|
|
62
|
+
export declare function renderChatBanner(): string;
|
|
63
|
+
export declare function renderChatHistory(conversations: Array<import('../storage/repositories/types.js').ConversationSummary>): string;
|
|
64
|
+
export declare function renderChatSearchResults(query: string, results: Array<import('../storage/repositories/types.js').ConversationSummary>): string;
|
|
60
65
|
export declare function renderHelpMenu(): string;
|
|
61
66
|
export declare function renderTasksList(tasks: AgentTask[]): string;
|
|
62
67
|
export declare function renderApprovalCard(approval: ApprovalRequest, taskTitle?: string): string;
|
|
63
68
|
export declare function renderCompletionCard(task: AgentTask, plan?: AgentPlan | null, durationMs?: number): string;
|
|
64
69
|
export declare function renderFailureCard(task: AgentTask, errorMessage?: string): string;
|
|
70
|
+
export declare function renderTaskDecompositionPlanCard(plan: DecompositionPlan, taskTitle: string): string;
|
|
71
|
+
export declare function renderDecompositionCompletionCard(task: AgentTask, result: ProjectOrchestrationResult, durationMs?: number): string;
|
|
72
|
+
export declare function renderDecompositionFailureCard(task: AgentTask, result: ProjectOrchestrationResult): string;
|
|
65
73
|
export declare function renderPromptPreview(text: string): string;
|
|
66
74
|
export declare function renderComposeHeader(): string;
|
|
67
75
|
export declare function renderModelControlScreen(models: Array<{
|
|
68
76
|
id: string;
|
|
69
77
|
name: string;
|
|
78
|
+
provider?: string;
|
|
70
79
|
capabilities: string[];
|
|
80
|
+
isAvailable?: boolean;
|
|
71
81
|
}>, roleStatus: Record<string, {
|
|
72
82
|
modelId: string;
|
|
73
83
|
source: 'USER' | 'AUTO';
|
|
74
|
-
}>, providerName?: string): string;
|
|
84
|
+
}>, providerName?: string, activeModelId?: string): string;
|
|
75
85
|
export declare function renderModelStatusScreen(roleStatus: Record<string, {
|
|
76
86
|
modelId: string;
|
|
77
87
|
source: 'USER' | 'AUTO';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uiFormatters.d.ts","sourceRoot":"","sources":["../../src/cli/uiFormatters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"uiFormatters.d.ts","sourceRoot":"","sources":["../../src/cli/uiFormatters.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/uiFormatters.js
CHANGED
|
@@ -417,6 +417,89 @@ export function renderDashboard(report, workspaceRoot) {
|
|
|
417
417
|
lines.push('');
|
|
418
418
|
return lines.join('\n');
|
|
419
419
|
}
|
|
420
|
+
export function formatRelativeTime(isoString) {
|
|
421
|
+
try {
|
|
422
|
+
const time = new Date(isoString).getTime();
|
|
423
|
+
if (isNaN(time))
|
|
424
|
+
return 'recently';
|
|
425
|
+
const now = Date.now();
|
|
426
|
+
const diffMs = Math.max(0, now - time);
|
|
427
|
+
const diffSec = Math.floor(diffMs / 1000);
|
|
428
|
+
const diffMin = Math.floor(diffSec / 60);
|
|
429
|
+
const diffHour = Math.floor(diffMin / 60);
|
|
430
|
+
const diffDay = Math.floor(diffHour / 24);
|
|
431
|
+
if (diffSec < 45)
|
|
432
|
+
return 'just now';
|
|
433
|
+
if (diffMin === 1)
|
|
434
|
+
return '1 minute ago';
|
|
435
|
+
if (diffMin < 60)
|
|
436
|
+
return `${diffMin} minutes ago`;
|
|
437
|
+
if (diffHour === 1)
|
|
438
|
+
return '1 hour ago';
|
|
439
|
+
if (diffHour < 24)
|
|
440
|
+
return `${diffHour} hours ago`;
|
|
441
|
+
if (diffDay === 1)
|
|
442
|
+
return 'yesterday';
|
|
443
|
+
if (diffDay < 7)
|
|
444
|
+
return `${diffDay} days ago`;
|
|
445
|
+
return new Date(isoString).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
return 'recently';
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
export function renderChatBanner() {
|
|
452
|
+
const lines = [];
|
|
453
|
+
lines.push(`${colors.bold}${colors.brightCyan}NEXUS CHAT${colors.reset}`);
|
|
454
|
+
lines.push(drawDivider('─', 40));
|
|
455
|
+
lines.push('');
|
|
456
|
+
lines.push('You are now chatting with NEXUS.');
|
|
457
|
+
lines.push(`Type ${colors.brightCyan}/exit-chat${colors.reset} to return to the main NEXUS prompt.`);
|
|
458
|
+
lines.push(`Type ${colors.brightCyan}/new-chat${colors.reset} to start a new conversation.`);
|
|
459
|
+
lines.push(`Type ${colors.brightCyan}/chats${colors.reset} to view conversation history.`);
|
|
460
|
+
return lines.join('\n');
|
|
461
|
+
}
|
|
462
|
+
export function renderChatHistory(conversations) {
|
|
463
|
+
const lines = [];
|
|
464
|
+
lines.push(`${colors.bold}${colors.brightCyan}NEXUS CHAT HISTORY${colors.reset}`);
|
|
465
|
+
lines.push(drawDivider('─', 40));
|
|
466
|
+
lines.push('');
|
|
467
|
+
if (conversations.length === 0) {
|
|
468
|
+
lines.push(`${colors.dim}No conversation history found. Type /chat to start chatting.${colors.reset}`);
|
|
469
|
+
lines.push('');
|
|
470
|
+
return lines.join('\n');
|
|
471
|
+
}
|
|
472
|
+
conversations.forEach((c, idx) => {
|
|
473
|
+
const relTime = formatRelativeTime(c.updatedAt);
|
|
474
|
+
lines.push(`${colors.bold}${colors.white}${idx + 1}. ${c.title}${colors.reset}`);
|
|
475
|
+
lines.push(` ${colors.dim}Updated:${colors.reset} ${relTime}`);
|
|
476
|
+
lines.push(` ${colors.dim}Messages:${colors.reset} ${c.messageCount}`);
|
|
477
|
+
lines.push(` ${colors.dim}ID:${colors.reset} ${colors.brightCyan}${c.id}${colors.reset}`);
|
|
478
|
+
lines.push('');
|
|
479
|
+
});
|
|
480
|
+
lines.push(`${colors.bold}Commands:${colors.reset}`);
|
|
481
|
+
lines.push(` ${colors.brightCyan}/chats open <id>${colors.reset} Open conversation`);
|
|
482
|
+
lines.push(` ${colors.brightCyan}/chats delete <id>${colors.reset} Delete conversation`);
|
|
483
|
+
lines.push(` ${colors.brightCyan}/chats search <q>${colors.reset} Search conversations`);
|
|
484
|
+
return lines.join('\n');
|
|
485
|
+
}
|
|
486
|
+
export function renderChatSearchResults(query, results) {
|
|
487
|
+
const lines = [];
|
|
488
|
+
lines.push(`${colors.bold}${colors.brightCyan}NEXUS CHAT SEARCH RESULTS: "${query}"${colors.reset}`);
|
|
489
|
+
lines.push(drawDivider('─', 48));
|
|
490
|
+
lines.push('');
|
|
491
|
+
if (results.length === 0) {
|
|
492
|
+
lines.push(`${colors.dim}No conversations found matching "${query}".${colors.reset}`);
|
|
493
|
+
lines.push('');
|
|
494
|
+
return lines.join('\n');
|
|
495
|
+
}
|
|
496
|
+
results.forEach((c, idx) => {
|
|
497
|
+
lines.push(`${colors.bold}${idx + 1}. ${c.title}${colors.reset} ${colors.dim}(${c.messageCount} msg${c.messageCount === 1 ? '' : 's'}) [ID: ${colors.brightCyan}${c.id}${colors.dim}]${colors.reset}`);
|
|
498
|
+
});
|
|
499
|
+
lines.push('');
|
|
500
|
+
lines.push(`${colors.dim}Use /chats open <id> to resume a conversation.${colors.reset}`);
|
|
501
|
+
return lines.join('\n');
|
|
502
|
+
}
|
|
420
503
|
// ---------------------------------------------------------------------------
|
|
421
504
|
// Help Command Renderer
|
|
422
505
|
// ---------------------------------------------------------------------------
|
|
@@ -424,7 +507,20 @@ export function renderHelpMenu() {
|
|
|
424
507
|
const lines = [
|
|
425
508
|
`${colors.bold}${colors.brightCyan}NEXUS AI Agent Runner \u2014 Help & Command Reference${colors.reset}`,
|
|
426
509
|
drawDivider('─', 64),
|
|
427
|
-
`${colors.dim}
|
|
510
|
+
`${colors.dim}CHAT${colors.reset}`,
|
|
511
|
+
` ${colors.brightCyan}/chat${colors.reset} Start normal AI conversation`,
|
|
512
|
+
` ${colors.brightCyan}/chats${colors.reset} View conversation history`,
|
|
513
|
+
` ${colors.brightCyan}/chats open <id>${colors.reset} Open previous conversation`,
|
|
514
|
+
` ${colors.brightCyan}/chats search <q>${colors.reset} Search conversations`,
|
|
515
|
+
` ${colors.brightCyan}/chats delete <id>${colors.reset} Delete conversation`,
|
|
516
|
+
'',
|
|
517
|
+
`${colors.dim}CHAT MODE${colors.reset}`,
|
|
518
|
+
` ${colors.brightCyan}/exit-chat${colors.reset} Return to Agent Mode`,
|
|
519
|
+
` ${colors.brightCyan}/new-chat${colors.reset} Start new conversation`,
|
|
520
|
+
` ${colors.brightCyan}/chats${colors.reset} View conversations`,
|
|
521
|
+
` ${colors.brightCyan}/model${colors.reset} Display or switch active model`,
|
|
522
|
+
'',
|
|
523
|
+
`${colors.dim}AGENT MODE${colors.reset}`,
|
|
428
524
|
` ${colors.brightCyan}<task description>${colors.reset} Submit a natural language goal`,
|
|
429
525
|
` ${colors.brightCyan}/task <goal>${colors.reset} Explicitly submit a task (alias: /t)`,
|
|
430
526
|
` ${colors.brightCyan}/code <goal>${colors.reset} Run automated coding task (P6-D)`,
|
|
@@ -440,7 +536,7 @@ export function renderHelpMenu() {
|
|
|
440
536
|
` ${colors.brightCyan}/preview stop${colors.reset} Stop active preview server`,
|
|
441
537
|
` ${colors.brightCyan}/preview status${colors.reset} Show active preview status`,
|
|
442
538
|
` ${colors.brightCyan}/tasks${colors.reset} List recent task history`,
|
|
443
|
-
` ${colors.brightCyan}/models${colors.reset} List installed
|
|
539
|
+
` ${colors.brightCyan}/models${colors.reset} List installed models`,
|
|
444
540
|
` ${colors.brightCyan}/model <role> <n>${colors.reset} Set role model override`,
|
|
445
541
|
` ${colors.brightCyan}/model reset${colors.reset} Reset all model overrides`,
|
|
446
542
|
` ${colors.brightCyan}/workspace${colors.reset} Workspace root & security info`,
|
|
@@ -451,8 +547,8 @@ export function renderHelpMenu() {
|
|
|
451
547
|
` ${colors.brightCyan}/clear${colors.reset} Clear terminal screen`,
|
|
452
548
|
` ${colors.brightCyan}/exit${colors.reset} Exit NEXUS CLI`,
|
|
453
549
|
drawDivider('─', 64),
|
|
454
|
-
`${colors.dim}TIP:
|
|
455
|
-
`${colors.dim}
|
|
550
|
+
`${colors.dim}TIP: Type /chat to talk directly with the AI without creating tasks.${colors.reset}`,
|
|
551
|
+
`${colors.dim} Type task instructions at NEXUS> to have the Agent build & execute.${colors.reset}`,
|
|
456
552
|
];
|
|
457
553
|
return lines.join('\n');
|
|
458
554
|
}
|
|
@@ -467,10 +563,11 @@ export function renderTasksList(tasks) {
|
|
|
467
563
|
`${colors.bold}${colors.brightCyan}RECENT TASKS${colors.reset}`,
|
|
468
564
|
drawDivider('─', 74),
|
|
469
565
|
];
|
|
470
|
-
tasks.slice(0, 15).forEach((t) => {
|
|
566
|
+
tasks.slice(0, 15).forEach((t, idx) => {
|
|
567
|
+
const num = `${idx + 1}.`.padEnd(4, ' ');
|
|
471
568
|
const symbol = getSymbolForState(t.state);
|
|
472
569
|
const idPad = t.id.padEnd(26, ' ');
|
|
473
|
-
const titleTrunc = t.title.length >
|
|
570
|
+
const titleTrunc = t.title.length > 26 ? `${t.title.slice(0, 23)}...` : t.title.padEnd(26, ' ');
|
|
474
571
|
const stateColor = t.state === 'completed'
|
|
475
572
|
? colors.brightGreen
|
|
476
573
|
: t.state === 'failed'
|
|
@@ -478,10 +575,10 @@ export function renderTasksList(tasks) {
|
|
|
478
575
|
: t.state === 'awaiting_approval'
|
|
479
576
|
? colors.brightYellow
|
|
480
577
|
: colors.dim;
|
|
481
|
-
lines.push(`${symbol} ${colors.brightCyan}${idPad}${colors.reset} ${titleTrunc} ${stateColor}${t.state.toUpperCase()}${colors.reset}`);
|
|
578
|
+
lines.push(`${colors.bold}${num}${colors.reset}${symbol} ${colors.brightCyan}${idPad}${colors.reset} ${titleTrunc} ${stateColor}${t.state.toUpperCase()}${colors.reset}`);
|
|
482
579
|
});
|
|
483
580
|
lines.push(drawDivider('─', 74));
|
|
484
|
-
lines.push(`${colors.dim}
|
|
581
|
+
lines.push(`${colors.dim}Commands: /preview (latest) | /preview <number> (e.g. /preview 2) | /task <id>${colors.reset}`);
|
|
485
582
|
return lines.join('\n');
|
|
486
583
|
}
|
|
487
584
|
// ---------------------------------------------------------------------------
|
|
@@ -569,6 +666,90 @@ export function renderFailureCard(task, errorMessage) {
|
|
|
569
666
|
return lines.join('\n');
|
|
570
667
|
}
|
|
571
668
|
// ---------------------------------------------------------------------------
|
|
669
|
+
// Task Decomposition & Project Orchestration Renderers
|
|
670
|
+
// ---------------------------------------------------------------------------
|
|
671
|
+
export function renderTaskDecompositionPlanCard(plan, taskTitle) {
|
|
672
|
+
const lines = [];
|
|
673
|
+
lines.push('');
|
|
674
|
+
lines.push(drawDivider('─', 64));
|
|
675
|
+
lines.push(` ${colors.bold}${colors.brightCyan}NEXUS TASK PLAN${colors.reset}`);
|
|
676
|
+
lines.push(drawDivider('─', 64));
|
|
677
|
+
lines.push('');
|
|
678
|
+
lines.push(` ${colors.bold}Goal:${colors.reset} ${taskTitle}`);
|
|
679
|
+
lines.push(` ${colors.dim}${plan.units.length} implementation units detected (${plan.estimatedComplexity.toUpperCase()} complexity):${colors.reset}`);
|
|
680
|
+
lines.push('');
|
|
681
|
+
plan.units.forEach((unit, idx) => {
|
|
682
|
+
const num = `${idx + 1}.`.padEnd(4, ' ');
|
|
683
|
+
const title = unit.title;
|
|
684
|
+
const cat = `[${unit.category}]`.padEnd(14, ' ');
|
|
685
|
+
const deps = unit.dependencies.length > 0 ? `${colors.dim}(deps: ${unit.dependencies.join(', ')})${colors.reset}` : '';
|
|
686
|
+
lines.push(` ${colors.bold}${num}${colors.reset} ${colors.brightCyan}${cat}${colors.reset} ${title} ${deps}`);
|
|
687
|
+
});
|
|
688
|
+
lines.push('');
|
|
689
|
+
lines.push(` ${colors.dim}Executing queue sequentially with per-unit verification...${colors.reset}`);
|
|
690
|
+
lines.push(drawDivider('─', 64));
|
|
691
|
+
return lines.join('\n');
|
|
692
|
+
}
|
|
693
|
+
export function renderDecompositionCompletionCard(task, result, durationMs) {
|
|
694
|
+
const durationSec = durationMs ? (durationMs / 1000).toFixed(1) : 'N/A';
|
|
695
|
+
const lines = [];
|
|
696
|
+
lines.push(drawDivider('─', 64));
|
|
697
|
+
lines.push(` ${colors.bold}${colors.brightGreen}FINAL RESULT \u2014 PROJECT COMPLETED${colors.reset}`);
|
|
698
|
+
lines.push(drawDivider('─', 64));
|
|
699
|
+
lines.push('');
|
|
700
|
+
lines.push(` ${colors.bold}Goal:${colors.reset} ${task.title}`);
|
|
701
|
+
lines.push(` ${colors.bold}Status:${colors.reset} ${colors.brightGreen}\u2713 COMPLETED${colors.reset}`);
|
|
702
|
+
lines.push(` ${colors.bold}Task ID:${colors.reset} ${task.id}`);
|
|
703
|
+
lines.push(` ${colors.bold}Duration:${colors.reset} ${durationSec}s`);
|
|
704
|
+
lines.push(` ${colors.bold}Units:${colors.reset} ${result.completedUnits}/${result.totalUnits} completed cleanly`);
|
|
705
|
+
lines.push('');
|
|
706
|
+
lines.push(`${colors.bold}Execution Summary:${colors.reset}`);
|
|
707
|
+
result.childResults.forEach((child, idx) => {
|
|
708
|
+
const sym = child.success ? `${colors.brightGreen}\u2713${colors.reset}` : `${colors.brightRed}\u2716${colors.reset}`;
|
|
709
|
+
lines.push(` ${sym} Unit ${idx + 1}: ${child.title}`);
|
|
710
|
+
});
|
|
711
|
+
lines.push('');
|
|
712
|
+
lines.push(`${colors.bold}Verification:${colors.reset}`);
|
|
713
|
+
lines.push(` ${colors.brightGreen}\u2713 All child implementation units verified${colors.reset}`);
|
|
714
|
+
lines.push(` ${colors.brightGreen}\u2713 Final end-to-end integration verified${colors.reset}`);
|
|
715
|
+
lines.push(` ${colors.brightGreen}\u2713 Artifacts registered and ready for /preview${colors.reset}`);
|
|
716
|
+
lines.push(drawDivider('─', 64));
|
|
717
|
+
return lines.join('\n');
|
|
718
|
+
}
|
|
719
|
+
export function renderDecompositionFailureCard(task, result) {
|
|
720
|
+
const lines = [];
|
|
721
|
+
lines.push(drawDivider('─', 64));
|
|
722
|
+
lines.push(` ${colors.bold}${colors.brightRed}PROJECT EXECUTION FAILED${colors.reset}`);
|
|
723
|
+
lines.push(drawDivider('─', 64));
|
|
724
|
+
lines.push('');
|
|
725
|
+
lines.push(` ${colors.bold}Goal:${colors.reset} ${task.title}`);
|
|
726
|
+
lines.push(` ${colors.bold}Status:${colors.reset} ${colors.brightRed}\u2716 FAILED${colors.reset}`);
|
|
727
|
+
lines.push(` ${colors.bold}Task ID:${colors.reset} ${task.id}`);
|
|
728
|
+
lines.push(` ${colors.bold}Progress:${colors.reset} ${result.completedUnits}/${result.totalUnits} units succeeded`);
|
|
729
|
+
if (result.error) {
|
|
730
|
+
lines.push(` ${colors.bold}Error:${colors.reset} ${colors.brightRed}${result.error}${colors.reset}`);
|
|
731
|
+
}
|
|
732
|
+
lines.push('');
|
|
733
|
+
lines.push(`${colors.bold}Unit Breakdown:${colors.reset}`);
|
|
734
|
+
result.childResults.forEach((child, idx) => {
|
|
735
|
+
const sym = child.success
|
|
736
|
+
? `${colors.brightGreen}\u2713${colors.reset}`
|
|
737
|
+
: child.status === 'blocked'
|
|
738
|
+
? `${colors.gray}\u25cb${colors.reset}`
|
|
739
|
+
: `${colors.brightRed}\u2716${colors.reset}`;
|
|
740
|
+
const statusText = child.success
|
|
741
|
+
? `${colors.brightGreen}COMPLETED${colors.reset}`
|
|
742
|
+
: child.status === 'blocked'
|
|
743
|
+
? `${colors.gray}BLOCKED${colors.reset}`
|
|
744
|
+
: `${colors.brightRed}FAILED${colors.reset}`;
|
|
745
|
+
lines.push(` ${sym} Unit ${idx + 1}: ${child.title.padEnd(30, ' ')} [${statusText}]`);
|
|
746
|
+
});
|
|
747
|
+
lines.push('');
|
|
748
|
+
lines.push(` ${colors.dim}Preview is unavailable due to verification or execution failure.${colors.reset}`);
|
|
749
|
+
lines.push(drawDivider('─', 64));
|
|
750
|
+
return lines.join('\n');
|
|
751
|
+
}
|
|
752
|
+
// ---------------------------------------------------------------------------
|
|
572
753
|
// P7-F.1: Prompt Preview Card
|
|
573
754
|
// ---------------------------------------------------------------------------
|
|
574
755
|
const MAX_PREVIEW_LINES = 5;
|
|
@@ -618,13 +799,17 @@ export function renderComposeHeader() {
|
|
|
618
799
|
// ---------------------------------------------------------------------------
|
|
619
800
|
// P7-G: Model Control & Status Screen Renderers
|
|
620
801
|
// ---------------------------------------------------------------------------
|
|
621
|
-
export function renderModelControlScreen(models, roleStatus, providerName = 'Embedded (Local)') {
|
|
802
|
+
export function renderModelControlScreen(models, roleStatus, providerName = 'Embedded (Local)', activeModelId) {
|
|
622
803
|
const lines = [];
|
|
623
804
|
lines.push(drawDivider('─', 60));
|
|
624
805
|
lines.push(` ${colors.bold}${colors.brightCyan}NEXUS MODEL CONTROL${colors.reset}`);
|
|
625
806
|
lines.push(drawDivider('─', 60));
|
|
626
807
|
lines.push('');
|
|
627
|
-
|
|
808
|
+
const activeModelDisplay = activeModelId || roleStatus['chat']?.modelId || roleStatus['coder']?.modelId || (models[0] ? models[0].id : 'None');
|
|
809
|
+
const activeModelObj = models.find((m) => m.id === activeModelDisplay);
|
|
810
|
+
const activeProviderDisplay = activeModelObj?.provider ? (activeModelObj.provider === 'embedded' ? 'Embedded' : 'Ollama') : providerName;
|
|
811
|
+
lines.push(` ${colors.bold}Current Active Model:${colors.reset} ${colors.brightCyan}${colors.bold}${activeModelDisplay}${colors.reset}`);
|
|
812
|
+
lines.push(` ${colors.dim}Provider:${colors.reset} ${colors.brightGreen}${activeProviderDisplay}${colors.reset} • ${colors.dim}Status:${colors.reset} ${colors.brightGreen}READY${colors.reset}`);
|
|
628
813
|
lines.push('');
|
|
629
814
|
lines.push(`${colors.bold}AVAILABLE MODELS${colors.reset}`);
|
|
630
815
|
lines.push('');
|
|
@@ -633,8 +818,10 @@ export function renderModelControlScreen(models, roleStatus, providerName = 'Emb
|
|
|
633
818
|
}
|
|
634
819
|
else {
|
|
635
820
|
models.forEach((m, idx) => {
|
|
636
|
-
|
|
637
|
-
|
|
821
|
+
const pTag = m.provider === 'embedded' ? `${colors.brightGreen}[Embedded]${colors.reset}` : `${colors.brightCyan}[Ollama]${colors.reset}`;
|
|
822
|
+
const statusTag = m.isAvailable !== false ? `${colors.brightGreen}AVAILABLE${colors.reset}` : `${colors.brightRed}UNAVAILABLE${colors.reset}`;
|
|
823
|
+
lines.push(` ${colors.brightCyan}[${idx + 1}]${colors.reset} ${colors.bold}${m.name}${colors.reset} ${pTag}`);
|
|
824
|
+
lines.push(` ${colors.dim}Capabilities:${colors.reset} ${m.capabilities.join(', ')} • ${colors.dim}Status:${colors.reset} ${statusTag}`);
|
|
638
825
|
lines.push('');
|
|
639
826
|
});
|
|
640
827
|
}
|
|
@@ -709,14 +896,47 @@ export function renderPreviewCard(result) {
|
|
|
709
896
|
lines.push(drawDivider('─', 56));
|
|
710
897
|
lines.push('');
|
|
711
898
|
if (result.status === 'NO_COMPLETED_TASK') {
|
|
712
|
-
lines.push(` ${colors.
|
|
899
|
+
lines.push(` ${colors.brightYellow}ℹ No previewable task is available.${colors.reset}`);
|
|
900
|
+
lines.push('');
|
|
901
|
+
lines.push(` ${colors.dim}${result.message || 'Run a task to build a project first, or type /tasks to view history.'}${colors.reset}`);
|
|
902
|
+
lines.push(drawDivider('─', 56));
|
|
903
|
+
return lines.join('\n');
|
|
904
|
+
}
|
|
905
|
+
if (result.status === 'TASK_FAILED') {
|
|
906
|
+
lines.push(` ${colors.brightRed}\u2716 Preview Unavailable${colors.reset}`);
|
|
907
|
+
lines.push('');
|
|
908
|
+
if (result.task) {
|
|
909
|
+
lines.push(` ${colors.bold}Task:${colors.reset}`);
|
|
910
|
+
lines.push(` ${result.task.title}`);
|
|
911
|
+
lines.push('');
|
|
912
|
+
lines.push(` ${colors.bold}Status:${colors.reset}`);
|
|
913
|
+
lines.push(` ${colors.brightRed}FAILED${colors.reset}`);
|
|
914
|
+
lines.push('');
|
|
915
|
+
lines.push(` ${colors.bold}Reason:${colors.reset}`);
|
|
916
|
+
lines.push(` ${result.error || result.task.errorCategory || 'Execution Failed'}`);
|
|
917
|
+
lines.push('');
|
|
918
|
+
}
|
|
919
|
+
lines.push(` ${colors.dim}Run /tasks to view history or /preview <number> to preview an older completed task.${colors.reset}`);
|
|
920
|
+
lines.push(drawDivider('─', 56));
|
|
921
|
+
return lines.join('\n');
|
|
922
|
+
}
|
|
923
|
+
if (result.status === 'TASK_INCOMPLETE') {
|
|
924
|
+
lines.push(` ${colors.brightYellow}\u26a0 Preview Unavailable${colors.reset}`);
|
|
713
925
|
lines.push('');
|
|
714
|
-
|
|
926
|
+
if (result.task) {
|
|
927
|
+
lines.push(` ${colors.bold}Task:${colors.reset}`);
|
|
928
|
+
lines.push(` ${result.task.title}`);
|
|
929
|
+
lines.push('');
|
|
930
|
+
lines.push(` ${colors.bold}Status:${colors.reset}`);
|
|
931
|
+
lines.push(` ${colors.brightYellow}${result.task.state.toUpperCase()}${colors.reset}`);
|
|
932
|
+
lines.push('');
|
|
933
|
+
}
|
|
934
|
+
lines.push(` ${colors.dim}${result.message || 'Only completed tasks can be previewed. Run /tasks to view history.'}${colors.reset}`);
|
|
715
935
|
lines.push(drawDivider('─', 56));
|
|
716
936
|
return lines.join('\n');
|
|
717
937
|
}
|
|
718
938
|
if (result.status === 'NOT_WEB_PROJECT') {
|
|
719
|
-
lines.push(` ${colors.brightYellow}\u26a0
|
|
939
|
+
lines.push(` ${colors.brightYellow}\u26a0 Selected task does not contain a previewable web project.${colors.reset}`);
|
|
720
940
|
lines.push('');
|
|
721
941
|
if (result.task) {
|
|
722
942
|
lines.push(` ${colors.bold}Task:${colors.reset}`);
|
|
@@ -757,6 +977,24 @@ export function renderPreviewCard(result) {
|
|
|
757
977
|
lines.push(drawDivider('─', 56));
|
|
758
978
|
return lines.join('\n');
|
|
759
979
|
}
|
|
980
|
+
if (result.status === 'PLACEHOLDER_ARTIFACT_BLOCKED') {
|
|
981
|
+
lines.push(` ${colors.brightRed}\u2716 Preview Blocked${colors.reset}`);
|
|
982
|
+
lines.push('');
|
|
983
|
+
if (result.task) {
|
|
984
|
+
lines.push(` ${colors.bold}Task:${colors.reset}`);
|
|
985
|
+
lines.push(` ${result.task.title}`);
|
|
986
|
+
lines.push('');
|
|
987
|
+
lines.push(` ${colors.bold}Status:${colors.reset}`);
|
|
988
|
+
lines.push(` ${colors.brightRed}PLACEHOLDER_ARTIFACT_REJECTED${colors.reset}`);
|
|
989
|
+
lines.push('');
|
|
990
|
+
}
|
|
991
|
+
lines.push(` ${colors.bold}Reason:${colors.reset}`);
|
|
992
|
+
lines.push(` ${result.message || 'Generated artifact does not contain a valid implementation of the requested task.'}`);
|
|
993
|
+
lines.push('');
|
|
994
|
+
lines.push(` ${colors.dim}The agent must generate a real project implementation before previewing.${colors.reset}`);
|
|
995
|
+
lines.push(drawDivider('─', 56));
|
|
996
|
+
return lines.join('\n');
|
|
997
|
+
}
|
|
760
998
|
if (result.status === 'ERROR' || !result.success || !result.serverInfo) {
|
|
761
999
|
lines.push(` ${colors.brightRed}\u2716 Preview Launch Failed${colors.reset}`);
|
|
762
1000
|
lines.push(` ${result.error || result.message || 'Unknown preview error'}`);
|