feat(terminal): add system commands and DevTools bridge

This commit is contained in:
Codex committed 2026-09-28 14:20:12 +08:00
1 parent 78c1ffe1fd
commit 6972a00445
12 files changed
+120 -19

No files matched your search

+29 -2
View File
@@ -74,8 +74,9 @@ browserNodes['.browser-toolbar'].listeners.click({ target: { closest: () => ({ d
assert.equal(browserNodes.iframe.src, 'https://www.google.com/webhp?igu=1');
const terminalStorage = new Map(), terminalRenders = [];
const terminalContext = vm.createContext({
document: { createElement: () => ({ textContent: '' }), head: { append() {} } },
LifeI18n: { t: key => key }, lang: () => 'en',
document: { createElement: () => ({ textContent: '' }), head: { append() {} }, querySelector: () => null },
console: { info() {}, warn() {} },
LifeI18n: { t: key => key, dictionaries: { en: assets.localeEn, zh: assets.localeZh } }, lang: () => 'en',
APPS: { calendar: ['icon', 'CALENDAR'] }, openApp: id => terminalRenders.push(id),
crypto: globalThis.crypto, day: () => '2026-09-28',
mems: () => terminalStorage.get('lifeos_memories') || [],
@@ -118,6 +119,7 @@ assert.equal(terminalStorage.get('lifeos_memories').length, 2);
const terminalUiNodes = Object.fromEntries(['.terminal-output','.terminal-form','.terminal-compose','.terminal-input','.terminal-note','.terminal-shortcuts'].map(selector => [selector, { value: '', hidden: false, listeners: {}, children: [], focus() {}, addEventListener(type, handler) { this.listeners[type] = handler; }, replaceChildren() { this.children = []; }, append(child) { this.children.push(child); } }]));
const terminalUi = { innerHTML: '', dataset: {}, querySelector(selector) { return selector === '.terminal-shell' ? (this.innerHTML ? {} : null) : terminalUiNodes[selector]; } };
terminalContext.terminalApp(terminalUi);
assert.equal(terminalUiNodes['.terminal-output'].children[0].textContent, 'terminal.welcome', 'opening the terminal shows its welcome banner');
const submitTerminal = value => { terminalUiNodes['.terminal-input'].value = value; terminalUiNodes['.terminal-form'].listeners.submit({ preventDefault() {} }); };
submitTerminal('memory add "Via UI" --date 2026-10-01');
for (let index = 0; index < 5; index++) submitTerminal('');
@@ -126,6 +128,14 @@ terminalUiNodes['.terminal-note'].value = 'A note from the guided form';
terminalUiNodes['.terminal-compose'].listeners.click({ target: { closest: () => ({ dataset: { note: 'save' } }) } });
assert.equal(terminalStorage.get('lifeos_memories').find(item => item.date === '2026-10-01').text, 'A note from the guided form');
assert.equal(terminalUiNodes['.terminal-compose'].hidden, true);
submitTerminal('goal add "UI goal"');
submitTerminal(''); submitTerminal(''); submitTerminal('');
assert.match(terminalUiNodes['.terminal-output'].children.at(-1).textContent, /terminal\.flow\.confirmCreate/);
submitTerminal('yes');
assert.equal(terminalStorage.get('lifeos_system').tasksBoard.goals[0].title, 'UI goal');
submitTerminal('goal delete "UI goal"');
submitTerminal('yes');
assert.equal(terminalStorage.get('lifeos_system').tasksBoard.goals.some(item => item.title === 'UI goal'), false);
assert.match(command('goal add').message, /terminal\.flow\.title/);
assert.match(command('A guided goal').message, /terminal\.flow\.description/);
assert.match(command('').message, /terminal\.flow\.targetDate/);
@@ -158,6 +168,23 @@ terminalContext.LifeOSActions.createMemory({ date: '2026-10-02', title: 'Linked
assert.match(command('task delete 1').message, /terminal\.flow\.confirmDelete/);
assert.match(command('yes').message, /terminal\.flow\.deleted/);
assert.equal(terminalStorage.get('lifeos_memories').find(item => item.date === '2026-10-02').taskId, '');
assert.ok(command('date').message.length > 8);
assert.ok(command('time').message.includes(':'));
assert.ok(command('datetime').message.length > 12);
assert.equal(command('uptime').message, 'terminal.uptime');
assert.equal(command('version').message, 'Life OS v1.12.0');
assert.equal(command('status').message, 'terminal.status');
assert.match(command('apps').message, /calendar/);
assert.equal(command('echo "hello Life OS"').message, 'hello Life OS');
assert.match(terminalContext.LifeOS.help(), /memory add/);
assert.match(terminalContext.LifeOS.run('goal add'), /terminal\.flow\.title/);
assert.equal(terminalContext.LifeOS.cancel(), 'terminal.flow.cancelled');
assert.match(terminalContext.LifeOS.run('memory add "Console memory" --date 2026-10-03'), /terminal\.wizard\.tags/);
for (let index = 0; index < 5; index++) terminalContext.LifeOS.run('');
assert.equal(terminalContext.LifeOS.note('Created through DevTools'), 'terminal.memorySaved');
assert.equal(terminalStorage.get('lifeos_memories').find(item => item.date === '2026-10-03').text, 'Created through DevTools');
assert.equal(terminalContext.LifeOS.note('Again'), 'terminal.noNote');
assert.equal(terminalContext.LifeOS.run('window.alert(1)'), 'terminal.unknownCommand');
assert.equal(command('open calendar').message, 'terminal.opened');
assert.ok(terminalRenders.includes('calendar'));
assert.deepEqual(Array.from(terminalContext.LifeOSTerminalEngine.words('task add "quoted title" --priority high')), ['task','add','quoted title','--priority','high']);