aoaoe 0.56.0 → 0.57.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/README.md +4 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js +27 -2
- package/dist/console.d.ts +6 -0
- package/dist/console.js +19 -0
- package/dist/index.js +105 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -244,6 +244,10 @@ commands:
|
|
|
244
244
|
config --diff show only fields that differ from defaults
|
|
245
245
|
notify-test send a test notification to configured webhooks
|
|
246
246
|
doctor comprehensive health check (config, tools, daemon, disk)
|
|
247
|
+
logs show recent conversation log entries
|
|
248
|
+
logs --actions show action log entries (from ~/.aoaoe/actions.log)
|
|
249
|
+
logs --grep <pattern> filter log entries by substring or regex
|
|
250
|
+
logs -n <count> number of entries to show (default: 50)
|
|
247
251
|
task manage tasks and sessions (list, start, stop, new, rm, edit)
|
|
248
252
|
tasks show task progress (from aoaoe.tasks.json)
|
|
249
253
|
history review recent actions (from ~/.aoaoe/actions.log)
|
package/dist/config.d.ts
CHANGED
|
@@ -30,6 +30,10 @@ export declare function parseCliArgs(argv: string[]): {
|
|
|
30
30
|
configDiff: boolean;
|
|
31
31
|
notifyTest: boolean;
|
|
32
32
|
runDoctor: boolean;
|
|
33
|
+
runLogs: boolean;
|
|
34
|
+
logsActions: boolean;
|
|
35
|
+
logsGrep?: string;
|
|
36
|
+
logsCount?: number;
|
|
33
37
|
runInit: boolean;
|
|
34
38
|
initForce: boolean;
|
|
35
39
|
runTaskCli: boolean;
|
package/dist/config.js
CHANGED
|
@@ -299,7 +299,7 @@ export function parseCliArgs(argv) {
|
|
|
299
299
|
let initForce = false;
|
|
300
300
|
let runTaskCli = false;
|
|
301
301
|
let registerTitle;
|
|
302
|
-
const defaults = { overrides, help: false, version: false, register: false, testContext: false, runTest: false, showTasks: false, showHistory: false, showStatus: false, showConfig: false, configValidate: false, configDiff: false, notifyTest: false, runDoctor: false, runInit: false, initForce: false, runTaskCli: false };
|
|
302
|
+
const defaults = { overrides, help: false, version: false, register: false, testContext: false, runTest: false, showTasks: false, showHistory: false, showStatus: false, showConfig: false, configValidate: false, configDiff: false, notifyTest: false, runDoctor: false, runLogs: false, logsActions: false, logsGrep: undefined, logsCount: undefined, runInit: false, initForce: false, runTaskCli: false };
|
|
303
303
|
// check for subcommand as first non-flag arg
|
|
304
304
|
if (argv[2] === "test-context") {
|
|
305
305
|
return { ...defaults, testContext: true };
|
|
@@ -330,6 +330,22 @@ export function parseCliArgs(argv) {
|
|
|
330
330
|
if (argv[2] === "doctor") {
|
|
331
331
|
return { ...defaults, runDoctor: true };
|
|
332
332
|
}
|
|
333
|
+
if (argv[2] === "logs") {
|
|
334
|
+
const actions = argv.includes("--actions") || argv.includes("-a");
|
|
335
|
+
let grep;
|
|
336
|
+
let count;
|
|
337
|
+
for (let i = 3; i < argv.length; i++) {
|
|
338
|
+
if ((argv[i] === "--grep" || argv[i] === "-g") && argv[i + 1]) {
|
|
339
|
+
grep = argv[++i];
|
|
340
|
+
}
|
|
341
|
+
else if ((argv[i] === "-n" || argv[i] === "--count") && argv[i + 1]) {
|
|
342
|
+
const val = parseInt(argv[++i], 10);
|
|
343
|
+
if (!isNaN(val) && val > 0)
|
|
344
|
+
count = val;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return { ...defaults, runLogs: true, logsActions: actions, logsGrep: grep, logsCount: count };
|
|
348
|
+
}
|
|
333
349
|
if (argv[2] === "init") {
|
|
334
350
|
const force = argv.includes("--force") || argv.includes("-f");
|
|
335
351
|
return { ...defaults, runInit: true, initForce: force };
|
|
@@ -419,7 +435,7 @@ export function parseCliArgs(argv) {
|
|
|
419
435
|
break;
|
|
420
436
|
}
|
|
421
437
|
}
|
|
422
|
-
return { overrides, help, version, register: false, testContext: false, runTest: false, showTasks: false, showHistory: false, showStatus: false, showConfig: false, configValidate: false, configDiff: false, notifyTest: false, runDoctor: false, runInit: false, initForce: false, runTaskCli: false };
|
|
438
|
+
return { overrides, help, version, register: false, testContext: false, runTest: false, showTasks: false, showHistory: false, showStatus: false, showConfig: false, configValidate: false, configDiff: false, notifyTest: false, runDoctor: false, runLogs: false, logsActions: false, logsGrep: undefined, logsCount: undefined, runInit: false, initForce: false, runTaskCli: false };
|
|
423
439
|
}
|
|
424
440
|
export function printHelp() {
|
|
425
441
|
console.log(`aoaoe - autonomous supervisor for agent-of-empires sessions
|
|
@@ -441,6 +457,10 @@ commands:
|
|
|
441
457
|
config --diff show only fields that differ from defaults
|
|
442
458
|
notify-test send a test notification to configured webhooks
|
|
443
459
|
doctor comprehensive health check (config, tools, daemon, disk)
|
|
460
|
+
logs show recent conversation log entries (last 50)
|
|
461
|
+
logs --actions show action log entries (from ~/.aoaoe/actions.log)
|
|
462
|
+
logs --grep <pattern> filter log entries by substring or regex
|
|
463
|
+
logs -n <count> number of entries to show (default: 50)
|
|
444
464
|
task manage tasks and sessions (list, start, stop, new, rm, edit)
|
|
445
465
|
tasks show task progress (from aoaoe.tasks.json)
|
|
446
466
|
history review recent actions (from ~/.aoaoe/actions.log)
|
|
@@ -467,6 +487,11 @@ options:
|
|
|
467
487
|
init options:
|
|
468
488
|
--force, -f overwrite existing config
|
|
469
489
|
|
|
490
|
+
logs options:
|
|
491
|
+
--actions, -a show action log instead of conversation log
|
|
492
|
+
--grep, -g <pattern> filter entries by substring or regex
|
|
493
|
+
-n, --count <number> number of entries to show (default: 50)
|
|
494
|
+
|
|
470
495
|
register options:
|
|
471
496
|
--title, -t <name> session title in AoE (default: aoaoe)
|
|
472
497
|
|
package/dist/console.d.ts
CHANGED
|
@@ -65,5 +65,11 @@ export declare function summarizeRecentActions(logLines: string[], windowMs?: nu
|
|
|
65
65
|
* Pure function: takes stderr text, returns a plain-English explanation.
|
|
66
66
|
*/
|
|
67
67
|
export declare function friendlyError(stderr: string): string;
|
|
68
|
+
/**
|
|
69
|
+
* Filter log lines by a grep pattern (substring or regex).
|
|
70
|
+
* Tries the pattern as a regex first; falls back to plain case-insensitive substring match
|
|
71
|
+
* if the pattern is not valid regex syntax.
|
|
72
|
+
*/
|
|
73
|
+
export declare function filterLogLines(lines: string[], pattern: string): string[];
|
|
68
74
|
export declare function colorizeConsoleLine(line: string): string;
|
|
69
75
|
//# sourceMappingURL=console.d.ts.map
|
package/dist/console.js
CHANGED
|
@@ -365,6 +365,25 @@ export function friendlyError(stderr) {
|
|
|
365
365
|
const firstLine = s.split("\n")[0].trim();
|
|
366
366
|
return firstLine.length > 120 ? firstLine.slice(0, 117) + "..." : firstLine;
|
|
367
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* Filter log lines by a grep pattern (substring or regex).
|
|
370
|
+
* Tries the pattern as a regex first; falls back to plain case-insensitive substring match
|
|
371
|
+
* if the pattern is not valid regex syntax.
|
|
372
|
+
*/
|
|
373
|
+
export function filterLogLines(lines, pattern) {
|
|
374
|
+
let re = null;
|
|
375
|
+
try {
|
|
376
|
+
re = new RegExp(pattern, "i");
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
// invalid regex — use substring
|
|
380
|
+
}
|
|
381
|
+
return lines.filter((line) => {
|
|
382
|
+
if (re)
|
|
383
|
+
return re.test(line);
|
|
384
|
+
return line.toLowerCase().includes(pattern.toLowerCase());
|
|
385
|
+
});
|
|
386
|
+
}
|
|
368
387
|
// colorize a single console line for inline terminal output
|
|
369
388
|
// applied to each line as it's written (not batch like chat.ts colorize)
|
|
370
389
|
export function colorizeConsoleLine(line) {
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { printDashboard } from "./dashboard.js";
|
|
|
7
7
|
import { InputReader } from "./input.js";
|
|
8
8
|
import { ReasonerConsole } from "./console.js";
|
|
9
9
|
import { writeState, buildSessionStates, checkInterrupt, clearInterrupt, cleanupState, acquireLock, readState } from "./daemon-state.js";
|
|
10
|
-
import { formatSessionSummaries, formatActionDetail, formatPlainEnglishAction, narrateObservation, summarizeRecentActions, friendlyError } from "./console.js";
|
|
10
|
+
import { formatSessionSummaries, formatActionDetail, formatPlainEnglishAction, narrateObservation, summarizeRecentActions, friendlyError, colorizeConsoleLine, filterLogLines } from "./console.js";
|
|
11
11
|
import { loadGlobalContext, resolveProjectDirWithSource, discoverContextFiles, loadSessionContext } from "./context.js";
|
|
12
12
|
import { tick as loopTick } from "./loop.js";
|
|
13
13
|
import { exec as shellExec } from "./shell.js";
|
|
@@ -28,7 +28,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
28
28
|
const AOAOE_DIR = join(homedir(), ".aoaoe"); // watch dir for wakeable sleep
|
|
29
29
|
const INPUT_FILE = join(AOAOE_DIR, "pending-input.txt"); // file IPC from chat.ts
|
|
30
30
|
async function main() {
|
|
31
|
-
const { overrides, help, version, register, testContext: isTestContext, runTest, showTasks, showHistory, showStatus, showConfig, configValidate, configDiff, notifyTest, runDoctor, runInit, initForce, runTaskCli: isTaskCli, registerTitle } = parseCliArgs(process.argv);
|
|
31
|
+
const { overrides, help, version, register, testContext: isTestContext, runTest, showTasks, showHistory, showStatus, showConfig, configValidate, configDiff, notifyTest, runDoctor, runLogs, logsActions, logsGrep, logsCount, runInit, initForce, runTaskCli: isTaskCli, registerTitle } = parseCliArgs(process.argv);
|
|
32
32
|
if (help) {
|
|
33
33
|
printHelp();
|
|
34
34
|
process.exit(0);
|
|
@@ -96,6 +96,11 @@ async function main() {
|
|
|
96
96
|
await runDoctorCheck();
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
|
+
// `aoaoe logs` -- show conversation or action log entries
|
|
100
|
+
if (runLogs) {
|
|
101
|
+
await showLogs(logsActions, logsGrep, logsCount);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
99
104
|
// `aoaoe task` -- task management CLI
|
|
100
105
|
if (isTaskCli) {
|
|
101
106
|
await runTaskCli(process.argv);
|
|
@@ -1188,6 +1193,104 @@ async function showActionHistory() {
|
|
|
1188
1193
|
console.log(` breakdown: ${breakdown}`);
|
|
1189
1194
|
console.log("");
|
|
1190
1195
|
}
|
|
1196
|
+
// `aoaoe logs` -- show conversation or action log entries
|
|
1197
|
+
async function showLogs(actions, grep, count) {
|
|
1198
|
+
const n = count ?? 50;
|
|
1199
|
+
if (actions) {
|
|
1200
|
+
// show action log entries (JSONL from ~/.aoaoe/actions.log)
|
|
1201
|
+
const logFile = join(homedir(), ".aoaoe", "actions.log");
|
|
1202
|
+
if (!existsSync(logFile)) {
|
|
1203
|
+
console.log("no action log found (no actions have been taken yet)");
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
let lines;
|
|
1207
|
+
try {
|
|
1208
|
+
lines = readFileSync(logFile, "utf-8").trim().split("\n").filter((l) => l.trim());
|
|
1209
|
+
}
|
|
1210
|
+
catch {
|
|
1211
|
+
console.error("failed to read action log");
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
if (lines.length === 0) {
|
|
1215
|
+
console.log("action log is empty");
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
// apply grep filter before slicing
|
|
1219
|
+
if (grep) {
|
|
1220
|
+
lines = filterLogLines(lines, grep);
|
|
1221
|
+
if (lines.length === 0) {
|
|
1222
|
+
console.log(`no action log entries matching '${grep}'`);
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
const recent = lines.slice(-n);
|
|
1227
|
+
console.log("");
|
|
1228
|
+
console.log(` action log (last ${recent.length} of ${lines.length}${grep ? ` matching '${grep}'` : ""})`);
|
|
1229
|
+
console.log(` ${"─".repeat(70)}`);
|
|
1230
|
+
for (const line of recent) {
|
|
1231
|
+
try {
|
|
1232
|
+
const entry = toActionLogEntry(JSON.parse(line));
|
|
1233
|
+
if (!entry)
|
|
1234
|
+
continue;
|
|
1235
|
+
const time = new Date(entry.timestamp).toLocaleTimeString();
|
|
1236
|
+
const date = new Date(entry.timestamp).toLocaleDateString();
|
|
1237
|
+
const icon = entry.success ? `${GREEN}+${RESET}` : `${RED}!${RESET}`;
|
|
1238
|
+
const actionName = entry.action.action;
|
|
1239
|
+
const session = entry.action.session?.slice(0, 8) ?? entry.action.title ?? "";
|
|
1240
|
+
const detail = entry.detail.length > 50 ? entry.detail.slice(0, 47) + "..." : entry.detail;
|
|
1241
|
+
console.log(` ${icon} ${DIM}${date} ${time}${RESET} ${YELLOW}${actionName.padEnd(16)}${RESET} ${session.padEnd(10)} ${detail}`);
|
|
1242
|
+
}
|
|
1243
|
+
catch {
|
|
1244
|
+
// skip unparseable lines
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
console.log(` ${"─".repeat(70)}`);
|
|
1248
|
+
console.log("");
|
|
1249
|
+
}
|
|
1250
|
+
else {
|
|
1251
|
+
// show conversation log entries (text from ~/.aoaoe/conversation.log)
|
|
1252
|
+
const logFile = join(homedir(), ".aoaoe", "conversation.log");
|
|
1253
|
+
if (!existsSync(logFile)) {
|
|
1254
|
+
console.log("no conversation log found (daemon hasn't run yet)");
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
let lines;
|
|
1258
|
+
try {
|
|
1259
|
+
const content = readFileSync(logFile, "utf-8");
|
|
1260
|
+
lines = content.split("\n");
|
|
1261
|
+
}
|
|
1262
|
+
catch {
|
|
1263
|
+
console.error("failed to read conversation log");
|
|
1264
|
+
return;
|
|
1265
|
+
}
|
|
1266
|
+
// remove trailing empty line from split
|
|
1267
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
1268
|
+
lines.pop();
|
|
1269
|
+
}
|
|
1270
|
+
if (lines.length === 0) {
|
|
1271
|
+
console.log("conversation log is empty");
|
|
1272
|
+
return;
|
|
1273
|
+
}
|
|
1274
|
+
// apply grep filter before slicing
|
|
1275
|
+
if (grep) {
|
|
1276
|
+
lines = filterLogLines(lines, grep);
|
|
1277
|
+
if (lines.length === 0) {
|
|
1278
|
+
console.log(`no conversation log entries matching '${grep}'`);
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
const recent = lines.slice(-n);
|
|
1283
|
+
console.log("");
|
|
1284
|
+
console.log(` conversation log (last ${recent.length} of ${lines.length}${grep ? ` matching '${grep}'` : ""})`);
|
|
1285
|
+
console.log(` ${"─".repeat(70)}`);
|
|
1286
|
+
// colorize using the same function as the inline console output
|
|
1287
|
+
for (const line of recent) {
|
|
1288
|
+
console.log(` ${colorizeConsoleLine(line)}`);
|
|
1289
|
+
}
|
|
1290
|
+
console.log(` ${"─".repeat(70)}`);
|
|
1291
|
+
console.log("");
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1191
1294
|
// `aoaoe test` -- dynamically import and run the integration test
|
|
1192
1295
|
async function runIntegrationTest() {
|
|
1193
1296
|
const testModule = resolve(__dirname, "integration-test.js");
|