@made-by-moonlight/athene-core 0.9.1

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.
Files changed (285) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +241 -0
  3. package/dist/activity-events.d.ts +42 -0
  4. package/dist/activity-events.d.ts.map +1 -0
  5. package/dist/activity-events.js +192 -0
  6. package/dist/activity-events.js.map +1 -0
  7. package/dist/activity-log.d.ts +71 -0
  8. package/dist/activity-log.d.ts.map +1 -0
  9. package/dist/activity-log.js +203 -0
  10. package/dist/activity-log.js.map +1 -0
  11. package/dist/activity-signal.d.ts +20 -0
  12. package/dist/activity-signal.d.ts.map +1 -0
  13. package/dist/activity-signal.js +91 -0
  14. package/dist/activity-signal.js.map +1 -0
  15. package/dist/agent-report.d.ts +148 -0
  16. package/dist/agent-report.d.ts.map +1 -0
  17. package/dist/agent-report.js +516 -0
  18. package/dist/agent-report.js.map +1 -0
  19. package/dist/agent-selection.d.ts +31 -0
  20. package/dist/agent-selection.d.ts.map +1 -0
  21. package/dist/agent-selection.js +69 -0
  22. package/dist/agent-selection.js.map +1 -0
  23. package/dist/agent-workspace-hooks.d.ts +74 -0
  24. package/dist/agent-workspace-hooks.d.ts.map +1 -0
  25. package/dist/agent-workspace-hooks.js +988 -0
  26. package/dist/agent-workspace-hooks.js.map +1 -0
  27. package/dist/atomic-write.d.ts +6 -0
  28. package/dist/atomic-write.d.ts.map +1 -0
  29. package/dist/atomic-write.js +49 -0
  30. package/dist/atomic-write.js.map +1 -0
  31. package/dist/cleanup-stack.d.ts +37 -0
  32. package/dist/cleanup-stack.d.ts.map +1 -0
  33. package/dist/cleanup-stack.js +45 -0
  34. package/dist/cleanup-stack.js.map +1 -0
  35. package/dist/code-review-manager.d.ts +118 -0
  36. package/dist/code-review-manager.d.ts.map +1 -0
  37. package/dist/code-review-manager.js +719 -0
  38. package/dist/code-review-manager.js.map +1 -0
  39. package/dist/code-review-store.d.ts +114 -0
  40. package/dist/code-review-store.d.ts.map +1 -0
  41. package/dist/code-review-store.js +346 -0
  42. package/dist/code-review-store.js.map +1 -0
  43. package/dist/config-generator.d.ts +84 -0
  44. package/dist/config-generator.d.ts.map +1 -0
  45. package/dist/config-generator.js +295 -0
  46. package/dist/config-generator.js.map +1 -0
  47. package/dist/config.d.ts +55 -0
  48. package/dist/config.d.ts.map +1 -0
  49. package/dist/config.js +852 -0
  50. package/dist/config.js.map +1 -0
  51. package/dist/daemon-children.d.ts +55 -0
  52. package/dist/daemon-children.d.ts.map +1 -0
  53. package/dist/daemon-children.js +435 -0
  54. package/dist/daemon-children.js.map +1 -0
  55. package/dist/dashboard-notifications.d.ts +42 -0
  56. package/dist/dashboard-notifications.d.ts.map +1 -0
  57. package/dist/dashboard-notifications.js +123 -0
  58. package/dist/dashboard-notifications.js.map +1 -0
  59. package/dist/events-db.d.ts +39 -0
  60. package/dist/events-db.d.ts.map +1 -0
  61. package/dist/events-db.js +185 -0
  62. package/dist/events-db.js.map +1 -0
  63. package/dist/feature-flags.d.ts +2 -0
  64. package/dist/feature-flags.d.ts.map +1 -0
  65. package/dist/feature-flags.js +9 -0
  66. package/dist/feature-flags.js.map +1 -0
  67. package/dist/feedback-tools.d.ts +97 -0
  68. package/dist/feedback-tools.d.ts.map +1 -0
  69. package/dist/feedback-tools.js +161 -0
  70. package/dist/feedback-tools.js.map +1 -0
  71. package/dist/file-lock.d.ts +5 -0
  72. package/dist/file-lock.d.ts.map +1 -0
  73. package/dist/file-lock.js +59 -0
  74. package/dist/file-lock.js.map +1 -0
  75. package/dist/format-automated-comments.d.ts +18 -0
  76. package/dist/format-automated-comments.d.ts.map +1 -0
  77. package/dist/gh-trace.d.ts +57 -0
  78. package/dist/gh-trace.d.ts.map +1 -0
  79. package/dist/gh-trace.js +320 -0
  80. package/dist/gh-trace.js.map +1 -0
  81. package/dist/git-activity.d.ts +10 -0
  82. package/dist/git-activity.d.ts.map +1 -0
  83. package/dist/git-activity.js +30 -0
  84. package/dist/git-activity.js.map +1 -0
  85. package/dist/global-config.d.ts +1085 -0
  86. package/dist/global-config.d.ts.map +1 -0
  87. package/dist/global-config.js +1067 -0
  88. package/dist/global-config.js.map +1 -0
  89. package/dist/index.d.ts +91 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +59 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/key-value.d.ts +7 -0
  94. package/dist/key-value.d.ts.map +1 -0
  95. package/dist/key-value.js +24 -0
  96. package/dist/key-value.js.map +1 -0
  97. package/dist/lifecycle-manager.d.ts +22 -0
  98. package/dist/lifecycle-manager.d.ts.map +1 -0
  99. package/dist/lifecycle-manager.js +2813 -0
  100. package/dist/lifecycle-manager.js.map +1 -0
  101. package/dist/lifecycle-state.d.ts +28 -0
  102. package/dist/lifecycle-state.d.ts.map +1 -0
  103. package/dist/lifecycle-state.js +446 -0
  104. package/dist/lifecycle-state.js.map +1 -0
  105. package/dist/lifecycle-status-decisions.d.ts +85 -0
  106. package/dist/lifecycle-status-decisions.d.ts.map +1 -0
  107. package/dist/lifecycle-status-decisions.js +262 -0
  108. package/dist/lifecycle-status-decisions.js.map +1 -0
  109. package/dist/lifecycle-transition.d.ts +81 -0
  110. package/dist/lifecycle-transition.d.ts.map +1 -0
  111. package/dist/lifecycle-transition.js +207 -0
  112. package/dist/lifecycle-transition.js.map +1 -0
  113. package/dist/metadata.d.ts +54 -0
  114. package/dist/metadata.d.ts.map +1 -0
  115. package/dist/metadata.js +484 -0
  116. package/dist/metadata.js.map +1 -0
  117. package/dist/migration/storage-v2.d.ts +76 -0
  118. package/dist/migration/storage-v2.d.ts.map +1 -0
  119. package/dist/migration/storage-v2.js +1614 -0
  120. package/dist/migration/storage-v2.js.map +1 -0
  121. package/dist/notification-data.d.ts +135 -0
  122. package/dist/notification-data.d.ts.map +1 -0
  123. package/dist/notification-data.js +204 -0
  124. package/dist/notification-data.js.map +1 -0
  125. package/dist/notification-observability.d.ts +21 -0
  126. package/dist/notification-observability.d.ts.map +1 -0
  127. package/dist/notification-observability.js +154 -0
  128. package/dist/notification-observability.js.map +1 -0
  129. package/dist/notifier-resolution.d.ts +14 -0
  130. package/dist/notifier-resolution.d.ts.map +1 -0
  131. package/dist/notifier-resolution.js +23 -0
  132. package/dist/notifier-resolution.js.map +1 -0
  133. package/dist/observability.d.ts +100 -0
  134. package/dist/observability.d.ts.map +1 -0
  135. package/dist/observability.js +535 -0
  136. package/dist/observability.js.map +1 -0
  137. package/dist/opencode-agents-md.d.ts +3 -0
  138. package/dist/opencode-agents-md.d.ts.map +1 -0
  139. package/dist/opencode-agents-md.js +40 -0
  140. package/dist/opencode-agents-md.js.map +1 -0
  141. package/dist/opencode-config.d.ts +2 -0
  142. package/dist/opencode-config.d.ts.map +1 -0
  143. package/dist/opencode-config.js +17 -0
  144. package/dist/opencode-config.js.map +1 -0
  145. package/dist/opencode-session-id.d.ts +2 -0
  146. package/dist/opencode-session-id.d.ts.map +1 -0
  147. package/dist/opencode-session-id.js +12 -0
  148. package/dist/opencode-session-id.js.map +1 -0
  149. package/dist/opencode-shared.d.ts +80 -0
  150. package/dist/opencode-shared.d.ts.map +1 -0
  151. package/dist/opencode-shared.js +202 -0
  152. package/dist/opencode-shared.js.map +1 -0
  153. package/dist/orchestrator-prompt.d.ts +19 -0
  154. package/dist/orchestrator-prompt.d.ts.map +1 -0
  155. package/dist/orchestrator-prompt.js +130 -0
  156. package/dist/orchestrator-prompt.js.map +1 -0
  157. package/dist/orchestrator-session-strategy.d.ts +5 -0
  158. package/dist/orchestrator-session-strategy.d.ts.map +1 -0
  159. package/dist/orchestrator-session-strategy.js +13 -0
  160. package/dist/orchestrator-session-strategy.js.map +1 -0
  161. package/dist/paths.d.ts +145 -0
  162. package/dist/paths.d.ts.map +1 -0
  163. package/dist/paths.js +288 -0
  164. package/dist/paths.js.map +1 -0
  165. package/dist/platform.d.ts +32 -0
  166. package/dist/platform.d.ts.map +1 -0
  167. package/dist/platform.js +211 -0
  168. package/dist/platform.js.map +1 -0
  169. package/dist/plugin-registry.d.ts +15 -0
  170. package/dist/plugin-registry.d.ts.map +1 -0
  171. package/dist/plugin-registry.js +499 -0
  172. package/dist/plugin-registry.js.map +1 -0
  173. package/dist/portfolio-projects.d.ts +7 -0
  174. package/dist/portfolio-projects.d.ts.map +1 -0
  175. package/dist/portfolio-projects.js +65 -0
  176. package/dist/portfolio-projects.js.map +1 -0
  177. package/dist/portfolio-registry.d.ts +42 -0
  178. package/dist/portfolio-registry.d.ts.map +1 -0
  179. package/dist/portfolio-registry.js +311 -0
  180. package/dist/portfolio-registry.js.map +1 -0
  181. package/dist/portfolio-routing.d.ts +5 -0
  182. package/dist/portfolio-routing.d.ts.map +1 -0
  183. package/dist/portfolio-routing.js +24 -0
  184. package/dist/portfolio-routing.js.map +1 -0
  185. package/dist/portfolio-session-service.d.ts +15 -0
  186. package/dist/portfolio-session-service.d.ts.map +1 -0
  187. package/dist/portfolio-session-service.js +206 -0
  188. package/dist/portfolio-session-service.js.map +1 -0
  189. package/dist/process-cache.d.ts +32 -0
  190. package/dist/process-cache.d.ts.map +1 -0
  191. package/dist/process-cache.js +44 -0
  192. package/dist/process-cache.js.map +1 -0
  193. package/dist/project-resolver.d.ts +5 -0
  194. package/dist/project-resolver.d.ts.map +1 -0
  195. package/dist/project-resolver.js +20 -0
  196. package/dist/project-resolver.js.map +1 -0
  197. package/dist/prompt-builder.d.ts +42 -0
  198. package/dist/prompt-builder.d.ts.map +1 -0
  199. package/dist/prompt-builder.js +182 -0
  200. package/dist/prompt-builder.js.map +1 -0
  201. package/dist/prompts/orchestrator.md.js +4 -0
  202. package/dist/prompts/orchestrator.md.js.map +1 -0
  203. package/dist/query-activity-events.d.ts +42 -0
  204. package/dist/query-activity-events.d.ts.map +1 -0
  205. package/dist/query-activity-events.js +170 -0
  206. package/dist/query-activity-events.js.map +1 -0
  207. package/dist/recovery/actions.d.ts +7 -0
  208. package/dist/recovery/actions.d.ts.map +1 -0
  209. package/dist/recovery/index.d.ts +8 -0
  210. package/dist/recovery/index.d.ts.map +1 -0
  211. package/dist/recovery/logger.d.ts +12 -0
  212. package/dist/recovery/logger.d.ts.map +1 -0
  213. package/dist/recovery/manager.d.ts +24 -0
  214. package/dist/recovery/manager.d.ts.map +1 -0
  215. package/dist/recovery/scanner.d.ts +11 -0
  216. package/dist/recovery/scanner.d.ts.map +1 -0
  217. package/dist/recovery/types.d.ts +170 -0
  218. package/dist/recovery/types.d.ts.map +1 -0
  219. package/dist/recovery/validator.d.ts +8 -0
  220. package/dist/recovery/validator.d.ts.map +1 -0
  221. package/dist/report-watcher.d.ts +93 -0
  222. package/dist/report-watcher.d.ts.map +1 -0
  223. package/dist/report-watcher.js +182 -0
  224. package/dist/report-watcher.js.map +1 -0
  225. package/dist/scm-webhook-utils.d.ts +6 -0
  226. package/dist/scm-webhook-utils.d.ts.map +1 -0
  227. package/dist/scm-webhook-utils.js +36 -0
  228. package/dist/scm-webhook-utils.js.map +1 -0
  229. package/dist/session-manager.d.ts +22 -0
  230. package/dist/session-manager.d.ts.map +1 -0
  231. package/dist/session-manager.js +3077 -0
  232. package/dist/session-manager.js.map +1 -0
  233. package/dist/spawn-target.d.ts +23 -0
  234. package/dist/spawn-target.d.ts.map +1 -0
  235. package/dist/spawn-target.js +39 -0
  236. package/dist/spawn-target.js.map +1 -0
  237. package/dist/storage-key.d.ts +9 -0
  238. package/dist/storage-key.d.ts.map +1 -0
  239. package/dist/storage-key.js +59 -0
  240. package/dist/storage-key.js.map +1 -0
  241. package/dist/tmux.d.ts +39 -0
  242. package/dist/tmux.d.ts.map +1 -0
  243. package/dist/tmux.js +141 -0
  244. package/dist/tmux.js.map +1 -0
  245. package/dist/types.d.ts +1496 -0
  246. package/dist/types.d.ts.map +1 -0
  247. package/dist/types.js +215 -0
  248. package/dist/types.js.map +1 -0
  249. package/dist/update-cache.d.ts +59 -0
  250. package/dist/update-cache.d.ts.map +1 -0
  251. package/dist/update-cache.js +77 -0
  252. package/dist/update-cache.js.map +1 -0
  253. package/dist/utils/metadata-flatten.d.ts +3 -0
  254. package/dist/utils/metadata-flatten.d.ts.map +1 -0
  255. package/dist/utils/metadata-flatten.js +18 -0
  256. package/dist/utils/metadata-flatten.js.map +1 -0
  257. package/dist/utils/pr.d.ts +7 -0
  258. package/dist/utils/pr.d.ts.map +1 -0
  259. package/dist/utils/pr.js +97 -0
  260. package/dist/utils/pr.js.map +1 -0
  261. package/dist/utils/session-from-metadata.d.ts +16 -0
  262. package/dist/utils/session-from-metadata.d.ts.map +1 -0
  263. package/dist/utils/session-from-metadata.js +87 -0
  264. package/dist/utils/session-from-metadata.js.map +1 -0
  265. package/dist/utils/session-id.d.ts +4 -0
  266. package/dist/utils/session-id.d.ts.map +1 -0
  267. package/dist/utils/session-id.js +9 -0
  268. package/dist/utils/session-id.js.map +1 -0
  269. package/dist/utils/validation.d.ts +9 -0
  270. package/dist/utils/validation.d.ts.map +1 -0
  271. package/dist/utils/validation.js +45 -0
  272. package/dist/utils/validation.js.map +1 -0
  273. package/dist/utils.d.ts +65 -0
  274. package/dist/utils.d.ts.map +1 -0
  275. package/dist/utils.js +189 -0
  276. package/dist/utils.js.map +1 -0
  277. package/dist/version-compare.d.ts +27 -0
  278. package/dist/version-compare.d.ts.map +1 -0
  279. package/dist/version-compare.js +121 -0
  280. package/dist/version-compare.js.map +1 -0
  281. package/dist/windows-pty-registry.d.ts +27 -0
  282. package/dist/windows-pty-registry.d.ts.map +1 -0
  283. package/dist/windows-pty-registry.js +109 -0
  284. package/dist/windows-pty-registry.js.map +1 -0
  285. package/package.json +110 -0
