aoaoe 0.89.0 → 0.90.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 +26 -1
- package/dist/input.d.ts +3 -0
- package/dist/input.js +20 -0
- package/dist/tui.d.ts +6 -0
- package/dist/tui.js +13 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
2
3
|
import { loadConfig, validateEnvironment, parseCliArgs, printHelp, configFileExists, findConfigFile, DEFAULTS, computeConfigDiff } from "./config.js";
|
|
3
4
|
import { Poller, computeTmuxName } from "./poller.js";
|
|
4
5
|
import { createReasoner } from "./reasoner/index.js";
|
|
@@ -15,7 +16,7 @@ import { wakeableSleep } from "./wake.js";
|
|
|
15
16
|
import { classifyMessages, formatUserMessages, buildReceipts, shouldSkipSleep, hasPendingFile, isInsistMessage, stripInsistPrefix } from "./message.js";
|
|
16
17
|
import { TaskManager, loadTaskDefinitions, loadTaskState, formatTaskTable } from "./task-manager.js";
|
|
17
18
|
import { runTaskCli, handleTaskSlashCommand } from "./task-cli.js";
|
|
18
|
-
import { TUI, hitTestSession, nextSortMode, SORT_MODES, formatUptime } from "./tui.js";
|
|
19
|
+
import { TUI, hitTestSession, nextSortMode, SORT_MODES, formatUptime, formatClipText } from "./tui.js";
|
|
19
20
|
import { isDaemonRunningFromState } from "./chat.js";
|
|
20
21
|
import { sendNotification, sendTestNotification } from "./notify.js";
|
|
21
22
|
import { startHealthServer } from "./health.js";
|
|
@@ -517,6 +518,30 @@ async function main() {
|
|
|
517
518
|
}
|
|
518
519
|
}
|
|
519
520
|
});
|
|
521
|
+
// wire /clip to export activity entries to clipboard or file
|
|
522
|
+
input.onClip((count) => {
|
|
523
|
+
const buffer = tui.getActivityBuffer();
|
|
524
|
+
if (buffer.length === 0) {
|
|
525
|
+
tui.log("system", "no activity to clip");
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
const text = formatClipText(buffer, count);
|
|
529
|
+
const entryCount = Math.min(count, buffer.length);
|
|
530
|
+
try {
|
|
531
|
+
execSync("pbcopy", { input: text, timeout: 5000 });
|
|
532
|
+
tui.log("system", `copied ${entryCount} entries to clipboard`);
|
|
533
|
+
}
|
|
534
|
+
catch {
|
|
535
|
+
try {
|
|
536
|
+
const clipPath = join(homedir(), ".aoaoe", "clip.txt");
|
|
537
|
+
writeFileSync(clipPath, text, "utf-8");
|
|
538
|
+
tui.log("system", `saved ${entryCount} entries to ~/.aoaoe/clip.txt`);
|
|
539
|
+
}
|
|
540
|
+
catch (writeErr) {
|
|
541
|
+
tui.log("error", `clip failed: ${writeErr}`);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
});
|
|
520
545
|
// wire mouse move to hover highlight on session cards (disabled in compact)
|
|
521
546
|
input.onMouseMove((row, _col) => {
|
|
522
547
|
if (tui.getViewMode() === "overview" && !tui.isCompact()) {
|
package/dist/input.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type UptimeHandler = () => void;
|
|
|
18
18
|
export type AutoPinHandler = () => void;
|
|
19
19
|
export type NoteHandler = (target: string, text: string) => void;
|
|
20
20
|
export type NotesHandler = () => void;
|
|
21
|
+
export type ClipHandler = (count: number) => void;
|
|
21
22
|
export interface MouseEvent {
|
|
22
23
|
button: number;
|
|
23
24
|
col: number;
|
|
@@ -58,6 +59,7 @@ export declare class InputReader {
|
|
|
58
59
|
private autoPinHandler;
|
|
59
60
|
private noteHandler;
|
|
60
61
|
private notesHandler;
|
|
62
|
+
private clipHandler;
|
|
61
63
|
private mouseDataListener;
|
|
62
64
|
onScroll(handler: (dir: ScrollDirection) => void): void;
|
|
63
65
|
onQueueChange(handler: (count: number) => void): void;
|
|
@@ -82,6 +84,7 @@ export declare class InputReader {
|
|
|
82
84
|
onAutoPin(handler: AutoPinHandler): void;
|
|
83
85
|
onNote(handler: NoteHandler): void;
|
|
84
86
|
onNotes(handler: NotesHandler): void;
|
|
87
|
+
onClip(handler: ClipHandler): void;
|
|
85
88
|
private notifyQueueChange;
|
|
86
89
|
start(): void;
|
|
87
90
|
drain(): string[];
|
package/dist/input.js
CHANGED
|
@@ -50,6 +50,7 @@ export class InputReader {
|
|
|
50
50
|
autoPinHandler = null;
|
|
51
51
|
noteHandler = null;
|
|
52
52
|
notesHandler = null;
|
|
53
|
+
clipHandler = null;
|
|
53
54
|
mouseDataListener = null;
|
|
54
55
|
// register a callback for scroll key events (PgUp/PgDn/Home/End)
|
|
55
56
|
onScroll(handler) {
|
|
@@ -143,6 +144,10 @@ export class InputReader {
|
|
|
143
144
|
onNotes(handler) {
|
|
144
145
|
this.notesHandler = handler;
|
|
145
146
|
}
|
|
147
|
+
// register a callback for clipboard export (/clip [N])
|
|
148
|
+
onClip(handler) {
|
|
149
|
+
this.clipHandler = handler;
|
|
150
|
+
}
|
|
146
151
|
notifyQueueChange() {
|
|
147
152
|
this.queueChangeHandler?.(this.queue.length);
|
|
148
153
|
}
|
|
@@ -332,6 +337,7 @@ ${BOLD}navigation:${RESET}
|
|
|
332
337
|
/auto-pin toggle auto-pin on error (pin sessions that emit errors)
|
|
333
338
|
/note N|name text attach a note to a session (no text = clear)
|
|
334
339
|
/notes list all session notes
|
|
340
|
+
/clip [N] copy last N activity entries to clipboard (default 20)
|
|
335
341
|
/mark bookmark current activity position
|
|
336
342
|
/jump N jump to bookmark N
|
|
337
343
|
/marks list all bookmarks
|
|
@@ -543,6 +549,20 @@ ${BOLD}other:${RESET}
|
|
|
543
549
|
console.error(`${DIM}notes not available (no TUI)${RESET}`);
|
|
544
550
|
}
|
|
545
551
|
break;
|
|
552
|
+
case "/clip": {
|
|
553
|
+
const clipArg = line.slice("/clip".length).trim();
|
|
554
|
+
const clipCount = clipArg ? parseInt(clipArg, 10) : 20;
|
|
555
|
+
if (this.clipHandler && !isNaN(clipCount) && clipCount > 0) {
|
|
556
|
+
this.clipHandler(clipCount);
|
|
557
|
+
}
|
|
558
|
+
else if (!this.clipHandler) {
|
|
559
|
+
console.error(`${DIM}clip not available (no TUI)${RESET}`);
|
|
560
|
+
}
|
|
561
|
+
else {
|
|
562
|
+
console.error(`${DIM}usage: /clip [N] — copy last N activity entries to clipboard${RESET}`);
|
|
563
|
+
}
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
546
566
|
case "/mark":
|
|
547
567
|
if (this.markHandler) {
|
|
548
568
|
this.markHandler();
|
package/dist/tui.d.ts
CHANGED
|
@@ -57,6 +57,10 @@ export declare function formatMuteBadge(count: number): string;
|
|
|
57
57
|
export declare function matchesTagFilter(entry: ActivityEntry, tag: string): boolean;
|
|
58
58
|
/** Format the tag filter indicator text for the separator bar. */
|
|
59
59
|
export declare function formatTagFilterIndicator(tag: string, matchCount: number, totalCount: number): string;
|
|
60
|
+
/** Default number of entries for /clip when no count specified. */
|
|
61
|
+
export declare const CLIP_DEFAULT_COUNT = 20;
|
|
62
|
+
/** Format activity entries as plain text for clipboard/export. One line per entry. */
|
|
63
|
+
export declare function formatClipText(entries: readonly ActivityEntry[], n?: number): string;
|
|
60
64
|
/** Determine if a log entry should trigger auto-pin (error-like tags). */
|
|
61
65
|
export declare function shouldAutoPin(tag: string): boolean;
|
|
62
66
|
/** Format milliseconds as human-readable uptime: "2h 15m", "45m", "3d 2h", "< 1m". */
|
|
@@ -175,6 +179,8 @@ export declare class TUI {
|
|
|
175
179
|
getUptime(id: string): number;
|
|
176
180
|
/** Return all session first-seen timestamps (for /uptime listing). */
|
|
177
181
|
getAllFirstSeen(): ReadonlyMap<string, number>;
|
|
182
|
+
/** Return the activity buffer (for /clip export). */
|
|
183
|
+
getActivityBuffer(): readonly ActivityEntry[];
|
|
178
184
|
/**
|
|
179
185
|
* Add a bookmark at the current activity position.
|
|
180
186
|
* Returns the bookmark number (1-indexed) or 0 if buffer is empty.
|
package/dist/tui.js
CHANGED
|
@@ -191,6 +191,15 @@ export function matchesTagFilter(entry, tag) {
|
|
|
191
191
|
export function formatTagFilterIndicator(tag, matchCount, totalCount) {
|
|
192
192
|
return `${SLATE}filter:${RESET} ${AMBER}${tag}${RESET} ${DIM}(${matchCount}/${totalCount})${RESET}`;
|
|
193
193
|
}
|
|
194
|
+
// ── Clip ─────────────────────────────────────────────────────────────────────
|
|
195
|
+
/** Default number of entries for /clip when no count specified. */
|
|
196
|
+
export const CLIP_DEFAULT_COUNT = 20;
|
|
197
|
+
/** Format activity entries as plain text for clipboard/export. One line per entry. */
|
|
198
|
+
export function formatClipText(entries, n) {
|
|
199
|
+
const count = n ?? CLIP_DEFAULT_COUNT;
|
|
200
|
+
const slice = entries.slice(-Math.max(1, count));
|
|
201
|
+
return slice.map((e) => `[${e.time}] ${e.tag}: ${e.text}`).join("\n") + "\n";
|
|
202
|
+
}
|
|
194
203
|
// ── Auto-pin ─────────────────────────────────────────────────────────────────
|
|
195
204
|
/** Determine if a log entry should trigger auto-pin (error-like tags). */
|
|
196
205
|
export function shouldAutoPin(tag) {
|
|
@@ -527,6 +536,10 @@ export class TUI {
|
|
|
527
536
|
getAllFirstSeen() {
|
|
528
537
|
return this.sessionFirstSeen;
|
|
529
538
|
}
|
|
539
|
+
/** Return the activity buffer (for /clip export). */
|
|
540
|
+
getActivityBuffer() {
|
|
541
|
+
return this.activityBuffer;
|
|
542
|
+
}
|
|
530
543
|
/**
|
|
531
544
|
* Add a bookmark at the current activity position.
|
|
532
545
|
* Returns the bookmark number (1-indexed) or 0 if buffer is empty.
|