aboutsummaryrefslogtreecommitdiff
path: root/modules/ext/ui-easy.js
blob: cd1388a6864bdd6aadc83f0e007307c31a517e71 (plain)
1
2
3
4
5
6
7
8
9
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// UI mode: easy (level 1). Nothing here parses commands; every button calls executeCommand.
class UIEasyMode {
    constructor() { this.commands = {}; this.terminal = null; }
    requirements() { return { met: true, missing: [] }; }
    getHelpInfo() { return {}; }
    registerCommands() {}
    init(terminal) {
        this.terminal = terminal;
        if (!terminal.uiShell) return;
        terminal.uiShell.registerMode({
            id: 'easy', label: 'Easy', level: 1, icon: '🌱',
            tagline: 'Just ask. No commands.',
            mount: (api) => this.mount(api)
        });
    }
    mount(api) {
        api.injectCSS('easy', `
body[data-ui-mode="easy"] { font-family: system-ui, -apple-system, "Segoe UI", sans-serif; }
/* padding-bottom 34px, not 0: #ui-foot is absolutely positioned and 34px tall, and the shorthand
   reset the bottom padding the base sheet reserves, so the footer sat on top of the composer. */
body[data-ui-mode="easy"] #ui-root { display: flex; flex-direction: column; padding: 14px 14px 34px; gap: 12px; }
#easy-top { flex: 0 0 auto; }
#easy-top h1 { font-size: 1.25em; margin: 0 0 4px; font-weight: 600; }
#easy-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px; }
#easy-actions .wx11-btn { display: flex; align-items: center; gap: 10px; font-size: 1em; min-height: 62px; }
#easy-actions .ico { font-size: 1.5em; line-height: 1; }
#easy-chat { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
#easy-chat .output-line { background: var(--bg-secondary); border: 1px solid var(--border-color);
  border-radius: 12px; padding: 10px 12px; font-family: inherit; font-size: .95em; line-height: 1.45;
  white-space: pre-wrap; word-break: break-word; }
#easy-chat .output-line.error { border-color: var(--error-color); }
#easy-chat .output-line.success { border-color: var(--accent-color); }
#easy-composer { flex: 0 0 auto; display: flex; gap: 8px; align-items: flex-end; }
#easy-composer #input-area { flex: 1 1 auto; display: flex; gap: 6px; align-items: flex-end; }
#easy-composer .prompt-label { display: none; }
#easy-composer #command-input { font-size: 1em; min-height: 48px; font-family: inherit; width: 100%; }
#easy-composer #autocomplete-dropdown { display: none; }
@media (max-width: 600px) { #easy-actions { grid-template-columns: 1fr; } }
`);

        const root = api.root;
        root.innerHTML = '';
        const top = api.el('div', { id: 'easy-top' });
        top.appendChild(api.el('h1', { text: 'Hi — what do you want to do?' }));
        top.appendChild(api.el('div', { class: 'wx11-dim', text: 'Tap a card, or just type below in plain language.' }));

        const styleBtn = api.el('button', { class: 'wx11-btn', text: '⇄ Change view' });
        styleBtn.style.cssText = 'margin-top:10px;width:100%;text-align:center';
        styleBtn.addEventListener('click', () => api.exec('ui picker'));
        top.appendChild(styleBtn);

        const actions = api.el('div', { id: 'easy-actions' });
        const cards = [
            { ico: '🤖', label: 'Ask the AI', run: () => api.exec('ai "hello — what can you help me with?"') },
            { ico: '📁', label: 'My files', run: () => api.exec('ls') },
            { ico: '🎓', label: 'Learn', run: () => api.exec('course') },
            { ico: '⚙️', label: 'Settings', run: () => api.exec('config') }
        ];
        cards.forEach(c => {
            const b = api.el('button', { class: 'wx11-btn' });
            b.appendChild(api.el('span', { class: 'ico', text: c.ico }));
            b.appendChild(api.el('span', { text: c.label }));
            b.addEventListener('click', c.run);
            actions.appendChild(b);
        });
        top.appendChild(actions);

        const chat = api.el('div', { id: 'easy-chat' });
        const composer = api.el('div', { id: 'easy-composer' });
        root.appendChild(top);
        root.appendChild(chat);
        root.appendChild(composer);

        // one output stream: the real terminal is restyled into bubbles inside #easy-chat
        api.attach(chat, api.stock.output);
        api.attach(composer, api.stock.input);
        const field = document.getElementById('command-input');
        if (field) field.placeholder = 'Ask anything…';

        return () => {
            const f = document.getElementById('command-input');
            if (f) f.placeholder = 'Type a command...';
        };
    }
}