@@ -0,0 +1,203 @@
1
+ import { mkdir, appendFile } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+
4
+ /**
5
+ * Activity JSONL log — shared utilities for agents that don't have native JSONL.
6
+ *
7
+ * Agents like Aider and OpenCode use this to write activity observations
8
+ * (derived from terminal output) to `{workspacePath}/.ao/activity.jsonl`.
9
+ * Their `getActivityState()` then reads from this file, enabling detection
10
+ * of states like `waiting_input` and `blocked` that terminal-only parsing
11
+ * couldn't surface through the deprecated `detectActivity()` path.
12
+ *
13
+ * Agents with native JSONL (Claude Code, Codex) don't use this — they read
14
+ * richer data directly from their own session files.
15
+ */
16
+ /**
17
+ * Get the path to the activity JSONL log for a session.
18
+ * Location: `{workspacePath}/.ao/activity.jsonl`
19
+ */
20
+ function getActivityLogPath(workspacePath) {
21
+ return join(workspacePath, ".ao", "activity.jsonl");
22
+ }
23
+ /**
24
+ * Append an activity observation to the session's JSONL log.
25
+ * Creates the `.ao/` directory if it doesn't exist.
26
+ */
27
+ async function appendActivityEntry(workspacePath, state, source, trigger) {
28
+ const logPath = getActivityLogPath(workspacePath);
29
+ await mkdir(dirname(logPath), { recursive: true });
30
+ const entry = {
31
+ ts: new Date().toISOString(),
32
+ state,
33
+ source,
34
+ ...(trigger !== undefined &&
35
+ (state === "waiting_input" || state === "blocked") && { trigger }),
36
+ };
37
+ await appendFile(logPath, JSON.stringify(entry) + "\n", "utf-8");
38
+ }
39
+ /**
40
+ * Read the last activity entry from the session's JSONL log.
41
+ * Returns the parsed entry with the file's modification time, or null if
42
+ * the file doesn't exist or is empty.
43
+ */
44
+ async function readLastActivityEntry(workspacePath) {
45
+ const logPath = getActivityLogPath(workspacePath);
46
+ try {
47
+ const { open } = await import('node:fs/promises');
48
+ const handle = await open(logPath, "r");
49
+ try {
50
+ const fileStat = await handle.stat();
51
+ if (fileStat.size === 0)
52
+ return null;
53
+ // Read last 4KB — more than enough for a single JSON line
54
+ const tailSize = Math.min(fileStat.size, 4096);
55
+ const offset = Math.max(0, fileStat.size - tailSize);
56
+ const buffer = Buffer.alloc(tailSize);
57
+ const { bytesRead } = await handle.read(buffer, 0, tailSize, offset);
58
+ if (bytesRead === 0)
59
+ return null;
60
+ const content = buffer.subarray(0, bytesRead).toString("utf-8");
61
+ // Find the last non-empty line. If we read from a non-zero offset,
62
+ // the first line may be truncated — drop it.
63
+ let lines = content.split("\n").filter((l) => l.trim());
64
+ if (offset > 0 && lines.length > 1)
65
+ lines = lines.slice(1);
66
+ if (lines.length === 0)
67
+ return null;
68
+ // Try lines from the end — skip any that fail to parse (e.g. truncated)
69
+ let parsed = null;
70
+ for (let i = lines.length - 1; i >= 0; i--) {
71
+ try {
72
+ parsed = JSON.parse(lines[i]);
73
+ break;
74
+ }
75
+ catch {
76
+ continue;
77
+ }
78
+ }
79
+ if (parsed === null)
80
+ return null;
81
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
82
+ return null;
83
+ const record = parsed;
84
+ const validStates = new Set(["active", "ready", "idle", "waiting_input", "blocked", "exited"]);
85
+ const validSources = new Set(["terminal", "native", "hook"]);
86
+ if (typeof record.ts !== "string" ||
87
+ typeof record.state !== "string" ||
88
+ typeof record.source !== "string" ||
89
+ !validStates.has(record.state) ||
90
+ !validSources.has(record.source)) {
91
+ return null;
92
+ }
93
+ const entry = {
94
+ ts: record.ts,
95
+ state: record.state,
96
+ source: record.source,
97
+ ...(typeof record.trigger === "string" && { trigger: record.trigger }),
98
+ };
99
+ return { entry, modifiedAt: fileStat.mtime };
100
+ }
101
+ finally {
102
+ await handle.close();
103
+ }
104
+ }
105
+ catch {
106
+ return null;
107
+ }
108
+ }
109
+ /**
110
+ * Check the AO activity JSONL for actionable states only.
111
+ *
112
+ * Only returns `waiting_input`/`blocked`.
113
+ * Non-critical states (`active`, `ready`, `idle`) always return `null` so
114
+ * callers fall through to their native signals (git commits, chat history,
115
+ * API queries, native JSONL). This prevents the lifecycle manager's
116
+ * `recordActivity` writes (which refresh `mtime` every poll cycle) from
117
+ * shadowing those richer detection methods and breaking stuck-detection.
118
+ */
119
+ function checkActivityLogState(activityResult) {
120
+ if (!activityResult)
121
+ return null;
122
+ const { entry } = activityResult;
123
+ if (entry.state === "waiting_input" || entry.state === "blocked") {
124
+ const entryTs = new Date(entry.ts);
125
+ if (Number.isNaN(entryTs.getTime()))
126
+ return null;
127
+ return { state: entry.state, timestamp: entryTs };
128
+ }
129
+ // Non-critical states fall through to native signals
130
+ return null;
131
+ }
132
+ /**
133
+ * Derive an activity state from the JSONL entry with age-based decay.
134
+ *
135
+ * Unlike `checkActivityLogState` (which only returns actionable states),
136
+ * this returns any state — but reclassifies `active`/`ready` entries as
137
+ * `ready`/`idle` if they've aged past the active window / threshold.
138
+ * Use this as a last-resort fallback when native signals are unavailable.
139
+ */
140
+ function getActivityFallbackState(activityResult, activeWindowMs, thresholdMs) {
141
+ if (!activityResult)
142
+ return null;
143
+ const { entry } = activityResult;
144
+ const entryTs = new Date(entry.ts);
145
+ if (Number.isNaN(entryTs.getTime()))
146
+ return null;
147
+ if (entry.state === "waiting_input" || entry.state === "blocked") {
148
+ return { state: entry.state, timestamp: entryTs };
149
+ }
150
+ // Age-based decay: active→ready→idle, but never promote past the
151
+ // entry's detected state (e.g. a fresh "idle" entry stays "idle").
152
+ const ageMs = Math.max(0, Date.now() - entryTs.getTime());
153
+ let ageState;
154
+ if (ageMs <= activeWindowMs)
155
+ ageState = "active";
156
+ else if (ageMs <= thresholdMs)
157
+ ageState = "ready";
158
+ else
159
+ ageState = "idle";
160
+ const activityRank = { active: 0, ready: 1, idle: 2 };
161
+ const entryRank = activityRank[entry.state] ?? 2;
162
+ const ageRank = activityRank[ageState] ?? 2;
163
+ const finalState = ageRank >= entryRank ? ageState : entry.state;
164
+ return { state: finalState, timestamp: entryTs };
165
+ }
166
+ /**
167
+ * Build the arguments for `appendActivityEntry` from terminal output.
168
+ *
169
+ * Classifies terminal output via the provided `detectActivity` function and
170
+ * returns the state + trigger. Plugins call `appendActivityEntry` themselves
171
+ * (keeping it mockable in tests).
172
+ */
173
+ function classifyTerminalActivity(terminalOutput, detectActivity) {
174
+ const state = detectActivity(terminalOutput);
175
+ const trigger = state === "waiting_input" || state === "blocked"
176
+ ? terminalOutput.trim().split("\n").slice(-3).join("\n")
177
+ : undefined;
178
+ return { state, trigger };
179
+ }
180
+ /**
181
+ * Shared `recordActivity` implementation for all agents.
182
+ *
183
+ * Classifies terminal output, deduplicates writes (skips when the state
184
+ * hasn't changed and the last entry is recent), and appends to the JSONL.
185
+ * Actionable states (waiting_input/blocked) always write immediately.
186
+ */
187
+ async function recordTerminalActivity(workspacePath, terminalOutput, detectActivity) {
188
+ const { state, trigger } = classifyTerminalActivity(terminalOutput, detectActivity);
189
+ // Deduplicate writes to reduce I/O. Skip when the state hasn't changed
190
+ // and the last entry is recent (<20s). Actionable states always write.
191
+ if (state !== "waiting_input" && state !== "blocked") {
192
+ const lastEntry = await readLastActivityEntry(workspacePath);
193
+ if (lastEntry && lastEntry.entry.state === state) {
194
+ const entryAgeMs = Date.now() - lastEntry.modifiedAt.getTime();
195
+ if (entryAgeMs < 20_000)
196
+ return;
197
+ }
198
+ }
199
+ await appendActivityEntry(workspacePath, state, "terminal", trigger);
200
+ }
201
+
202
+ export { appendActivityEntry, checkActivityLogState, classifyTerminalActivity, getActivityFallbackState, getActivityLogPath, readLastActivityEntry, recordTerminalActivity };
203
+ //# sourceMappingURL=activity-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-log.js","sources":["../src/activity-log.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAAA;;;;;;;;;;;AAWG;AAWH;;;AAGG;AACG,SAAU,kBAAkB,CAAC,aAAqB,EAAA;IACtD,OAAO,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,gBAAgB,CAAC;AACrD;AAEA;;;AAGG;AACI,eAAe,mBAAmB,CACvC,aAAqB,EACrB,KAAoB,EACpB,MAAsC,EACtC,OAAgB,EAAA;AAEhB,IAAA,MAAM,OAAO,GAAG,kBAAkB,CAAC,aAAa,CAAC;AACjD,IAAA,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAElD,IAAA,MAAM,KAAK,GAAqB;AAC9B,QAAA,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,KAAK;QACL,MAAM;QACN,IAAI,OAAO,KAAK,SAAS;AACvB,aAAC,KAAK,KAAK,eAAe,IAAI,KAAK,KAAK,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;KACrE;AAED,IAAA,MAAM,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC;AAClE;AAEA;;;;AAIG;AACI,eAAe,qBAAqB,CACzC,aAAqB,EAAA;AAErB,IAAA,MAAM,OAAO,GAAG,kBAAkB,CAAC,aAAa,CAAC;AAEjD,IAAA,IAAI;QACF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,kBAAkB,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC;AACvC,QAAA,IAAI;AACF,YAAA,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE;AACpC,YAAA,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC;AAAE,gBAAA,OAAO,IAAI;;AAGpC,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;AAC9C,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC;YACpD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;AACrC,YAAA,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC;YACpE,IAAI,SAAS,KAAK,CAAC;AAAE,gBAAA,OAAO,IAAI;AAChC,YAAA,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;;;YAI/D,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;YACvD,IAAI,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;AAAE,gBAAA,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1D,YAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;AAAE,gBAAA,OAAO,IAAI;;YAGnC,IAAI,MAAM,GAAY,IAAI;AAC1B,YAAA,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;AAC1C,gBAAA,IAAI;oBACF,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC;oBAC9B;gBACF;AAAE,gBAAA,MAAM;oBACN;gBACF;YACF;YACA,IAAI,MAAM,KAAK,IAAI;AAAE,gBAAA,OAAO,IAAI;AAChC,YAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAAE,gBAAA,OAAO,IAAI;YAEvF,MAAM,MAAM,GAAG,MAAiC;AAChD,YAAA,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC9F,YAAA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC5D,YAAA,IACE,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ;AAC7B,gBAAA,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;AAChC,gBAAA,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;AACjC,gBAAA,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC9B,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAChC;AACA,gBAAA,OAAO,IAAI;YACb;AAEA,YAAA,MAAM,KAAK,GAAqB;gBAC9B,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,KAAK,EAAE,MAAM,CAAC,KAAkC;gBAChD,MAAM,EAAE,MAAM,CAAC,MAAoC;AACnD,gBAAA,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;aACvE;YACD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,KAAK,EAAE;QAC9C;gBAAU;AACR,YAAA,MAAM,MAAM,CAAC,KAAK,EAAE;QACtB;IACF;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,IAAI;IACb;AACF;AAEA;;;;;;;;;AASG;AACG,SAAU,qBAAqB,CACnC,cAAoE,EAAA;AAEpE,IAAA,IAAI,CAAC,cAAc;AAAE,QAAA,OAAO,IAAI;AAEhC,IAAA,MAAM,EAAE,KAAK,EAAE,GAAG,cAAc;AAEhC,IAAA,IAAI,KAAK,CAAC,KAAK,KAAK,eAAe,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE;QAChE,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;AAAE,YAAA,OAAO,IAAI;QAChD,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE;IACnD;;AAGA,IAAA,OAAO,IAAI;AACb;AAEA;;;;;;;AAOG;SACa,wBAAwB,CACtC,cAAoE,EACpE,cAAsB,EACtB,WAAmB,EAAA;AAEnB,IAAA,IAAI,CAAC,cAAc;AAAE,QAAA,OAAO,IAAI;AAEhC,IAAA,MAAM,EAAE,KAAK,EAAE,GAAG,cAAc;IAChC,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IAClC,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;AAAE,QAAA,OAAO,IAAI;AAEhD,IAAA,IAAI,KAAK,CAAC,KAAK,KAAK,eAAe,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE;QAChE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE;IACnD;;;AAIA,IAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;AACzD,IAAA,IAAI,QAAuB;IAC3B,IAAI,KAAK,IAAI,cAAc;QAAE,QAAQ,GAAG,QAAQ;SAC3C,IAAI,KAAK,IAAI,WAAW;QAAE,QAAQ,GAAG,OAAO;;QAC5C,QAAQ,GAAG,MAAM;AAEtB,IAAA,MAAM,YAAY,GAA2B,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;IAC7E,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;IAChD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC3C,IAAA,MAAM,UAAU,GAAG,OAAO,IAAI,SAAS,GAAG,QAAQ,GAAG,KAAK,CAAC,KAAK;IAEhE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE;AAClD;AAEA;;;;;;AAMG;AACG,SAAU,wBAAwB,CACtC,cAAsB,EACtB,cAAiD,EAAA;AAEjD,IAAA,MAAM,KAAK,GAAG,cAAc,CAAC,cAAc,CAAC;IAC5C,MAAM,OAAO,GACX,KAAK,KAAK,eAAe,IAAI,KAAK,KAAK;UACnC,cAAc,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI;UACrD,SAAS;AACf,IAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;AAC3B;AAEA;;;;;;AAMG;AACI,eAAe,sBAAsB,CAC1C,aAAqB,EACrB,cAAsB,EACtB,cAAiD,EAAA;AAEjD,IAAA,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,wBAAwB,CAAC,cAAc,EAAE,cAAc,CAAC;;;IAInF,IAAI,KAAK,KAAK,eAAe,IAAI,KAAK,KAAK,SAAS,EAAE;AACpD,QAAA,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,aAAa,CAAC;QAC5D,IAAI,SAAS,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,EAAE;AAChD,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE;YAC9D,IAAI,UAAU,GAAG,MAAM;gBAAE;QAC3B;IACF;IAEA,MAAM,mBAAmB,CAAC,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC;AACtE;;;;"}
@@ -0,0 +1,20 @@
1
+ import type { ActivityDetection, ActivitySignal, ActivitySignalSource, ActivityState } from "./types.js";
2
+ export declare const ACTIVITY_STRONG_WINDOW_MS = 60000;
3
+ export declare const ACTIVITY_WEAK_WINDOW_MS: number;
4
+ export declare function summarizeActivityFreshness(timestamp: Date | undefined, now?: Date): "strong" | "weak" | "stale" | "none";
5
+ export declare function createActivitySignal(state: ActivitySignal["state"], options?: {
6
+ activity?: ActivityState | null;
7
+ timestamp?: Date;
8
+ source?: ActivitySignalSource;
9
+ detail?: string;
10
+ }): ActivitySignal;
11
+ export declare function classifyActivitySignal(detection: ActivityDetection, source: ActivitySignalSource, now?: Date): ActivitySignal;
12
+ export declare function hasPositiveIdleEvidence(signal: ActivitySignal): signal is ActivitySignal & {
13
+ activity: "idle" | "blocked";
14
+ timestamp: Date;
15
+ state: "valid";
16
+ };
17
+ export declare function supportsRecentLiveness(signal: ActivitySignal, now?: Date): boolean;
18
+ export declare function isWeakActivityEvidence(signal: ActivitySignal): boolean;
19
+ export declare function formatActivitySignalEvidence(signal: ActivitySignal): string;
20
+ //# sourceMappingURL=activity-signal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-signal.d.ts","sourceRoot":"","sources":["../src/activity-signal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAYzG,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAChD,eAAO,MAAM,uBAAuB,QAAa,CAAC;AAElD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,IAAI,GAAG,SAAS,EAC3B,GAAG,GAAE,IAAiB,GACrB,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAMtC;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,EAC9B,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,GACL,cAAc,CAQhB;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,oBAAoB,EAC5B,GAAG,GAAE,IAAiB,GACrB,cAAc,CAyChB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,IAAI,cAAc,GAAG;IAC1F,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,CAOA;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAQ9F;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAEtE;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAM3E"}
@@ -0,0 +1,91 @@
1
+ const TIMING_SENSITIVE_ACTIVITY_STATES = new Set([
2
+ "active",
3
+ "ready",
4
+ "idle",
5
+ "blocked",
6
+ ]);
7
+ const LIVENESS_ACTIVITY_STATES = new Set(["active", "ready"]);
8
+ const IDLE_ACTIVITY_STATES = new Set(["idle", "blocked"]);
9
+ const ACTIVITY_STRONG_WINDOW_MS = 60_000;
10
+ const ACTIVITY_WEAK_WINDOW_MS = 5 * 60_000;
11
+ function summarizeActivityFreshness(timestamp, now = new Date()) {
12
+ if (!timestamp)
13
+ return "none";
14
+ const ageMs = Math.max(0, now.getTime() - timestamp.getTime());
15
+ if (ageMs <= ACTIVITY_STRONG_WINDOW_MS)
16
+ return "strong";
17
+ if (ageMs <= ACTIVITY_WEAK_WINDOW_MS)
18
+ return "weak";
19
+ return "stale";
20
+ }
21
+ function createActivitySignal(state, options = {}) {
22
+ return {
23
+ state,
24
+ activity: options.activity ?? null,
25
+ timestamp: options.timestamp,
26
+ source: options.source ?? "none",
27
+ detail: options.detail,
28
+ };
29
+ }
30
+ function classifyActivitySignal(detection, source, now = new Date()) {
31
+ if (!TIMING_SENSITIVE_ACTIVITY_STATES.has(detection.state)) {
32
+ return createActivitySignal("valid", {
33
+ activity: detection.state,
34
+ timestamp: detection.timestamp,
35
+ source,
36
+ });
37
+ }
38
+ if (!detection.timestamp && IDLE_ACTIVITY_STATES.has(detection.state)) {
39
+ return createActivitySignal("stale", {
40
+ activity: detection.state,
41
+ source,
42
+ detail: "missing_timestamp",
43
+ });
44
+ }
45
+ if (!detection.timestamp) {
46
+ return createActivitySignal("valid", {
47
+ activity: detection.state,
48
+ source,
49
+ });
50
+ }
51
+ if (LIVENESS_ACTIVITY_STATES.has(detection.state) &&
52
+ summarizeActivityFreshness(detection.timestamp, now) === "stale") {
53
+ return createActivitySignal("stale", {
54
+ activity: detection.state,
55
+ timestamp: detection.timestamp,
56
+ source,
57
+ detail: "stale_timestamp",
58
+ });
59
+ }
60
+ return createActivitySignal("valid", {
61
+ activity: detection.state,
62
+ timestamp: detection.timestamp,
63
+ source,
64
+ });
65
+ }
66
+ function hasPositiveIdleEvidence(signal) {
67
+ return (signal.state === "valid" &&
68
+ signal.timestamp instanceof Date &&
69
+ signal.activity !== null &&
70
+ IDLE_ACTIVITY_STATES.has(signal.activity));
71
+ }
72
+ function supportsRecentLiveness(signal, now = new Date()) {
73
+ return (signal.state === "valid" &&
74
+ signal.timestamp instanceof Date &&
75
+ signal.activity !== null &&
76
+ LIVENESS_ACTIVITY_STATES.has(signal.activity) &&
77
+ summarizeActivityFreshness(signal.timestamp, now) !== "stale");
78
+ }
79
+ function isWeakActivityEvidence(signal) {
80
+ return signal.state !== "valid";
81
+ }
82
+ function formatActivitySignalEvidence(signal) {
83
+ const source = signal.source === "none" ? "" : ` via_${signal.source}`;
84
+ const activity = signal.activity ? ` activity=${signal.activity}` : "";
85
+ const timing = signal.timestamp ? ` at=${signal.timestamp.toISOString()}` : "";
86
+ const detail = signal.detail ? ` detail=${signal.detail}` : "";
87
+ return `activity_signal=${signal.state}${source}${activity}${timing}${detail}`;
88
+ }
89
+
90
+ export { ACTIVITY_STRONG_WINDOW_MS, ACTIVITY_WEAK_WINDOW_MS, classifyActivitySignal, createActivitySignal, formatActivitySignalEvidence, hasPositiveIdleEvidence, isWeakActivityEvidence, summarizeActivityFreshness, supportsRecentLiveness };
91
+ //# sourceMappingURL=activity-signal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-signal.js","sources":["../src/activity-signal.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Agent Report — explicit workflow transitions declared by the worker agent.
3
+ *
4
+ * Stage 3 of the state-machine redesign. Agents run `athene acknowledge` and
5
+ * `athene report <state>` from inside a managed session to declare the workflow
6
+ * phase they are entering. The lifecycle manager prefers fresh agent reports
7
+ * over weak inference, but runtime evidence (process death, merged PR) and
8
+ * SCM ground-truth (CI, review decisions) still take precedence.
9
+ *
10
+ * Fallback matrix (highest precedence first):
11
+ * 1. Runtime dead + no recent activity → terminated/stuck
12
+ * 2. Agent activity plugin surfaces waiting_input/exited
13
+ * 3. SCM/PR ground truth (merged, closed, CI, reviews)
14
+ * 4. Fresh agent report (this module)
15
+ * 5. Idle-beyond-threshold promotion → stuck
16
+ * 6. Default to working
17
+ */
18
+ import type { CanonicalSessionLifecycle, CanonicalSessionReason, CanonicalSessionState, SessionId, SessionStatus } from "./types.js";
19
+ /**
20
+ * Canonical set of states an agent can self-declare.
21
+ *
22
+ * - `started` — agent has begun the task after planning
23
+ * - `working` — generic working signal, useful after a pause
24
+ * - `waiting` — blocked on an external dependency agent cannot unblock
25
+ * - `needs_input` — blocked on human input
26
+ * - `fixing_ci` — responding to a failing CI run
27
+ * - `addressing_reviews`— responding to requested review changes
28
+ * - `pr_created` / `draft_pr_created` / `ready_for_review`
29
+ * — non-terminal PR workflow events with optional PR metadata
30
+ * - `completed` — finished research/non-coding work (not "merged")
31
+ *
32
+ * Note: agents cannot self-report `done`, `terminated`, or terminal PR states
33
+ * like `merged` / `closed`. Those remain owned by AO so ground-truth sources
34
+ * (SCM, runtime) stay authoritative.
35
+ */
36
+ export declare const AGENT_REPORTED_STATES: readonly ["started", "working", "waiting", "needs_input", "fixing_ci", "addressing_reviews", "pr_created", "draft_pr_created", "ready_for_review", "completed"];
37
+ export type AgentReportedState = (typeof AGENT_REPORTED_STATES)[number];
38
+ export interface AgentReport {
39
+ state: AgentReportedState;
40
+ /** ISO 8601 timestamp — when the agent issued the report. */
41
+ timestamp: string;
42
+ /** Optional free-text note the agent may include (e.g. brief status line). */
43
+ note?: string;
44
+ /** Optional PR number attached to PR workflow reports. */
45
+ prNumber?: number;
46
+ /** Optional PR URL attached to PR workflow reports. */
47
+ prUrl?: string;
48
+ /** Optional draft hint attached to PR workflow reports. */
49
+ prIsDraft?: boolean;
50
+ /** Local actor identity when available (e.g. $USER). */
51
+ actor?: string;
52
+ /** Which CLI surface produced this report. */
53
+ source?: "acknowledge" | "report";
54
+ }
55
+ export interface AgentReportAuditSnapshot {
56
+ legacyStatus: SessionStatus;
57
+ sessionState: CanonicalSessionState;
58
+ sessionReason: CanonicalSessionReason;
59
+ lastTransitionAt: string | null;
60
+ }
61
+ export interface AgentReportAuditEntry {
62
+ timestamp: string;
63
+ actor: string;
64
+ source: "acknowledge" | "report";
65
+ reportState: AgentReportedState;
66
+ note?: string;
67
+ prNumber?: number;
68
+ prUrl?: string;
69
+ prIsDraft?: boolean;
70
+ accepted: boolean;
71
+ rejectionReason?: string;
72
+ before: AgentReportAuditSnapshot;
73
+ after: AgentReportAuditSnapshot;
74
+ }
75
+ /** Metadata keys written by `applyAgentReport`. Keep in sync with CLI parsing. */
76
+ export declare const AGENT_REPORT_METADATA_KEYS: {
77
+ readonly STATE: "agentReportedState";
78
+ readonly AT: "agentReportedAt";
79
+ readonly NOTE: "agentReportedNote";
80
+ readonly PR_NUMBER: "agentReportedPrNumber";
81
+ readonly PR_URL: "agentReportedPrUrl";
82
+ readonly PR_IS_DRAFT: "agentReportedPrIsDraft";
83
+ };
84
+ /** Freshness window — agent reports older than this are ignored. */
85
+ export declare const AGENT_REPORT_FRESHNESS_MS = 300000;
86
+ export declare const AGENT_REPORT_CLOCK_SKEW_TOLERANCE_MS = 60000;
87
+ /** Normalize a user-supplied report name into the canonical form. */
88
+ export declare function normalizeAgentReportedState(input: string): AgentReportedState | null;
89
+ /** Canonical mapping: AgentReportedState → (canonical session state, reason). */
90
+ export declare function mapAgentReportToLifecycle(state: AgentReportedState): {
91
+ sessionState: CanonicalSessionState;
92
+ sessionReason: CanonicalSessionReason;
93
+ };
94
+ export interface AgentReportTransitionResult {
95
+ ok: boolean;
96
+ reason?: string;
97
+ }
98
+ /**
99
+ * Validate whether an agent-issued report is allowed given the current lifecycle.
100
+ *
101
+ * Rules:
102
+ * - Orchestrator sessions cannot accept agent reports (orchestrator sessions
103
+ * are read-only coordinators).
104
+ * - Terminal states (`done`, `terminated`) cannot be re-opened by an agent.
105
+ * - Merged PRs cannot be re-opened by an agent (`completed`/`working` etc.
106
+ * attempts are rejected).
107
+ * - Runtime state of `missing`/`exited` means the agent cannot possibly be
108
+ * reporting — reject so we don't silently contradict runtime truth.
109
+ */
110
+ export declare function validateAgentReportTransition(lifecycle: CanonicalSessionLifecycle, _next: AgentReportedState): AgentReportTransitionResult;
111
+ export interface ApplyAgentReportInput {
112
+ state: AgentReportedState;
113
+ note?: string;
114
+ prNumber?: number;
115
+ prUrl?: string;
116
+ actor?: string;
117
+ source?: "acknowledge" | "report";
118
+ /** Override the current clock — used by tests. */
119
+ now?: Date;
120
+ }
121
+ export interface ApplyAgentReportResult {
122
+ report: AgentReport;
123
+ legacyStatus: SessionStatus;
124
+ previousState: CanonicalSessionState;
125
+ nextState: CanonicalSessionState;
126
+ auditEntry: AgentReportAuditEntry;
127
+ }
128
+ export declare function readAgentReportAuditTrail(dataDir: string, sessionId: SessionId): AgentReportAuditEntry[];
129
+ export declare function readAgentReportAuditTrailAsync(dataDir: string, sessionId: SessionId): Promise<AgentReportAuditEntry[]>;
130
+ /**
131
+ * Apply an agent report to a session: update the canonical lifecycle on disk
132
+ * and persist the report metadata keys. Throws when the transition is rejected.
133
+ *
134
+ * The write is idempotent: applying the same report twice is safe (lifecycle
135
+ * fields are already set, metadata timestamp refreshes).
136
+ */
137
+ export declare function applyAgentReport(dataDir: string, sessionId: SessionId, input: ApplyAgentReportInput): ApplyAgentReportResult;
138
+ /** Read an agent report out of a session's raw metadata, or null if absent. */
139
+ export declare function readAgentReport(meta: Record<string, string> | null | undefined): AgentReport | null;
140
+ /**
141
+ * Check whether an agent report is fresh (within the freshness window).
142
+ *
143
+ * Future timestamps (clock skew, malformed input) are rejected — otherwise a
144
+ * single skewed `agentReportedAt` could appear "fresh" indefinitely and
145
+ * override stronger inference signals.
146
+ */
147
+ export declare function isAgentReportFresh(report: AgentReport, now?: Date, windowMs?: number, clockSkewToleranceMs?: number): boolean;
148
+ //# sourceMappingURL=agent-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-report.d.ts","sourceRoot":"","sources":["../src/agent-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EACV,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,SAAS,EACT,aAAa,EACd,MAAM,YAAY,CAAC;AAapB;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,qBAAqB,iKAWxB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAC;CACnC;AAED,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,aAAa,CAAC;IAC5B,YAAY,EAAE,qBAAqB,CAAC;IACpC,aAAa,EAAE,sBAAsB,CAAC;IACtC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,GAAG,QAAQ,CAAC;IACjC,WAAW,EAAE,kBAAkB,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,wBAAwB,CAAC;IACjC,KAAK,EAAE,wBAAwB,CAAC;CACjC;AAED,kFAAkF;AAClF,eAAO,MAAM,0BAA0B;;;;;;;CAO7B,CAAC;AAEX,oEAAoE;AACpE,eAAO,MAAM,yBAAyB,SAAU,CAAC;AACjD,eAAO,MAAM,oCAAoC,QAAS,CAAC;AAmC3D,qEAAqE;AACrE,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAGpF;AAED,iFAAiF;AACjF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,kBAAkB,GAAG;IACpE,YAAY,EAAE,qBAAqB,CAAC;IACpC,aAAa,EAAE,sBAAsB,CAAC;CACvC,CAuBA;AAMD,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,yBAAyB,EACpC,KAAK,EAAE,kBAAkB,GACxB,2BAA2B,CAmB7B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAC;IAClC,kDAAkD;IAClD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,aAAa,CAAC;IAC5B,aAAa,EAAE,qBAAqB,CAAC;IACrC,SAAS,EAAE,qBAAqB,CAAC;IACjC,UAAU,EAAE,qBAAqB,CAAC;CACnC;AA6ED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,GACnB,qBAAqB,EAAE,CAOzB;AAED,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAOlC;AA6BD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,qBAAqB,GAC3B,sBAAsB,CA0NxB;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,GAC9C,WAAW,GAAG,IAAI,CAuBpB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,GAAG,GAAE,IAAiB,EACtB,QAAQ,GAAE,MAAkC,EAC5C,oBAAoB,GAAE,MAA6C,GAClE,OAAO,CAMT"}