@staticpayload/zai-code 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +7 -17
- package/dist/cli.js.map +1 -1
- package/dist/interactive.d.ts +2 -0
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +286 -191
- package/dist/interactive.js.map +1 -1
- package/dist/tui/App.d.ts +11 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +159 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/CommandPalette.d.ts +17 -0
- package/dist/tui/CommandPalette.d.ts.map +1 -0
- package/dist/tui/CommandPalette.js +50 -0
- package/dist/tui/CommandPalette.js.map +1 -0
- package/dist/tui/Header.d.ts +8 -0
- package/dist/tui/Header.d.ts.map +1 -0
- package/dist/tui/Header.js +33 -0
- package/dist/tui/Header.js.map +1 -0
- package/dist/tui/InputBox.d.ts +13 -0
- package/dist/tui/InputBox.d.ts.map +1 -0
- package/dist/tui/InputBox.js +42 -0
- package/dist/tui/InputBox.js.map +1 -0
- package/dist/tui/OutputArea.d.ts +13 -0
- package/dist/tui/OutputArea.d.ts.map +1 -0
- package/dist/tui/OutputArea.js +26 -0
- package/dist/tui/OutputArea.js.map +1 -0
- package/dist/tui/entry.d.ts +2 -0
- package/dist/tui/entry.d.ts.map +1 -0
- package/dist/tui/entry.js +84 -0
- package/dist/tui/entry.js.map +1 -0
- package/dist/tui/index.d.ts +6 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +14 -0
- package/dist/tui/index.js.map +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -41,29 +41,23 @@ const apply_1 = require("./apply");
|
|
|
41
41
|
const workspace_1 = require("./workspace");
|
|
42
42
|
const session_1 = require("./session");
|
|
43
43
|
const workspace_model_1 = require("./workspace_model");
|
|
44
|
-
const ui_1 = require("./ui");
|
|
45
44
|
const settings_1 = require("./settings");
|
|
46
45
|
const path = __importStar(require("path"));
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
47
48
|
async function handleDefault() {
|
|
48
49
|
await (0, auth_1.ensureAuthenticated)();
|
|
49
50
|
const session = (0, session_1.getSession)();
|
|
50
51
|
const ws = (0, workspace_model_1.getWorkspace)(session.workingDirectory);
|
|
51
52
|
// Restore previous session
|
|
52
53
|
const restored = ws.restoreState();
|
|
53
|
-
// Get project name from directory
|
|
54
|
-
const projectName = path.basename(session.workingDirectory);
|
|
55
|
-
// Render startup - minimal
|
|
56
|
-
console.log((0, ui_1.renderStartup)(projectName));
|
|
57
|
-
// Restored message
|
|
58
|
-
if (restored) {
|
|
59
|
-
console.log((0, ui_1.dim)('Session restored.'));
|
|
60
|
-
console.log('');
|
|
61
|
-
}
|
|
62
54
|
// Mark first run complete
|
|
63
55
|
if ((0, settings_1.isFirstRun)()) {
|
|
64
56
|
(0, settings_1.markFirstRunComplete)();
|
|
65
57
|
}
|
|
66
58
|
await (0, interactive_1.startInteractive)({
|
|
59
|
+
projectName: path.basename(session.workingDirectory),
|
|
60
|
+
restored,
|
|
67
61
|
onExit: () => {
|
|
68
62
|
ws.saveState();
|
|
69
63
|
process.exit(0);
|
|
@@ -114,16 +108,12 @@ async function handleDoctor() {
|
|
|
114
108
|
console.log(`API key: ${hasKey ? 'configured' : 'not configured'}`);
|
|
115
109
|
console.log(`Node.js: ${process.version}`);
|
|
116
110
|
console.log(`Platform: ${process.platform}`);
|
|
117
|
-
const
|
|
118
|
-
const pathModule = await Promise.resolve().then(() => __importStar(require('path')));
|
|
119
|
-
const os = await Promise.resolve().then(() => __importStar(require('os')));
|
|
120
|
-
const configExists = fs.existsSync(pathModule.join(os.homedir(), '.zai'));
|
|
111
|
+
const configExists = fs.existsSync(path.join(os.homedir(), '.zai'));
|
|
121
112
|
console.log(`Config dir: ${configExists ? 'exists' : 'missing'}`);
|
|
122
|
-
const
|
|
123
|
-
const session = getSession();
|
|
113
|
+
const session = (0, session_1.getSession)();
|
|
124
114
|
let writable = false;
|
|
125
115
|
try {
|
|
126
|
-
const testFile =
|
|
116
|
+
const testFile = path.join(session.workingDirectory, '.zai-test');
|
|
127
117
|
fs.writeFileSync(testFile, 'test');
|
|
128
118
|
fs.unlinkSync(testFile);
|
|
129
119
|
writable = true;
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,+CAAiD;AACjD,iCAA4D;AAC5D,uCAAoD;AACpD,mCAAwC;AACxC,2CAAmE;AACnE,uCAAuC;AACvC,uDAAiD;AACjD,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/interactive.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../src/interactive.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../src/interactive.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AA4MD,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgMlF"}
|
package/dist/interactive.js
CHANGED
|
@@ -2,254 +2,349 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.startInteractive = startInteractive;
|
|
4
4
|
const session_1 = require("./session");
|
|
5
|
-
const ui_1 = require("./ui");
|
|
6
5
|
const orchestrator_1 = require("./orchestrator");
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
'
|
|
6
|
+
const git_1 = require("./git");
|
|
7
|
+
const settings_1 = require("./settings");
|
|
8
|
+
const profiles_1 = require("./profiles");
|
|
9
|
+
// Command definitions with descriptions
|
|
10
|
+
const COMMANDS = [
|
|
11
|
+
{ name: 'help', description: 'Show all commands' },
|
|
12
|
+
{ name: 'plan', description: 'Generate execution plan' },
|
|
13
|
+
{ name: 'generate', description: 'Create file changes' },
|
|
14
|
+
{ name: 'diff', description: 'Review pending changes' },
|
|
15
|
+
{ name: 'apply', description: 'Apply changes' },
|
|
16
|
+
{ name: 'undo', description: 'Rollback last operation' },
|
|
17
|
+
{ name: 'reset', description: 'Reset session state' },
|
|
18
|
+
{ name: 'exit', description: 'Exit zcode' },
|
|
19
|
+
{ name: 'mode', description: 'Set mode' },
|
|
20
|
+
{ name: 'dry-run', description: 'Toggle dry-run mode' },
|
|
21
|
+
{ name: 'profile', description: 'Manage profiles' },
|
|
22
|
+
{ name: 'settings', description: 'Open settings menu' },
|
|
23
|
+
{ name: 'context', description: 'Show current context' },
|
|
24
|
+
{ name: 'files', description: 'List open files' },
|
|
25
|
+
{ name: 'open', description: 'Add file to context' },
|
|
26
|
+
{ name: 'workspace', description: 'Show workspace info' },
|
|
27
|
+
{ name: 'git', description: 'Show git status' },
|
|
28
|
+
{ name: 'exec', description: 'Run shell command' },
|
|
29
|
+
{ name: 'history', description: 'View task history' },
|
|
30
|
+
{ name: 'doctor', description: 'System health check' },
|
|
31
|
+
{ name: 'decompose', description: 'Break task into steps' },
|
|
32
|
+
{ name: 'step', description: 'Plan current step' },
|
|
33
|
+
{ name: 'next', description: 'Complete and advance' },
|
|
34
|
+
{ name: 'skip', description: 'Skip current step' },
|
|
35
|
+
{ name: 'progress', description: 'Show task progress' },
|
|
36
|
+
];
|
|
37
|
+
// ANSI escape codes
|
|
38
|
+
const ESC = '\x1b';
|
|
39
|
+
const CSI = `${ESC}[`;
|
|
40
|
+
// Screen control
|
|
41
|
+
const screen = {
|
|
42
|
+
clear: () => process.stdout.write(`${CSI}2J${CSI}H`),
|
|
43
|
+
clearLine: () => process.stdout.write(`${CSI}2K`),
|
|
44
|
+
moveTo: (row, col) => process.stdout.write(`${CSI}${row};${col}H`),
|
|
45
|
+
moveUp: (n) => process.stdout.write(`${CSI}${n}A`),
|
|
46
|
+
moveDown: (n) => process.stdout.write(`${CSI}${n}B`),
|
|
47
|
+
saveCursor: () => process.stdout.write(`${ESC}7`),
|
|
48
|
+
restoreCursor: () => process.stdout.write(`${ESC}8`),
|
|
49
|
+
showCursor: () => process.stdout.write(`${CSI}?25h`),
|
|
50
|
+
hideCursor: () => process.stdout.write(`${CSI}?25l`),
|
|
36
51
|
};
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
52
|
+
// Colors
|
|
53
|
+
const c = {
|
|
54
|
+
reset: `${CSI}0m`,
|
|
55
|
+
dim: `${CSI}2m`,
|
|
56
|
+
bold: `${CSI}1m`,
|
|
57
|
+
cyan: `${CSI}36m`,
|
|
58
|
+
green: `${CSI}32m`,
|
|
59
|
+
yellow: `${CSI}33m`,
|
|
60
|
+
red: `${CSI}31m`,
|
|
61
|
+
inverse: `${CSI}7m`,
|
|
62
|
+
};
|
|
63
|
+
// Get terminal dimensions
|
|
64
|
+
function getTermSize() {
|
|
65
|
+
return {
|
|
66
|
+
rows: process.stdout.rows || 24,
|
|
67
|
+
cols: process.stdout.columns || 80,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// Render header
|
|
71
|
+
function renderHeader(projectName) {
|
|
72
|
+
const { cols } = getTermSize();
|
|
73
|
+
const session = (0, session_1.getSession)();
|
|
74
|
+
const gitInfo = (0, git_1.getGitInfo)(session.workingDirectory);
|
|
75
|
+
const model = (0, settings_1.getModel)().split('-').slice(1, 3).join('-');
|
|
76
|
+
const profile = (0, profiles_1.getActiveProfileName)() || 'custom';
|
|
77
|
+
const gitStatus = gitInfo.isRepo
|
|
78
|
+
? `${gitInfo.branch || '?'}${gitInfo.isDirty ? '*' : ''}`
|
|
79
|
+
: 'no-git';
|
|
80
|
+
const left = `${c.bold}${c.cyan}zai${c.reset}${c.dim}·code${c.reset} ${c.dim}${projectName}${c.reset}`;
|
|
81
|
+
const right = `${c.dim}${gitStatus} · ${model} · ${profile}${c.reset}`;
|
|
82
|
+
// Strip ANSI for length calculation
|
|
83
|
+
const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, '');
|
|
84
|
+
const leftLen = stripAnsi(left).length;
|
|
85
|
+
const rightLen = stripAnsi(right).length;
|
|
86
|
+
const padding = Math.max(0, cols - leftLen - rightLen - 2);
|
|
87
|
+
screen.moveTo(1, 1);
|
|
88
|
+
screen.clearLine();
|
|
89
|
+
process.stdout.write(`${left}${' '.repeat(padding)}${right}`);
|
|
90
|
+
// Separator line
|
|
91
|
+
screen.moveTo(2, 1);
|
|
92
|
+
screen.clearLine();
|
|
93
|
+
process.stdout.write(`${c.dim}${'─'.repeat(cols)}${c.reset}`);
|
|
94
|
+
}
|
|
95
|
+
// Render prompt
|
|
96
|
+
function renderPrompt(input) {
|
|
97
|
+
const { rows, cols } = getTermSize();
|
|
98
|
+
const session = (0, session_1.getSession)();
|
|
99
|
+
// State
|
|
100
|
+
const state = session.pendingActions || session.lastDiff ? 'pending' :
|
|
101
|
+
session.lastPlan?.length ? 'planned' : 'ready';
|
|
102
|
+
// Build prompt
|
|
103
|
+
const prompt = `${c.cyan}${session.mode}${c.reset}${session.dryRun ? `${c.yellow}(dry)${c.reset}` : ''}${c.dim}:${c.reset}${state}${c.bold}>${c.reset} `;
|
|
104
|
+
const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, '');
|
|
105
|
+
const promptLen = stripAnsi(prompt).length;
|
|
106
|
+
// Separator
|
|
107
|
+
screen.moveTo(rows - 1, 1);
|
|
108
|
+
screen.clearLine();
|
|
109
|
+
process.stdout.write(`${c.dim}${'─'.repeat(cols)}${c.reset}`);
|
|
110
|
+
// Prompt line
|
|
111
|
+
screen.moveTo(rows, 1);
|
|
112
|
+
screen.clearLine();
|
|
113
|
+
if (input) {
|
|
114
|
+
process.stdout.write(`${prompt}${input}`);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
process.stdout.write(`${prompt}${c.dim}Type / for commands...${c.reset}`);
|
|
118
|
+
}
|
|
119
|
+
// Position cursor
|
|
120
|
+
screen.moveTo(rows, promptLen + input.length + 1);
|
|
48
121
|
}
|
|
49
|
-
// Render
|
|
50
|
-
function
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
122
|
+
// Render command palette
|
|
123
|
+
function renderPalette(filter, selectedIndex) {
|
|
124
|
+
const { rows, cols } = getTermSize();
|
|
125
|
+
const query = filter.replace(/^\//, '').toLowerCase();
|
|
126
|
+
const filtered = COMMANDS.filter(cmd => cmd.name.startsWith(query)).slice(0, 8);
|
|
127
|
+
if (filtered.length === 0)
|
|
128
|
+
return 0;
|
|
129
|
+
const paletteTop = rows - 2 - filtered.length;
|
|
130
|
+
for (let i = 0; i < filtered.length; i++) {
|
|
131
|
+
const cmd = filtered[i];
|
|
132
|
+
const row = paletteTop + i;
|
|
133
|
+
const isSelected = i === selectedIndex;
|
|
134
|
+
screen.moveTo(row, 1);
|
|
135
|
+
screen.clearLine();
|
|
136
|
+
if (isSelected) {
|
|
137
|
+
process.stdout.write(`${c.inverse} ▸ /${cmd.name.padEnd(14)} ${cmd.description.substring(0, cols - 20)} ${c.reset}`);
|
|
62
138
|
}
|
|
63
139
|
else {
|
|
64
|
-
process.stdout.write(
|
|
140
|
+
process.stdout.write(` ${c.dim}/${cmd.name.padEnd(14)}${c.reset} ${c.dim}${cmd.description.substring(0, cols - 20)}${c.reset}`);
|
|
65
141
|
}
|
|
66
142
|
}
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
process.stdout.write(
|
|
143
|
+
// Hint line
|
|
144
|
+
screen.moveTo(rows - 2, 1);
|
|
145
|
+
screen.clearLine();
|
|
146
|
+
process.stdout.write(`${c.dim}↑↓ navigate · Enter select · Esc close${c.reset}`);
|
|
147
|
+
return filtered.length;
|
|
148
|
+
}
|
|
149
|
+
// Clear palette
|
|
150
|
+
function clearPalette(count) {
|
|
151
|
+
const { rows } = getTermSize();
|
|
152
|
+
const paletteTop = rows - 2 - count;
|
|
153
|
+
for (let i = 0; i <= count + 1; i++) {
|
|
154
|
+
screen.moveTo(paletteTop + i, 1);
|
|
155
|
+
screen.clearLine();
|
|
156
|
+
}
|
|
71
157
|
}
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
158
|
+
// Output buffer
|
|
159
|
+
let outputLines = [];
|
|
160
|
+
// Add output line
|
|
161
|
+
function addOutput(line) {
|
|
162
|
+
outputLines.push(line);
|
|
163
|
+
renderOutput();
|
|
164
|
+
}
|
|
165
|
+
// Render output area
|
|
166
|
+
function renderOutput() {
|
|
167
|
+
const { rows } = getTermSize();
|
|
168
|
+
const outputStart = 3;
|
|
169
|
+
const outputEnd = rows - 2;
|
|
170
|
+
const outputHeight = outputEnd - outputStart;
|
|
171
|
+
const visible = outputLines.slice(-outputHeight);
|
|
172
|
+
for (let i = 0; i < outputHeight; i++) {
|
|
173
|
+
screen.moveTo(outputStart + i, 1);
|
|
174
|
+
screen.clearLine();
|
|
175
|
+
if (visible[i]) {
|
|
176
|
+
process.stdout.write(visible[i]);
|
|
177
|
+
}
|
|
81
178
|
}
|
|
82
|
-
// Restore cursor position
|
|
83
|
-
process.stdout.write('\x1b[u');
|
|
84
179
|
}
|
|
85
|
-
// Main interactive loop
|
|
180
|
+
// Main interactive loop
|
|
86
181
|
async function startInteractive(options) {
|
|
87
|
-
|
|
88
|
-
let
|
|
89
|
-
let
|
|
90
|
-
let
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
182
|
+
const projectName = options?.projectName || 'project';
|
|
183
|
+
let input = '';
|
|
184
|
+
let showPalette = false;
|
|
185
|
+
let paletteIndex = 0;
|
|
186
|
+
let paletteCount = 0;
|
|
187
|
+
// Initial render
|
|
188
|
+
screen.clear();
|
|
189
|
+
renderHeader(projectName);
|
|
190
|
+
if (options?.restored) {
|
|
191
|
+
addOutput(`${c.dim}Session restored.${c.reset}`);
|
|
192
|
+
}
|
|
193
|
+
addOutput(`${c.dim}Type / for commands, or enter a task${c.reset}`);
|
|
194
|
+
renderOutput();
|
|
195
|
+
renderPrompt(input);
|
|
196
|
+
// Enable raw mode
|
|
101
197
|
if (process.stdin.isTTY) {
|
|
102
198
|
process.stdin.setRawMode(true);
|
|
103
199
|
}
|
|
104
200
|
process.stdin.resume();
|
|
105
201
|
process.stdin.setEncoding('utf8');
|
|
106
|
-
|
|
202
|
+
screen.showCursor();
|
|
107
203
|
const handleKey = async (key) => {
|
|
108
|
-
|
|
109
|
-
const prompt = (0, ui_1.getPrompt)(session);
|
|
110
|
-
const promptLen = prompt.length + currentInput.length;
|
|
111
|
-
// Ctrl+C - exit
|
|
204
|
+
// Ctrl+C
|
|
112
205
|
if (key === '\x03') {
|
|
206
|
+
screen.clear();
|
|
207
|
+
screen.moveTo(1, 1);
|
|
208
|
+
screen.showCursor();
|
|
113
209
|
if (process.stdin.isTTY)
|
|
114
210
|
process.stdin.setRawMode(false);
|
|
115
|
-
process.stdout.write('\n');
|
|
116
211
|
options?.onExit?.();
|
|
117
212
|
return;
|
|
118
213
|
}
|
|
119
|
-
// Escape
|
|
120
|
-
if (key === '\x1b' &&
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
214
|
+
// Escape
|
|
215
|
+
if (key === '\x1b' && showPalette) {
|
|
216
|
+
clearPalette(paletteCount);
|
|
217
|
+
showPalette = false;
|
|
218
|
+
paletteIndex = 0;
|
|
219
|
+
paletteCount = 0;
|
|
220
|
+
renderPrompt(input);
|
|
125
221
|
return;
|
|
126
222
|
}
|
|
127
|
-
// Up arrow
|
|
128
|
-
if (key === '\x1b[A' &&
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
223
|
+
// Up arrow
|
|
224
|
+
if (key === '\x1b[A' && showPalette) {
|
|
225
|
+
paletteIndex = Math.max(0, paletteIndex - 1);
|
|
226
|
+
paletteCount = renderPalette(input, paletteIndex);
|
|
227
|
+
renderPrompt(input);
|
|
132
228
|
return;
|
|
133
229
|
}
|
|
134
|
-
// Down arrow
|
|
135
|
-
if (key === '\x1b[B' &&
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
230
|
+
// Down arrow
|
|
231
|
+
if (key === '\x1b[B' && showPalette) {
|
|
232
|
+
paletteIndex = Math.min(paletteCount - 1, paletteIndex + 1);
|
|
233
|
+
paletteCount = renderPalette(input, paletteIndex);
|
|
234
|
+
renderPrompt(input);
|
|
139
235
|
return;
|
|
140
236
|
}
|
|
141
|
-
// Tab - autocomplete
|
|
142
|
-
if (key === '\t' &&
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
237
|
+
// Tab - autocomplete
|
|
238
|
+
if (key === '\t' && showPalette && paletteCount > 0) {
|
|
239
|
+
const query = input.replace(/^\//, '').toLowerCase();
|
|
240
|
+
const filtered = COMMANDS.filter(cmd => cmd.name.startsWith(query));
|
|
241
|
+
if (filtered[paletteIndex]) {
|
|
242
|
+
input = `/${filtered[paletteIndex].name} `;
|
|
243
|
+
clearPalette(paletteCount);
|
|
244
|
+
showPalette = false;
|
|
245
|
+
paletteIndex = 0;
|
|
246
|
+
paletteCount = 0;
|
|
247
|
+
renderPrompt(input);
|
|
248
|
+
}
|
|
151
249
|
return;
|
|
152
250
|
}
|
|
153
|
-
// Enter
|
|
251
|
+
// Enter
|
|
154
252
|
if (key === '\r' || key === '\n') {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
// Submit input
|
|
168
|
-
clearSuggestions(suggestions.length);
|
|
169
|
-
process.stdout.write('\n');
|
|
170
|
-
const input = currentInput.trim();
|
|
171
|
-
currentInput = '';
|
|
172
|
-
showingSuggestions = false;
|
|
173
|
-
suggestions = [];
|
|
174
|
-
selectedIndex = 0;
|
|
175
|
-
// Handle exit
|
|
176
|
-
if (input === 'exit' || input === 'quit' || input === ':q' || input === '/exit') {
|
|
177
|
-
if (process.stdin.isTTY)
|
|
178
|
-
process.stdin.setRawMode(false);
|
|
179
|
-
options?.onExit?.();
|
|
180
|
-
return;
|
|
253
|
+
// Select from palette
|
|
254
|
+
if (showPalette && paletteCount > 0) {
|
|
255
|
+
const query = input.replace(/^\//, '').toLowerCase();
|
|
256
|
+
const filtered = COMMANDS.filter(cmd => cmd.name.startsWith(query));
|
|
257
|
+
if (filtered[paletteIndex]) {
|
|
258
|
+
input = `/${filtered[paletteIndex].name}`;
|
|
259
|
+
}
|
|
260
|
+
clearPalette(paletteCount);
|
|
261
|
+
showPalette = false;
|
|
262
|
+
paletteIndex = 0;
|
|
263
|
+
paletteCount = 0;
|
|
181
264
|
}
|
|
182
|
-
//
|
|
183
|
-
|
|
265
|
+
// Submit
|
|
266
|
+
const trimmed = input.trim();
|
|
267
|
+
input = '';
|
|
268
|
+
if (trimmed) {
|
|
269
|
+
addOutput(`${c.dim}> ${trimmed}${c.reset}`);
|
|
270
|
+
// Exit
|
|
271
|
+
if (trimmed === '/exit' || trimmed === 'exit' || trimmed === 'quit') {
|
|
272
|
+
screen.clear();
|
|
273
|
+
screen.moveTo(1, 1);
|
|
274
|
+
screen.showCursor();
|
|
275
|
+
if (process.stdin.isTTY)
|
|
276
|
+
process.stdin.setRawMode(false);
|
|
277
|
+
options?.onExit?.();
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
// Process command
|
|
281
|
+
const originalLog = console.log;
|
|
282
|
+
console.log = (...args) => {
|
|
283
|
+
addOutput(args.map(a => String(a)).join(' '));
|
|
284
|
+
};
|
|
184
285
|
try {
|
|
185
|
-
await (0, orchestrator_1.orchestrate)(
|
|
286
|
+
await (0, orchestrator_1.orchestrate)(trimmed);
|
|
186
287
|
}
|
|
187
288
|
catch (e) {
|
|
188
|
-
|
|
289
|
+
addOutput(`${c.red}Error: ${e}${c.reset}`);
|
|
189
290
|
}
|
|
291
|
+
console.log = originalLog;
|
|
292
|
+
renderHeader(projectName);
|
|
293
|
+
renderOutput();
|
|
190
294
|
}
|
|
191
|
-
|
|
192
|
-
console.log('');
|
|
193
|
-
printPrompt();
|
|
295
|
+
renderPrompt(input);
|
|
194
296
|
return;
|
|
195
297
|
}
|
|
196
298
|
// Backspace
|
|
197
299
|
if (key === '\x7f' || key === '\b') {
|
|
198
|
-
if (
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
selectedIndex = 0;
|
|
206
|
-
if (suggestions.length > 0) {
|
|
207
|
-
showingSuggestions = true;
|
|
208
|
-
const newPromptLen = prompt.length + currentInput.length;
|
|
209
|
-
renderSuggestions(suggestions, selectedIndex, newPromptLen);
|
|
210
|
-
}
|
|
211
|
-
else {
|
|
212
|
-
showingSuggestions = false;
|
|
213
|
-
}
|
|
300
|
+
if (input.length > 0) {
|
|
301
|
+
input = input.slice(0, -1);
|
|
302
|
+
if (input.startsWith('/')) {
|
|
303
|
+
clearPalette(paletteCount);
|
|
304
|
+
paletteIndex = 0;
|
|
305
|
+
paletteCount = renderPalette(input, paletteIndex);
|
|
306
|
+
showPalette = paletteCount > 0;
|
|
214
307
|
}
|
|
215
|
-
else {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
suggestions = [];
|
|
220
|
-
}
|
|
308
|
+
else if (showPalette) {
|
|
309
|
+
clearPalette(paletteCount);
|
|
310
|
+
showPalette = false;
|
|
311
|
+
paletteCount = 0;
|
|
221
312
|
}
|
|
313
|
+
renderPrompt(input);
|
|
222
314
|
}
|
|
223
315
|
return;
|
|
224
316
|
}
|
|
225
|
-
// Regular character
|
|
317
|
+
// Regular character
|
|
226
318
|
if (key.length === 1 && key >= ' ') {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
selectedIndex = 0;
|
|
234
|
-
if (suggestions.length > 0) {
|
|
235
|
-
showingSuggestions = true;
|
|
236
|
-
const newPromptLen = prompt.length + currentInput.length;
|
|
237
|
-
renderSuggestions(suggestions, selectedIndex, newPromptLen);
|
|
238
|
-
}
|
|
239
|
-
else {
|
|
240
|
-
showingSuggestions = false;
|
|
241
|
-
}
|
|
319
|
+
input += key;
|
|
320
|
+
if (input.startsWith('/')) {
|
|
321
|
+
clearPalette(paletteCount);
|
|
322
|
+
paletteIndex = 0;
|
|
323
|
+
paletteCount = renderPalette(input, paletteIndex);
|
|
324
|
+
showPalette = paletteCount > 0;
|
|
242
325
|
}
|
|
326
|
+
renderPrompt(input);
|
|
243
327
|
}
|
|
244
328
|
};
|
|
245
329
|
process.stdin.on('data', handleKey);
|
|
246
|
-
// Handle SIGINT
|
|
247
330
|
process.on('SIGINT', () => {
|
|
331
|
+
screen.clear();
|
|
332
|
+
screen.moveTo(1, 1);
|
|
333
|
+
screen.showCursor();
|
|
248
334
|
if (process.stdin.isTTY)
|
|
249
335
|
process.stdin.setRawMode(false);
|
|
250
|
-
process.stdout.write('\n');
|
|
251
336
|
options?.onExit?.();
|
|
252
337
|
});
|
|
338
|
+
// Handle terminal resize
|
|
339
|
+
process.stdout.on('resize', () => {
|
|
340
|
+
screen.clear();
|
|
341
|
+
renderHeader(projectName);
|
|
342
|
+
renderOutput();
|
|
343
|
+
if (showPalette) {
|
|
344
|
+
paletteCount = renderPalette(input, paletteIndex);
|
|
345
|
+
}
|
|
346
|
+
renderPrompt(input);
|
|
347
|
+
});
|
|
253
348
|
return new Promise(() => { });
|
|
254
349
|
}
|
|
255
350
|
//# sourceMappingURL=interactive.js.map
|