aoaoe 0.91.0 → 0.92.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/index.js CHANGED
@@ -16,7 +16,7 @@ import { wakeableSleep } from "./wake.js";
16
16
  import { classifyMessages, formatUserMessages, buildReceipts, shouldSkipSleep, hasPendingFile, isInsistMessage, stripInsistPrefix } from "./message.js";
17
17
  import { TaskManager, loadTaskDefinitions, loadTaskState, formatTaskTable } from "./task-manager.js";
18
18
  import { runTaskCli, handleTaskSlashCommand } from "./task-cli.js";
19
- import { TUI, hitTestSession, nextSortMode, SORT_MODES, formatUptime, formatClipText } from "./tui.js";
19
+ import { TUI, hitTestSession, nextSortMode, SORT_MODES, formatUptime, formatClipText, loadTuiPrefs, saveTuiPrefs } from "./tui.js";
20
20
  import { isDaemonRunningFromState } from "./chat.js";
21
21
  import { sendNotification, sendTestNotification } from "./notify.js";
22
22
  import { startHealthServer } from "./health.js";
@@ -171,6 +171,34 @@ async function main() {
171
171
  const pkg = readPkgVersion();
172
172
  const useTui = process.stdin.isTTY === true;
173
173
  const tui = useTui ? new TUI() : null;
174
+ // restore sticky prefs from previous run
175
+ if (tui) {
176
+ const prefs = loadTuiPrefs();
177
+ if (prefs.sortMode && SORT_MODES.includes(prefs.sortMode))
178
+ tui.setSortMode(prefs.sortMode);
179
+ if (prefs.compact)
180
+ tui.setCompact(true);
181
+ if (prefs.focus)
182
+ tui.setFocus(true);
183
+ if (prefs.bell)
184
+ tui.setBell(true);
185
+ if (prefs.autoPin)
186
+ tui.setAutoPin(true);
187
+ if (prefs.tagFilter)
188
+ tui.setTagFilter(prefs.tagFilter);
189
+ }
190
+ const persistPrefs = () => {
191
+ if (!tui)
192
+ return;
193
+ saveTuiPrefs({
194
+ sortMode: tui.getSortMode(),
195
+ compact: tui.isCompact(),
196
+ focus: tui.isFocused(),
197
+ bell: tui.isBellEnabled(),
198
+ autoPin: tui.isAutoPinEnabled(),
199
+ tagFilter: tui.getTagFilter(),
200
+ });
201
+ };
174
202
  if (!useTui) {
175
203
  // fallback: plain scrolling output (non-TTY / piped)
176
204
  console.error("");
@@ -363,11 +391,13 @@ async function main() {
363
391
  if (mode && SORT_MODES.includes(mode)) {
364
392
  tui.setSortMode(mode);
365
393
  tui.log("system", `sort: ${mode}`);
394
+ persistPrefs();
366
395
  }
367
396
  else if (!mode) {
368
397
  const next = nextSortMode(tui.getSortMode());
369
398
  tui.setSortMode(next);
370
399
  tui.log("system", `sort: ${next}`);
400
+ persistPrefs();
371
401
  }
372
402
  else {
373
403
  tui.log("system", `unknown sort mode: ${mode} (try: status, name, activity, default)`);
@@ -378,6 +408,7 @@ async function main() {
378
408
  const enabled = !tui.isCompact();
379
409
  tui.setCompact(enabled);
380
410
  tui.log("system", `compact mode: ${enabled ? "on" : "off"}`);
411
+ persistPrefs();
381
412
  });
382
413
  // wire /mark bookmark
383
414
  input.onMark(() => {
@@ -439,12 +470,14 @@ async function main() {
439
470
  const enabled = !tui.isFocused();
440
471
  tui.setFocus(enabled);
441
472
  tui.log("system", `focus mode: ${enabled ? "on (pinned only)" : "off (all sessions)"}`);
473
+ persistPrefs();
442
474
  });
443
475
  // wire /bell toggle
444
476
  input.onBell(() => {
445
477
  const enabled = !tui.isBellEnabled();
446
478
  tui.setBell(enabled);
447
479
  tui.log("system", `bell notifications: ${enabled ? "on" : "off"}`);
480
+ persistPrefs();
448
481
  });
449
482
  // wire /pin toggle
450
483
  input.onPin((target) => {
@@ -487,6 +520,7 @@ async function main() {
487
520
  else {
488
521
  tui.log("system", "filter cleared");
489
522
  }
523
+ persistPrefs();
490
524
  });
491
525
  // wire /uptime listing
492
526
  input.onUptime(() => {
@@ -509,6 +543,7 @@ async function main() {
509
543
  const enabled = !tui.isAutoPinEnabled();
510
544
  tui.setAutoPin(enabled);
511
545
  tui.log("system", `auto-pin on error: ${enabled ? "on" : "off"}`);
546
+ persistPrefs();
512
547
  });
513
548
  // wire /note set/clear
514
549
  input.onNote((target, text) => {
package/dist/tui.d.ts CHANGED
@@ -65,6 +65,18 @@ export declare function formatClipText(entries: readonly ActivityEntry[], n?: nu
65
65
  export declare function shouldAutoPin(tag: string): boolean;
66
66
  /** Format milliseconds as human-readable uptime: "2h 15m", "45m", "3d 2h", "< 1m". */
67
67
  export declare function formatUptime(ms: number): string;
68
+ export interface TuiPrefs {
69
+ sortMode?: string;
70
+ compact?: boolean;
71
+ focus?: boolean;
72
+ bell?: boolean;
73
+ autoPin?: boolean;
74
+ tagFilter?: string | null;
75
+ }
76
+ /** Load persisted TUI preferences. Returns empty object on any error. */
77
+ export declare function loadTuiPrefs(): TuiPrefs;
78
+ /** Save TUI preferences to disk. Silently ignores errors. */
79
+ export declare function saveTuiPrefs(prefs: TuiPrefs): void;
68
80
  export declare class TUI {
69
81
  private active;
70
82
  private countdownTimer;
package/dist/tui.js CHANGED
@@ -1,3 +1,16 @@
1
+ // tui.ts — block-style terminal UI for aoaoe daemon
2
+ // OpenCode-inspired design: box-drawn panels, 256-color palette, phase spinner,
3
+ // visual hierarchy. no external deps — raw ANSI escape codes only.
4
+ //
5
+ // layout (top to bottom):
6
+ // ┌─ header bar (1 row, BG_DARK) ─────────────────────────────────────────┐
7
+ // │ sessions panel (box-drawn, 1 row per session + 2 border rows) │
8
+ // ├─ separator with hints ────────────────────────────────────────────────┤
9
+ // │ activity scroll region (all daemon output scrolls here) │
10
+ // └─ input line (phase-aware prompt) ─────────────────────────────────────┘
11
+ import { readFileSync, writeFileSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { homedir } from "node:os";
1
14
  import { BOLD, DIM, RESET, GREEN, CYAN, WHITE, BG_DARK, BG_HOVER, INDIGO, TEAL, AMBER, SLATE, ROSE, LIME, SKY, BOX, SPINNER, DOT, } from "./colors.js";
2
15
  import { appendHistoryEntry } from "./tui-history.js";
3
16
  // ── ANSI helpers ────────────────────────────────────────────────────────────
@@ -223,7 +236,23 @@ export function formatUptime(ms) {
223
236
  return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
224
237
  return `${minutes}m`;
225
238
  }
226
- // ── TUI class ───────────────────────────────────────────────────────────────
239
+ const PREFS_PATH = join(homedir(), ".aoaoe", "tui-prefs.json");
240
+ /** Load persisted TUI preferences. Returns empty object on any error. */
241
+ export function loadTuiPrefs() {
242
+ try {
243
+ return JSON.parse(readFileSync(PREFS_PATH, "utf-8"));
244
+ }
245
+ catch {
246
+ return {};
247
+ }
248
+ }
249
+ /** Save TUI preferences to disk. Silently ignores errors. */
250
+ export function saveTuiPrefs(prefs) {
251
+ try {
252
+ writeFileSync(PREFS_PATH, JSON.stringify(prefs) + "\n", "utf-8");
253
+ }
254
+ catch { /* best effort */ }
255
+ }
227
256
  export class TUI {
228
257
  active = false;
229
258
  countdownTimer = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aoaoe",
3
- "version": "0.91.0",
3
+ "version": "0.92.0",
4
4
  "description": "Autonomous supervisor for agent-of-empires sessions using OpenCode or Claude Code",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",