aoaoe 0.45.0 → 0.46.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 CHANGED
@@ -410,8 +410,8 @@ The reasoner returns structured JSON decisions:
410
410
  { "action": "stop_session", "session": "<id>" }
411
411
  { "action": "create_agent", "path": "<dir>", "title": "<name>", "tool": "<agent>" }
412
412
  { "action": "remove_agent", "session": "<id>" }
413
- { "action": "report_progress", "repo": "<path>", "summary": "<milestone>" }
414
- { "action": "complete_task", "repo": "<path>", "summary": "<final status>" }
413
+ { "action": "report_progress", "session": "<id>", "summary": "<milestone>" }
414
+ { "action": "complete_task", "session": "<id>", "summary": "<final status>" }
415
415
  { "action": "wait" }
416
416
  ```
417
417
 
package/dist/chat.js CHANGED
@@ -377,6 +377,8 @@ export function getCountdownFromState(state, daemonRunning, now = Date.now()) {
377
377
  function checkDaemon() {
378
378
  if (isDaemonRunning()) {
379
379
  const state = readState();
380
+ if (!state)
381
+ return;
380
382
  const eta = getCountdown();
381
383
  console.log(`${GREEN}daemon connected${RESET} ${DIM}(${state.sessionCount} sessions, poll #${state.pollCount})${RESET}`);
382
384
  if (eta !== null)
package/dist/colors.d.ts CHANGED
@@ -5,7 +5,6 @@ export declare const RED = "\u001B[31m";
5
5
  export declare const GREEN = "\u001B[32m";
6
6
  export declare const YELLOW = "\u001B[33m";
7
7
  export declare const CYAN = "\u001B[36m";
8
- export declare const MAGENTA = "\u001B[35m";
9
8
  export declare const WHITE = "\u001B[37m";
10
9
  export declare const BG_DARK = "\u001B[48;5;236m";
11
10
  //# sourceMappingURL=colors.d.ts.map
package/dist/colors.js CHANGED
@@ -6,7 +6,6 @@ export const RED = "\x1b[31m";
6
6
  export const GREEN = "\x1b[32m";
7
7
  export const YELLOW = "\x1b[33m";
8
8
  export const CYAN = "\x1b[36m";
9
- export const MAGENTA = "\x1b[35m";
10
9
  export const WHITE = "\x1b[37m";
11
10
  export const BG_DARK = "\x1b[48;5;236m";
12
11
  //# sourceMappingURL=colors.js.map
package/dist/config.js CHANGED
@@ -115,6 +115,32 @@ export function validateConfig(config) {
115
115
  if (config.contextFiles !== undefined && !Array.isArray(config.contextFiles)) {
116
116
  errors.push(`contextFiles must be an array of file paths, got ${typeof config.contextFiles}`);
117
117
  }
118
+ // claudeCode.yolo and claudeCode.resume must be booleans (string "false" is truthy)
119
+ if (config.claudeCode?.yolo !== undefined && typeof config.claudeCode.yolo !== "boolean") {
120
+ errors.push(`claudeCode.yolo must be a boolean, got ${typeof config.claudeCode.yolo}`);
121
+ }
122
+ if (config.claudeCode?.resume !== undefined && typeof config.claudeCode.resume !== "boolean") {
123
+ errors.push(`claudeCode.resume must be a boolean, got ${typeof config.claudeCode.resume}`);
124
+ }
125
+ // aoe.profile must be a non-empty string
126
+ if (config.aoe?.profile !== undefined && (typeof config.aoe.profile !== "string" || !config.aoe.profile)) {
127
+ errors.push(`aoe.profile must be a non-empty string, got ${JSON.stringify(config.aoe?.profile)}`);
128
+ }
129
+ // policies.autoAnswerPermissions must be a boolean
130
+ if (config.policies?.autoAnswerPermissions !== undefined && typeof config.policies.autoAnswerPermissions !== "boolean") {
131
+ errors.push(`policies.autoAnswerPermissions must be a boolean, got ${typeof config.policies.autoAnswerPermissions}`);
132
+ }
133
+ // policies.userActivityThresholdMs must be a non-negative number
134
+ if (config.policies?.userActivityThresholdMs !== undefined) {
135
+ const t = config.policies.userActivityThresholdMs;
136
+ if (typeof t !== "number" || !isFinite(t) || t < 0) {
137
+ errors.push(`policies.userActivityThresholdMs must be a number >= 0, got ${t}`);
138
+ }
139
+ }
140
+ // policies.allowDestructive must be a boolean
141
+ if (config.policies?.allowDestructive !== undefined && typeof config.policies.allowDestructive !== "boolean") {
142
+ errors.push(`policies.allowDestructive must be a boolean, got ${typeof config.policies.allowDestructive}`);
143
+ }
118
144
  if (errors.length > 0) {
119
145
  throw new Error(`invalid config:\n ${errors.join("\n ")}`);
120
146
  }
package/dist/context.js CHANGED
@@ -276,7 +276,7 @@ export function resolveProjectDirWithSource(basePath, sessionTitle, sessionDirs)
276
276
  }
277
277
  return { dir: null, source: null };
278
278
  }
