archicore 0.2.2 → 0.2.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.
@@ -29,51 +29,6 @@ const COMMANDS = [
29
29
  { name: 'logout', aliases: [], description: 'Log out from ArchiCore' },
30
30
  { name: 'exit', aliases: ['quit', 'q'], description: 'Exit ArchiCore CLI' },
31
31
  ];
32
- // Get all command names and aliases for autocomplete
33
- function getAllCommandNames() {
34
- const names = [];
35
- for (const cmd of COMMANDS) {
36
- names.push('/' + cmd.name);
37
- for (const alias of cmd.aliases) {
38
- names.push('/' + alias);
39
- }
40
- }
41
- return names.sort();
42
- }
43
- /**
44
- * Tab autocomplete function for readline
45
- * Works on Linux, Windows, and macOS
46
- */
47
- function completer(line) {
48
- // If line starts with /, autocomplete commands
49
- if (line.startsWith('/')) {
50
- const allCommands = getAllCommandNames();
51
- const hits = allCommands.filter((cmd) => cmd.startsWith(line));
52
- // If exact match or no matches, return the line as-is
53
- if (hits.length === 0) {
54
- return [allCommands, line];
55
- }
56
- // Show matching commands with descriptions
57
- if (hits.length > 1) {
58
- console.log();
59
- for (const hit of hits) {
60
- const cmdName = hit.slice(1); // Remove leading /
61
- const cmd = COMMANDS.find(c => c.name === cmdName || c.aliases.includes(cmdName));
62
- if (cmd) {
63
- const desc = colors.dim(cmd.description);
64
- console.log(` ${colors.primary(hit.padEnd(18))} ${desc}`);
65
- }
66
- else {
67
- console.log(` ${colors.primary(hit)}`);
68
- }
69
- }
70
- console.log();
71
- }
72
- return [hits, line];
73
- }
74
- // For non-command input, no autocomplete
75
- return [[], line];
76
- }
77
32
  const state = {
78
33
  running: true,
79
34
  projectId: null,
@@ -177,31 +132,67 @@ export async function startInteractiveMode() {
177
132
  console.log(colors.muted(` Project: ${colors.primary(state.projectName)}`));
178
133
  }
179
134
  console.log();
180
- console.log(colors.muted(' Type /help for commands or ask a question about your code.'));
181
- console.log(colors.muted(' Press Tab to autocomplete commands.'));
135
+ console.log(colors.muted(' Type / to see commands, or ask a question about your code.'));
136
+ console.log(colors.muted(' Press Tab to autocomplete. Type ? for shortcuts.'));
182
137
  console.log();
183
- // Start REPL with Tab autocomplete
184
- const rl = readline.createInterface({
185
- input: process.stdin,
186
- output: process.stdout,
187
- terminal: true,
188
- completer: completer,
189
- });
190
- // Keep the process alive
191
- rl.ref?.();
192
- const prompt = () => {
193
- const prefix = state.projectName
138
+ // Interactive input with real-time autocomplete
139
+ await startInteractiveInput(state);
140
+ }
141
+ /**
142
+ * Start interactive input loop with real-time command suggestions
143
+ */
144
+ async function startInteractiveInput(state) {
145
+ const getPromptPrefix = () => {
146
+ return state.projectName
194
147
  ? colors.muted(`[${state.projectName}] `)
195
148
  : '';
196
- process.stdout.write(`${prefix}${colors.primary(icons.arrow)} `);
197
149
  };
198
- prompt();
199
- const processLine = async (input) => {
200
- const trimmed = input.trim();
201
- if (!trimmed) {
202
- prompt();
150
+ const promptStr = () => `${getPromptPrefix()}${colors.primary(icons.arrow)} `;
151
+ // State for current input
152
+ let currentInput = '';
153
+ let menuVisible = false;
154
+ let selectedIndex = 0;
155
+ let filteredCommands = [];
156
+ // Filter commands based on input
157
+ const filterCommands = (input) => {
158
+ if (!input.startsWith('/'))
159
+ return [];
160
+ const query = input.slice(1).toLowerCase();
161
+ if (!query)
162
+ return COMMANDS.slice(0, 10);
163
+ return COMMANDS.filter(cmd => cmd.name.toLowerCase().startsWith(query) ||
164
+ cmd.aliases.some(a => a.toLowerCase().startsWith(query))).slice(0, 10);
165
+ };
166
+ // Render the menu
167
+ const renderMenu = () => {
168
+ if (filteredCommands.length === 0)
203
169
  return;
170
+ console.log();
171
+ for (let i = 0; i < filteredCommands.length; i++) {
172
+ const cmd = filteredCommands[i];
173
+ const isSelected = i === selectedIndex;
174
+ const nameStr = `/${cmd.name}`.padEnd(18);
175
+ if (isSelected) {
176
+ console.log(` ${colors.highlight(nameStr)} ${colors.muted(cmd.description)}`);
177
+ }
178
+ else {
179
+ console.log(` ${colors.primary(nameStr)} ${colors.dim(cmd.description)}`);
180
+ }
181
+ }
182
+ console.log(colors.dim(' ↑↓ select • Tab complete • Enter run'));
183
+ };
184
+ // Clear menu lines
185
+ const clearMenu = (lines) => {
186
+ for (let i = 0; i < lines; i++) {
187
+ readline.moveCursor(process.stdout, 0, -1);
188
+ readline.clearLine(process.stdout, 0);
204
189
  }
190
+ };
191
+ // Process submitted input
192
+ const processInput = async (input) => {
193
+ const trimmed = input.trim();
194
+ if (!trimmed)
195
+ return;
205
196
  state.history.push(trimmed);
206
197
  try {
207
198
  await handleInput(trimmed);
@@ -209,57 +200,147 @@ export async function startInteractiveMode() {
209
200
  catch (error) {
210
201
  printError(String(error));
211
202
  }
212
- if (state.running) {
203
+ };
204
+ // Use raw mode for real-time input
205
+ if (process.stdin.isTTY) {
206
+ readline.emitKeypressEvents(process.stdin);
207
+ process.stdin.setRawMode(true);
208
+ }
209
+ process.stdout.write(promptStr());
210
+ const handleKeypress = async (str, key) => {
211
+ // Handle Ctrl+C
212
+ if (key.ctrl && key.name === 'c') {
213
+ if (menuVisible) {
214
+ clearMenu(filteredCommands.length + 2);
215
+ menuVisible = false;
216
+ }
213
217
  console.log();
214
- prompt();
215
- }
216
- else {
217
- rl.close();
218
+ state.running = false;
219
+ printGoodbye();
220
+ process.exit(0);
218
221
  }
219
- };
220
- rl.on('line', (input) => {
221
- processLine(input).catch((err) => {
222
- printError(String(err));
223
- prompt();
224
- });
225
- });
226
- rl.on('close', () => {
227
- if (state.running) {
228
- // Unexpected close - don't exit, restart readline
222
+ // Handle Enter
223
+ if (key.name === 'return') {
224
+ if (menuVisible && filteredCommands.length > 0) {
225
+ // Select from menu
226
+ clearMenu(filteredCommands.length + 2);
227
+ menuVisible = false;
228
+ const selected = filteredCommands[selectedIndex];
229
+ currentInput = '/' + selected.name;
230
+ readline.clearLine(process.stdout, 0);
231
+ readline.cursorTo(process.stdout, 0);
232
+ process.stdout.write(promptStr() + currentInput);
233
+ }
234
+ // Submit
235
+ if (menuVisible) {
236
+ clearMenu(filteredCommands.length + 2);
237
+ menuVisible = false;
238
+ }
229
239
  console.log();
230
- printWarning('Input stream interrupted, restarting...');
231
- // Recreate readline interface with Tab autocomplete
232
- const newRl = readline.createInterface({
233
- input: process.stdin,
234
- output: process.stdout,
235
- terminal: true,
236
- completer: completer,
237
- });
238
- newRl.on('line', (input) => {
239
- processLine(input).catch((err) => {
240
- printError(String(err));
241
- prompt();
242
- });
243
- });
244
- newRl.on('close', () => {
245
- if (!state.running) {
246
- printGoodbye();
247
- process.exit(0);
240
+ await processInput(currentInput);
241
+ currentInput = '';
242
+ selectedIndex = 0;
243
+ filteredCommands = [];
244
+ if (state.running) {
245
+ console.log();
246
+ process.stdout.write(promptStr());
247
+ }
248
+ else {
249
+ process.stdin.setRawMode(false);
250
+ process.exit(0);
251
+ }
252
+ return;
253
+ }
254
+ // Handle Tab - autocomplete
255
+ if (key.name === 'tab') {
256
+ if (filteredCommands.length > 0) {
257
+ if (menuVisible) {
258
+ clearMenu(filteredCommands.length + 2);
248
259
  }
249
- });
250
- console.log();
251
- prompt();
260
+ const selected = filteredCommands[selectedIndex];
261
+ currentInput = '/' + selected.name + ' ';
262
+ menuVisible = false;
263
+ filteredCommands = [];
264
+ readline.clearLine(process.stdout, 0);
265
+ readline.cursorTo(process.stdout, 0);
266
+ process.stdout.write(promptStr() + currentInput);
267
+ }
268
+ return;
252
269
  }
253
- else {
254
- printGoodbye();
255
- process.exit(0);
270
+ // Handle Escape - close menu
271
+ if (key.name === 'escape') {
272
+ if (menuVisible) {
273
+ clearMenu(filteredCommands.length + 2);
274
+ menuVisible = false;
275
+ filteredCommands = [];
276
+ }
277
+ return;
256
278
  }
257
- });
258
- // Handle SIGINT (Ctrl+C)
259
- process.on('SIGINT', () => {
260
- console.log();
261
- state.running = false;
262
- rl.close();
279
+ // Handle Up arrow
280
+ if (key.name === 'up') {
281
+ if (menuVisible && selectedIndex > 0) {
282
+ clearMenu(filteredCommands.length + 2);
283
+ selectedIndex--;
284
+ renderMenu();
285
+ }
286
+ return;
287
+ }
288
+ // Handle Down arrow
289
+ if (key.name === 'down') {
290
+ if (menuVisible && selectedIndex < filteredCommands.length - 1) {
291
+ clearMenu(filteredCommands.length + 2);
292
+ selectedIndex++;
293
+ renderMenu();
294
+ }
295
+ return;
296
+ }
297
+ // Handle Backspace
298
+ if (key.name === 'backspace') {
299
+ if (currentInput.length > 0) {
300
+ if (menuVisible) {
301
+ clearMenu(filteredCommands.length + 2);
302
+ }
303
+ currentInput = currentInput.slice(0, -1);
304
+ readline.clearLine(process.stdout, 0);
305
+ readline.cursorTo(process.stdout, 0);
306
+ process.stdout.write(promptStr() + currentInput);
307
+ // Update menu
308
+ filteredCommands = filterCommands(currentInput);
309
+ selectedIndex = 0;
310
+ menuVisible = currentInput.startsWith('/') && filteredCommands.length > 0;
311
+ if (menuVisible) {
312
+ renderMenu();
313
+ }
314
+ }
315
+ return;
316
+ }
317
+ // Regular character input
318
+ if (str && str.length === 1 && !key.ctrl && !key.meta) {
319
+ if (menuVisible) {
320
+ clearMenu(filteredCommands.length + 2);
321
+ }
322
+ currentInput += str;
323
+ readline.clearLine(process.stdout, 0);
324
+ readline.cursorTo(process.stdout, 0);
325
+ process.stdout.write(promptStr() + currentInput);
326
+ // Show menu when typing /
327
+ filteredCommands = filterCommands(currentInput);
328
+ selectedIndex = 0;
329
+ menuVisible = currentInput.startsWith('/') && filteredCommands.length > 0;
330
+ if (menuVisible) {
331
+ renderMenu();
332
+ }
333
+ }
334
+ };
335
+ process.stdin.on('keypress', handleKeypress);
336
+ // Keep process alive
337
+ await new Promise((resolve) => {
338
+ const checkRunning = setInterval(() => {
339
+ if (!state.running) {
340
+ clearInterval(checkRunning);
341
+ resolve();
342
+ }
343
+ }, 100);
263
344
  });
264
345
  }
265
346
  /**
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Interactive Autocomplete Input for ArchiCore CLI
3
+ *
4
+ * Shows command suggestions in real-time as user types,
5
+ * similar to Claude's terminal interface.
6
+ *
7
+ * Works on Linux, Windows, and macOS.
8
+ */
9
+ import * as readline from 'readline';
10
+ export interface CommandItem {
11
+ name: string;
12
+ aliases: string[];
13
+ description: string;
14
+ }
15
+ export interface AutocompleteOptions {
16
+ commands: CommandItem[];
17
+ prompt?: string;
18
+ placeholder?: string;
19
+ }
20
+ /**
21
+ * Create an interactive input with autocomplete
22
+ */
23
+ export declare function createAutocompleteInput(options: AutocompleteOptions): Promise<string>;
24
+ /**
25
+ * Simple readline-based input with inline suggestions
26
+ * More compatible fallback for environments where raw mode doesn't work well
27
+ */
28
+ export declare function createSimpleAutocomplete(rl: readline.Interface, commands: CommandItem[], prompt: string): void;
29
+ //# sourceMappingURL=autocomplete.d.ts.map
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Interactive Autocomplete Input for ArchiCore CLI
3
+ *
4
+ * Shows command suggestions in real-time as user types,
5
+ * similar to Claude's terminal interface.
6
+ *
7
+ * Works on Linux, Windows, and macOS.
8
+ */
9
+ import * as readline from 'readline';
10
+ import { colors } from './colors.js';
11
+ /**
12
+ * Create an interactive input with autocomplete
13
+ */
14
+ export function createAutocompleteInput(options) {
15
+ return new Promise((resolve) => {
16
+ const { commands, prompt = '> ' } = options;
17
+ const state = {
18
+ input: '',
19
+ cursorPos: 0,
20
+ selectedIndex: 0,
21
+ filteredCommands: [],
22
+ showMenu: false,
23
+ };
24
+ // Filter commands based on input
25
+ const filterCommands = (input) => {
26
+ if (!input.startsWith('/'))
27
+ return [];
28
+ const query = input.slice(1).toLowerCase();
29
+ if (!query) {
30
+ return commands.slice(0, 8); // Show first 8 commands
31
+ }
32
+ return commands.filter(cmd => cmd.name.toLowerCase().startsWith(query) ||
33
+ cmd.aliases.some(a => a.toLowerCase().startsWith(query))).slice(0, 8);
34
+ };
35
+ // Render the current state
36
+ const render = () => {
37
+ // Clear previous output
38
+ readline.clearLine(process.stdout, 0);
39
+ readline.cursorTo(process.stdout, 0);
40
+ // Render prompt and input
41
+ const displayPrompt = colors.primary(prompt);
42
+ process.stdout.write(displayPrompt + state.input);
43
+ // If showing menu, render it below
44
+ if (state.showMenu && state.filteredCommands.length > 0) {
45
+ console.log(); // New line for menu
46
+ for (let i = 0; i < state.filteredCommands.length; i++) {
47
+ const cmd = state.filteredCommands[i];
48
+ const isSelected = i === state.selectedIndex;
49
+ const cmdName = `/${cmd.name}`.padEnd(18);
50
+ const desc = cmd.description;
51
+ if (isSelected) {
52
+ console.log(` ${colors.menuItemSelected(cmdName)} ${colors.muted(desc)}`);
53
+ }
54
+ else {
55
+ console.log(` ${colors.menuItem(cmdName)} ${colors.menuDescription(desc)}`);
56
+ }
57
+ }
58
+ // Hint at bottom
59
+ console.log(colors.dim(' ↑↓ navigate • Tab/Enter select • Esc cancel'));
60
+ // Move cursor back to input line
61
+ const menuLines = state.filteredCommands.length + 2;
62
+ readline.moveCursor(process.stdout, 0, -menuLines);
63
+ readline.cursorTo(process.stdout, prompt.length + state.cursorPos);
64
+ }
65
+ };
66
+ // Clear the menu from display
67
+ const clearMenu = () => {
68
+ if (state.showMenu && state.filteredCommands.length > 0) {
69
+ const menuLines = state.filteredCommands.length + 2;
70
+ for (let i = 0; i < menuLines; i++) {
71
+ readline.moveCursor(process.stdout, 0, 1);
72
+ readline.clearLine(process.stdout, 0);
73
+ }
74
+ readline.moveCursor(process.stdout, 0, -menuLines);
75
+ }
76
+ };
77
+ // Update state based on input
78
+ const updateState = () => {
79
+ state.filteredCommands = filterCommands(state.input);
80
+ state.showMenu = state.input.startsWith('/') && state.filteredCommands.length > 0;
81
+ state.selectedIndex = Math.min(state.selectedIndex, Math.max(0, state.filteredCommands.length - 1));
82
+ };
83
+ // Handle selection
84
+ const selectItem = () => {
85
+ if (state.filteredCommands.length > 0 && state.selectedIndex < state.filteredCommands.length) {
86
+ const selected = state.filteredCommands[state.selectedIndex];
87
+ state.input = '/' + selected.name + ' ';
88
+ state.cursorPos = state.input.length;
89
+ state.showMenu = false;
90
+ state.filteredCommands = [];
91
+ }
92
+ };
93
+ // Set up raw mode for keystroke capture
94
+ if (process.stdin.isTTY) {
95
+ process.stdin.setRawMode(true);
96
+ }
97
+ process.stdin.resume();
98
+ process.stdin.setEncoding('utf8');
99
+ // Initial render
100
+ process.stdout.write(colors.primary(prompt));
101
+ const handleKeypress = (key) => {
102
+ const code = key.charCodeAt(0);
103
+ // Ctrl+C - exit
104
+ if (key === '\x03') {
105
+ clearMenu();
106
+ console.log();
107
+ process.stdin.setRawMode(false);
108
+ process.exit(0);
109
+ }
110
+ // Enter - submit or select
111
+ if (key === '\r' || key === '\n') {
112
+ if (state.showMenu && state.filteredCommands.length > 0) {
113
+ clearMenu();
114
+ selectItem();
115
+ render();
116
+ }
117
+ else {
118
+ clearMenu();
119
+ console.log();
120
+ process.stdin.setRawMode(false);
121
+ process.stdin.removeListener('data', handleKeypress);
122
+ resolve(state.input);
123
+ }
124
+ return;
125
+ }
126
+ // Tab - autocomplete
127
+ if (key === '\t') {
128
+ if (state.showMenu && state.filteredCommands.length > 0) {
129
+ clearMenu();
130
+ selectItem();
131
+ render();
132
+ }
133
+ return;
134
+ }
135
+ // Escape - close menu or clear input
136
+ if (key === '\x1b' || key === '\x1b\x1b') {
137
+ if (state.showMenu) {
138
+ clearMenu();
139
+ state.showMenu = false;
140
+ render();
141
+ }
142
+ else if (state.input) {
143
+ clearMenu();
144
+ state.input = '';
145
+ state.cursorPos = 0;
146
+ updateState();
147
+ render();
148
+ }
149
+ return;
150
+ }
151
+ // Arrow keys (escape sequences)
152
+ if (key.startsWith('\x1b[')) {
153
+ const seq = key.slice(2);
154
+ // Up arrow
155
+ if (seq === 'A') {
156
+ if (state.showMenu && state.selectedIndex > 0) {
157
+ clearMenu();
158
+ state.selectedIndex--;
159
+ render();
160
+ }
161
+ return;
162
+ }
163
+ // Down arrow
164
+ if (seq === 'B') {
165
+ if (state.showMenu && state.selectedIndex < state.filteredCommands.length - 1) {
166
+ clearMenu();
167
+ state.selectedIndex++;
168
+ render();
169
+ }
170
+ return;
171
+ }
172
+ // Left arrow
173
+ if (seq === 'D') {
174
+ if (state.cursorPos > 0) {
175
+ state.cursorPos--;
176
+ readline.cursorTo(process.stdout, prompt.length + state.cursorPos);
177
+ }
178
+ return;
179
+ }
180
+ // Right arrow
181
+ if (seq === 'C') {
182
+ if (state.cursorPos < state.input.length) {
183
+ state.cursorPos++;
184
+ readline.cursorTo(process.stdout, prompt.length + state.cursorPos);
185
+ }
186
+ return;
187
+ }
188
+ return;
189
+ }
190
+ // Backspace
191
+ if (key === '\x7f' || key === '\b') {
192
+ if (state.cursorPos > 0) {
193
+ clearMenu();
194
+ state.input = state.input.slice(0, state.cursorPos - 1) + state.input.slice(state.cursorPos);
195
+ state.cursorPos--;
196
+ updateState();
197
+ render();
198
+ }
199
+ return;
200
+ }
201
+ // Regular character
202
+ if (code >= 32 && code < 127) {
203
+ clearMenu();
204
+ state.input = state.input.slice(0, state.cursorPos) + key + state.input.slice(state.cursorPos);
205
+ state.cursorPos++;
206
+ state.selectedIndex = 0; // Reset selection on new input
207
+ updateState();
208
+ render();
209
+ return;
210
+ }
211
+ };
212
+ process.stdin.on('data', handleKeypress);
213
+ });
214
+ }
215
+ /**
216
+ * Simple readline-based input with inline suggestions
217
+ * More compatible fallback for environments where raw mode doesn't work well
218
+ */
219
+ export function createSimpleAutocomplete(rl, commands, prompt) {
220
+ // This is used as the completer function for readline
221
+ const completer = (line) => {
222
+ if (line.startsWith('/')) {
223
+ const allCommands = [];
224
+ for (const cmd of commands) {
225
+ allCommands.push('/' + cmd.name);
226
+ for (const alias of cmd.aliases) {
227
+ allCommands.push('/' + alias);
228
+ }
229
+ }
230
+ const hits = allCommands.filter(c => c.startsWith(line));
231
+ if (hits.length > 1) {
232
+ console.log();
233
+ for (const hit of hits) {
234
+ const cmdName = hit.slice(1);
235
+ const cmd = commands.find(c => c.name === cmdName || c.aliases.includes(cmdName));
236
+ if (cmd) {
237
+ console.log(` ${colors.menuItem(hit.padEnd(18))} ${colors.menuDescription(cmd.description)}`);
238
+ }
239
+ }
240
+ console.log();
241
+ process.stdout.write(prompt + line);
242
+ }
243
+ return [hits, line];
244
+ }
245
+ return [[], line];
246
+ };
247
+ // Return the completer function
248
+ rl._completer = completer;
249
+ }
250
+ //# sourceMappingURL=autocomplete.js.map
@@ -19,6 +19,9 @@ export declare const colors: {
19
19
  brand: import("chalk").ChalkInstance;
20
20
  link: import("chalk").ChalkInstance;
21
21
  code: import("chalk").ChalkInstance;
22
+ menuItem: import("chalk").ChalkInstance;
23
+ menuItemSelected: import("chalk").ChalkInstance;
24
+ menuDescription: import("chalk").ChalkInstance;
22
25
  };
23
26
  export declare const icons: {
24
27
  success: string;
@@ -3,28 +3,32 @@
3
3
  */
4
4
  import chalk from 'chalk';
5
5
  export const colors = {
6
- // Primary colors
7
- primary: chalk.hex('#7C3AED'), // Purple
8
- secondary: chalk.hex('#06B6D4'), // Cyan
9
- accent: chalk.hex('#F59E0B'), // Amber
6
+ // Primary colors - ArchiCore brand (sky blue from logo #0ea5e9)
7
+ primary: chalk.hex('#0ea5e9'), // Sky Blue (logo color)
8
+ secondary: chalk.hex('#38bdf8'), // Lighter Sky Blue
9
+ accent: chalk.hex('#7dd3fc'), // Even lighter for accents
10
10
  // Status colors
11
- success: chalk.hex('#10B981'), // Green
12
- warning: chalk.hex('#F59E0B'), // Amber
13
- error: chalk.hex('#EF4444'), // Red
14
- info: chalk.hex('#3B82F6'), // Blue
11
+ success: chalk.hex('#22c55e'), // Green
12
+ warning: chalk.hex('#f59e0b'), // Amber
13
+ error: chalk.hex('#ef4444'), // Red
14
+ info: chalk.hex('#0ea5e9'), // Sky Blue (same as primary)
15
15
  // Text colors
16
- dim: chalk.gray,
17
- muted: chalk.hex('#6B7280'),
16
+ dim: chalk.hex('#64748b'), // Slate
17
+ muted: chalk.hex('#94a3b8'), // Light slate
18
18
  highlight: chalk.bold.white,
19
19
  // Impact levels
20
- critical: chalk.hex('#DC2626'), // Red
21
- high: chalk.hex('#EA580C'), // Orange
22
- medium: chalk.hex('#CA8A04'), // Yellow
23
- low: chalk.hex('#16A34A'), // Green
20
+ critical: chalk.hex('#dc2626'), // Red
21
+ high: chalk.hex('#ea580c'), // Orange
22
+ medium: chalk.hex('#eab308'), // Yellow
23
+ low: chalk.hex('#22c55e'), // Green
24
24
  // Special
25
- brand: chalk.hex('#7C3AED').bold,
26
- link: chalk.hex('#3B82F6').underline,
27
- code: chalk.hex('#F472B6'), // Pink
25
+ brand: chalk.hex('#0ea5e9').bold, // Sky Blue bold
26
+ link: chalk.hex('#38bdf8').underline,
27
+ code: chalk.hex('#7dd3fc'), // Light sky blue
28
+ // Menu colors (for autocomplete)
29
+ menuItem: chalk.hex('#0ea5e9'),
30
+ menuItemSelected: chalk.hex('#0ea5e9').bold.inverse,
31
+ menuDescription: chalk.hex('#64748b'),
28
32
  };
29
33
  export const icons = {
30
34
  // Status
@@ -7,4 +7,5 @@ export * from './table.js';
7
7
  export * from './spinner.js';
8
8
  export * from './prompt.js';
9
9
  export * from './progress.js';
10
+ export * from './autocomplete.js';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -7,4 +7,5 @@ export * from './table.js';
7
7
  export * from './spinner.js';
8
8
  export * from './prompt.js';
9
9
  export * from './progress.js';
10
+ export * from './autocomplete.js';
10
11
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archicore",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "AI Software Architect - code analysis, impact prediction, semantic search",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -18,6 +18,8 @@
18
18
  },
19
19
  "scripts": {
20
20
  "build": "tsc",
21
+ "build:frontend": "node scripts/build-frontend.js",
22
+ "build:all": "npm run build && npm run build:frontend",
21
23
  "dev": "tsx watch src/index.ts",
22
24
  "start": "node dist/index.js",
23
25
  "server": "tsx src/server/index.ts",
@@ -93,7 +95,11 @@
93
95
  "@types/multer": "^2.0.0",
94
96
  "@types/node": "^22.10.2",
95
97
  "@types/pg": "^8.11.6",
98
+ "clean-css": "^5.3.3",
99
+ "html-minifier-terser": "^7.2.0",
100
+ "javascript-obfuscator": "^4.1.1",
96
101
  "tsx": "^4.19.2",
97
- "typescript": "^5.7.2"
102
+ "typescript": "^5.7.2",
103
+ "vite": "^5.4.11"
98
104
  }
99
105
  }