279
- // convenience wrapper — returns just the path (backward compatible)
279
+ // convenience wrapper — returns just the path (used by tests and external callers)
280
280
  export function resolveProjectDir(basePath, sessionTitle, sessionDirs) {
281
281
  return resolveProjectDirWithSource(basePath, sessionTitle, sessionDirs).dir;
282
282
  }
package/dist/init.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type ResolutionSource } from "./context.js";
2
- import type { AoeSession } from "./types.js";
2
+ import { type AoeSession } from "./types.js";
3
3
  interface ToolCheck {
4
4
  name: string;
5
5
  path: string | null;
package/dist/init.js CHANGED
@@ -15,6 +15,7 @@ import { homedir } from "node:os";
15
15
  import { exec } from "./shell.js";
16
16
  import { resolveProjectDirWithSource } from "./context.js";
17
17
  import { saveTaskState, loadTaskState } from "./task-manager.js";
18
+ import { toSessionStatus } from "./types.js";
18
19
  import { createServer } from "node:net";
19
20
  import { BOLD, DIM, GREEN, YELLOW, RED, CYAN, RESET } from "./colors.js";
20
21
  // check if a tool is on PATH and get its version
@@ -66,7 +67,7 @@ async function getSessionStatus(id) {
66
67
  return "unknown";
67
68
  try {
68
69
  const data = JSON.parse(result.stdout);
69
- return String(data.status ?? "unknown");
70
+ return toSessionStatus(data.status);
70
71
  }
71
72
  catch {
72
73
  return "unknown";
package/dist/poller.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AoaoeConfig, Observation } from "./types.js";
1
+ import { type AoaoeConfig, type Observation } from "./types.js";
2
2
  export declare class Poller {
3
3
  private config;
4
4
  private previousSnapshots;
package/dist/poller.js CHANGED
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
2
2
  import { exec } from "./shell.js";
3
3
  import { loadSessionContext } from "./context.js";
4
4
  import { getActivityForSessions } from "./activity.js";
5
+ import { toSessionStatus, } from "./types.js";
5
6
  export class Poller {
6
7
  config;
7
8
  previousSnapshots = new Map();
@@ -112,7 +113,7 @@ export class Poller {
112
113
  return "unknown";
113
114
  try {
114
115
  const data = JSON.parse(result.stdout);
115
- return (String(data.status ?? "unknown"));
116
+ return toSessionStatus(data.status);
116
117
  }
117
118
  catch {
118
119
  return "unknown";
@@ -220,7 +221,6 @@ export function quickHash(s) {
220
221
  // covers: CSI (\x1b[...X), OSC (\x1b]...ST), and simple two-char escapes (\x1bX)
221
222
  // also strips \x9b (8-bit CSI) sequences
222
223
  export function stripAnsi(s) {
223
- // eslint-disable-next-line no-control-regex
224
224
  return s.replace(/[\x1b\x9b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[^[\]()#;?0-9A-ORZcf-nqry=><~]/g, "");
225
225
  }
226
226
  export async function listAoeSessionsShared(timeoutMs = 10_000) {
@@ -172,7 +172,9 @@ export class TaskManager {
172
172
  try {
173
173
  sessions = JSON.parse(listResult.stdout);
174
174
  }
175
- catch { }
175
+ catch (e) {
176
+ console.error(`[tasks] failed to parse aoe list output: ${e}`);
177
+ }
176
178
  }
177
179
  for (const task of this.tasks) {
178
180
  if (task.status === "completed")
@@ -208,7 +210,9 @@ export class TaskManager {
208
210
  created.push(task.sessionTitle);
209
211
  }
210
212
  }
211
- catch { }
213
+ catch (e) {
214
+ console.error(`[tasks] failed to parse refreshed session list: ${e}`);
215
+ }
212
216
  }
213
217
  }
214
218
  else {
package/dist/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export type AoeSessionStatus = "working" | "running" | "idle" | "waiting" | "done" | "error" | "stopped" | "unknown";
2
+ export declare function toSessionStatus(raw: unknown): AoeSessionStatus;
2
3
  export interface AoeSession {
3
4
  id: string;
4
5
  title: string;
package/dist/types.js CHANGED
@@ -1,3 +1,9 @@
1
+ const VALID_STATUSES = new Set(["working", "running", "idle", "waiting", "done", "error", "stopped", "unknown"]);
2
+ // coerce an arbitrary string (e.g. from CLI JSON output) to a valid AoeSessionStatus
3
+ export function toSessionStatus(raw) {
4
+ const s = String(raw ?? "unknown");
5
+ return VALID_STATUSES.has(s) ? s : "unknown";
6
+ }
1
7
  // extract the session/title identifier from any action (uses discriminated union narrowing)
2
8
  export function actionSession(action) {
3
9
  switch (action.action) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aoaoe",
3
- "version": "0.45.0",
3
+ "version": "0.46.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",