@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
package/dist/paths.js ADDED
@@ -0,0 +1,288 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { join, resolve, dirname, basename } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { realpathSync, existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
5
+
6
+ /**
7
+ * Path utilities for the AO storage directory structure.
8
+ *
9
+ * V2 layout (projects/{projectId}/):
10
+ * getProjectDir(projectId) → ~/.agent-orchestrator/projects/{projectId}
11
+ * getProjectSessionsDir(projectId) → .../projects/{projectId}/sessions
12
+ * getProjectWorktreesDir(projectId) → .../projects/{projectId}/worktrees
13
+ * getOrchestratorPath(projectId) → .../projects/{projectId}/orchestrator.json
14
+ * getSessionPath(projectId, sid) → .../projects/{projectId}/sessions/{sid}.json
15
+ *
16
+ * Legacy layout ({storageKey}/):
17
+ * getProjectBaseDir(storageKey) → ~/.agent-orchestrator/{storageKey}
18
+ * getSessionsDir(storageKey) → ~/.agent-orchestrator/{storageKey}/sessions
19
+ * ... (deprecated, kept for migration only)
20
+ */
21
+ /**
22
+ * Generate a 12-character hash from a config directory path.
23
+ *
24
+ * The hash is derived from dirname(configPath), which equals the project root
25
+ * directory when configPath is <project>/agent-orchestrator.yaml.
26
+ *
27
+ * Handles non-existent paths gracefully (e.g. synthesized paths in remote/
28
+ * Docker mode where no local config file exists) by falling back to
29
+ * resolve() when realpathSync fails.
30
+ */
31
+ function generateConfigHash(configPath) {
32
+ let resolved;
33
+ try {
34
+ resolved = realpathSync(configPath);
35
+ }
36
+ catch {
37
+ // File may not exist (remote mode, Docker, pre-creation) — use resolved path
38
+ resolved = resolve(configPath);
39
+ }
40
+ const configDir = dirname(resolved);
41
+ const hash = createHash("sha256").update(configDir).digest("hex");
42
+ return hash.slice(0, 12);
43
+ }
44
+ /**
45
+ * Generate project ID from project path (basename of the path).
46
+ * Example: ~/repos/integrator → "integrator"
47
+ *
48
+ * @deprecated New project registrations use generateExternalId() from global-config.ts.
49
+ */
50
+ function generateProjectId(projectPath) {
51
+ return basename(projectPath);
52
+ }
53
+ /**
54
+ * Generate session prefix from project ID using clean heuristics.
55
+ *
56
+ * Rules:
57
+ * 1. ≤4 chars: use as-is (lowercase)
58
+ * 2. CamelCase: extract uppercase letters (PyTorch → pt)
59
+ * 3. kebab/snake case: use initials (agent-orchestrator → ao)
60
+ * 4. Single word: first 3 chars (integrator → int)
61
+ */
62
+ function generateSessionPrefix(projectId) {
63
+ if (projectId.length <= 4) {
64
+ return projectId.toLowerCase();
65
+ }
66
+ // CamelCase: extract uppercase letters
67
+ const uppercase = projectId.match(/[A-Z]/g);
68
+ if (uppercase && uppercase.length > 1) {
69
+ return uppercase.join("").toLowerCase();
70
+ }
71
+ // kebab-case or snake_case: use initials
72
+ if (projectId.includes("-") || projectId.includes("_")) {
73
+ const separator = projectId.includes("-") ? "-" : "_";
74
+ return projectId
75
+ .split(separator)
76
+ .map((word) => word[0])
77
+ .join("")
78
+ .toLowerCase();
79
+ }
80
+ // Single word: first 3 characters
81
+ return projectId.slice(0, 3).toLowerCase();
82
+ }
83
+ // =============================================================================
84
+ // V2 PATH FUNCTIONS (projects/{projectId}/ layout)
85
+ // =============================================================================
86
+ /** Maximum allowed length for a project ID. */
87
+ const MAX_PROJECT_ID_LENGTH = 128;
88
+ /** Pattern for safe project IDs — alphanumeric, dots, hyphens, underscores only. */
89
+ const SAFE_PROJECT_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
90
+ /** Validate a projectId is safe for use as a directory name, shell commands, and tmux sessions. */
91
+ function assertSafeProjectId(projectId) {
92
+ if (!projectId ||
93
+ projectId === "." ||
94
+ projectId === ".." ||
95
+ projectId.length > MAX_PROJECT_ID_LENGTH ||
96
+ !SAFE_PROJECT_ID_PATTERN.test(projectId)) {
97
+ throw new Error(`Unsafe project ID: "${projectId}"`);
98
+ }
99
+ }
100
+ /** Get the project directory by project ID. */
101
+ function getProjectDir(projectId) {
102
+ assertSafeProjectId(projectId);
103
+ return join(getAoBaseDir(), "projects", projectId);
104
+ }
105
+ /** Get the sessions directory for a project (workers only). */
106
+ function getProjectSessionsDir(projectId) {
107
+ return join(getProjectDir(projectId), "sessions");
108
+ }
109
+ /** Get the worktrees directory for a project. */
110
+ function getProjectWorktreesDir(projectId) {
111
+ return join(getProjectDir(projectId), "worktrees");
112
+ }
113
+ /** Get the AO-local code review store directory for a project. */
114
+ function getProjectCodeReviewsDir(projectId) {
115
+ return join(getProjectDir(projectId), "code-reviews");
116
+ }
117
+ /** Get the feedback reports directory for a project (V2 layout). */
118
+ function getProjectFeedbackReportsDir(projectId) {
119
+ return join(getProjectDir(projectId), "feedback-reports");
120
+ }
121
+ /** Get the orchestrator metadata file path for a project. */
122
+ function getOrchestratorPath(projectId) {
123
+ return join(getProjectDir(projectId), "orchestrator.json");
124
+ }
125
+ /** Get the session metadata file path (.json). */
126
+ function getSessionPath(projectId, sessionId) {
127
+ return join(getProjectSessionsDir(projectId), `${sessionId}.json`);
128
+ }
129
+ // =============================================================================
130
+ // LEGACY PATH FUNCTIONS (deprecated — used by migration only)
131
+ // =============================================================================
132
+ /**
133
+ * @deprecated Use getProjectDir(projectId) instead.
134
+ * Get the project base directory for a storage key.
135
+ * Format: ~/.agent-orchestrator/{storageKey}
136
+ */
137
+ function getProjectBaseDir(storageKey) {
138
+ return join(expandHome("~/.agent-orchestrator"), requireStorageKey(storageKey));
139
+ }
140
+ /**
141
+ * Get the shared observability base directory for a config.
142
+ * Format: ~/.agent-orchestrator/{hash}-observability
143
+ */
144
+ function getObservabilityBaseDir(configPath) {
145
+ const hash = generateConfigHash(configPath);
146
+ return join(expandHome("~/.agent-orchestrator"), `${hash}-observability`);
147
+ }
148
+ /**
149
+ * @deprecated Use getProjectSessionsDir(projectId) instead.
150
+ * Get the sessions directory for a project.
151
+ */
152
+ function getSessionsDir(storageKey) {
153
+ return join(getProjectBaseDir(storageKey), "sessions");
154
+ }
155
+ /**
156
+ * @deprecated Use getProjectWorktreesDir(projectId) instead.
157
+ * Get the worktrees directory for a project.
158
+ */
159
+ function getWorktreesDir(storageKey) {
160
+ return join(getProjectBaseDir(storageKey), "worktrees");
161
+ }
162
+ /**
163
+ * @deprecated Use getProjectFeedbackReportsDir(projectId) instead.
164
+ * Get the feedback reports directory for a project.
165
+ */
166
+ function getFeedbackReportsDir(storageKey) {
167
+ return join(getProjectBaseDir(storageKey), "feedback-reports");
168
+ }
169
+ /**
170
+ * @deprecated Legacy archive directory — archive system removed.
171
+ * Get the archive directory for a project (legacy: nested inside sessions/).
172
+ */
173
+ function getArchiveDir(storageKey) {
174
+ return join(getSessionsDir(storageKey), "archive");
175
+ }
176
+ /**
177
+ * @deprecated No longer needed — collision detection by storageKey is removed.
178
+ * Get the .origin file path for a project.
179
+ */
180
+ function getOriginFilePath(storageKey) {
181
+ return join(getProjectBaseDir(storageKey), ".origin");
182
+ }
183
+ /**
184
+ * Generate user-facing session name.
185
+ * Format: {prefix}-{num}
186
+ * Example: "int-1", "ao-42"
187
+ */
188
+ function generateSessionName(prefix, num) {
189
+ return `${prefix}-${num}`;
190
+ }
191
+ /**
192
+ * @deprecated Session prefixes are globally unique — hash prefix is no longer needed.
193
+ * Use generateSessionName(prefix, num) instead (same output as the new tmux name).
194
+ *
195
+ * Generate tmux session name (legacy format with hash).
196
+ * Format: {storageKey}-{prefix}-{num}
197
+ * Example: "a3b4c5d6e7f8-int-1"
198
+ */
199
+ function generateTmuxName(storageKey, prefix, num) {
200
+ return `${requireStorageKey(storageKey)}-${prefix}-${num}`;
201
+ }
202
+ /**
203
+ * @deprecated Use parseTmuxNameV2 instead.
204
+ * Parse a legacy tmux session name (with hash prefix).
205
+ */
206
+ function parseTmuxName(tmuxName) {
207
+ const match = tmuxName.match(/^([a-f0-9]{12})-([a-zA-Z0-9_-]+)-(\d+)$/);
208
+ if (!match)
209
+ return null;
210
+ return {
211
+ hash: match[1],
212
+ prefix: match[2],
213
+ num: parseInt(match[3], 10),
214
+ };
215
+ }
216
+ /**
217
+ * Parse a V2 tmux session name (no hash prefix, same as session name).
218
+ * Format: {prefix}-{num} e.g. "ao-84", "my-app-1"
219
+ * Prefix must match sessionPrefix validation: [a-zA-Z0-9_-]+
220
+ */
221
+ function parseTmuxNameV2(tmuxName) {
222
+ // Greedy match: prefix is everything up to the last -{num}
223
+ const match = tmuxName.match(/^([a-zA-Z0-9][a-zA-Z0-9_-]*)-(\d+)$/);
224
+ if (!match)
225
+ return null;
226
+ return { prefix: match[1], num: parseInt(match[2], 10) };
227
+ }
228
+ /**
229
+ * Expand ~ to home directory.
230
+ */
231
+ function expandHome(filepath) {
232
+ if (filepath.startsWith("~/")) {
233
+ return join(homedir(), filepath.slice(2));
234
+ }
235
+ return filepath;
236
+ }
237
+ /** Get the base AO directory (~/.agent-orchestrator/) */
238
+ function getAoBaseDir() {
239
+ return expandHome("~/.agent-orchestrator");
240
+ }
241
+ /** Get the portfolio directory (~/.agent-orchestrator/portfolio/) */
242
+ function getPortfolioDir() {
243
+ return join(getAoBaseDir(), "portfolio");
244
+ }
245
+ /** Get the portfolio preferences file path */
246
+ function getPreferencesPath() {
247
+ return join(getPortfolioDir(), "preferences.json");
248
+ }
249
+ /** Get the portfolio registered projects file path */
250
+ function getRegisteredPath() {
251
+ return join(getPortfolioDir(), "registered.json");
252
+ }
253
+ /**
254
+ * @deprecated No longer needed — storageKey and .origin collision detection are removed.
255
+ * Validate and store the .origin file for a project.
256
+ */
257
+ function validateAndStoreOrigin(configPath, storageKey) {
258
+ const originPath = getOriginFilePath(storageKey);
259
+ let resolvedConfigPath;
260
+ try {
261
+ resolvedConfigPath = realpathSync(configPath);
262
+ }
263
+ catch {
264
+ resolvedConfigPath = resolve(configPath);
265
+ }
266
+ if (existsSync(originPath)) {
267
+ const stored = readFileSync(originPath, "utf-8").trim();
268
+ if (stored !== resolvedConfigPath) {
269
+ // Config path changed (local → global migration). Update .origin.
270
+ writeFileSync(originPath, resolvedConfigPath, "utf-8");
271
+ }
272
+ }
273
+ else {
274
+ // Create project base directory and .origin file
275
+ const baseDir = getProjectBaseDir(storageKey);
276
+ mkdirSync(baseDir, { recursive: true });
277
+ writeFileSync(originPath, resolvedConfigPath, "utf-8");
278
+ }
279
+ }
280
+ function requireStorageKey(storageKey) {
281
+ if (!storageKey) {
282
+ throw new Error("storageKey is required");
283
+ }
284
+ return storageKey;
285
+ }
286
+
287
+ export { expandHome, generateConfigHash, generateProjectId, generateSessionName, generateSessionPrefix, generateTmuxName, getAoBaseDir, getArchiveDir, getFeedbackReportsDir, getObservabilityBaseDir, getOrchestratorPath, getOriginFilePath, getPortfolioDir, getPreferencesPath, getProjectBaseDir, getProjectCodeReviewsDir, getProjectDir, getProjectFeedbackReportsDir, getProjectSessionsDir, getProjectWorktreesDir, getRegisteredPath, getSessionPath, getSessionsDir, getWorktreesDir, parseTmuxName, parseTmuxNameV2, requireStorageKey, validateAndStoreOrigin };
288
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sources":["../src/paths.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Cross-platform adapter.
3
+ *
4
+ * All platform-branching logic lives here. Every other module imports
5
+ * from this file instead of doing ad-hoc process.platform checks.
6
+ */
7
+ export declare function isWindows(): boolean;
8
+ export declare function isMac(): boolean;
9
+ export declare function isLinux(): boolean;
10
+ export declare function getDefaultRuntime(): "tmux" | "process";
11
+ export declare function getNodePtyPrebuildsSubdir(): string;
12
+ interface ShellInfo {
13
+ cmd: string;
14
+ args: (command: string) => string[];
15
+ }
16
+ export declare function getShell(): ShellInfo;
17
+ /** Reset cached shell (for testing)
18
+ * @internal
19
+ */
20
+ export declare function _resetShellCache(): void;
21
+ export declare function killProcessTree(pid: number, signal?: "SIGTERM" | "SIGKILL"): Promise<void>;
22
+ export declare function findPidByPort(port: number): Promise<string | null>;
23
+ interface EnvDefaults {
24
+ HOME: string;
25
+ SHELL: string;
26
+ TMPDIR: string;
27
+ PATH: string;
28
+ USER: string;
29
+ }
30
+ export declare function getEnvDefaults(): EnvDefaults;
31
+ export {};
32
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AAEH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,wBAAgB,KAAK,IAAI,OAAO,CAE/B;AAED,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAEtD;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAID,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;CACrC;AA0FD,wBAAgB,QAAQ,IAAI,SAAS,CAapC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAID,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,SAAS,GAAG,SAAqB,GACxC,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAID,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0BxE;AAID,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,cAAc,IAAI,WAAW,CAkB5C"}
@@ -0,0 +1,211 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { userInfo, homedir } from 'node:os';
4
+ import { existsSync } from 'node:fs';
5
+
6
+ const execFileAsync = promisify(execFile);
7
+ /**
8
+ * Cross-platform adapter.
9
+ *
10
+ * All platform-branching logic lives here. Every other module imports
11
+ * from this file instead of doing ad-hoc process.platform checks.
12
+ */
13
+ function isWindows() {
14
+ return process.platform === "win32";
15
+ }
16
+ function isMac() {
17
+ return process.platform === "darwin";
18
+ }
19
+ function isLinux() {
20
+ return process.platform === "linux";
21
+ }
22
+ function getDefaultRuntime() {
23
+ return isWindows() ? "process" : "tmux";
24
+ }
25
+ function getNodePtyPrebuildsSubdir() {
26
+ return `${process.platform}-${process.arch}`;
27
+ }
28
+ let cachedShell = null;
29
+ /**
30
+ * Infer the command-string flag for a given shell from its basename.
31
+ * pwsh / powershell → -Command, cmd → /c, bash / sh / zsh → -c.
32
+ * Default to PowerShell args (the historical behaviour) for unknown shells.
33
+ */
34
+ function inferShellArgsFlag(cmd) {
35
+ const base = cmd
36
+ .replace(/\\/g, "/")
37
+ .split("/")
38
+ .pop()
39
+ .toLowerCase()
40
+ .replace(/\.exe$/, "");
41
+ if (base === "cmd")
42
+ return (c) => ["/c", c];
43
+ if (base === "bash" || base === "sh" || base === "zsh" || base === "dash") {
44
+ return (c) => ["-c", c];
45
+ }
46
+ // pwsh, powershell, and anything else fall back to PowerShell-style args.
47
+ return (c) => ["-Command", c];
48
+ }
49
+ /**
50
+ * Walk PATH looking for an executable. Windows-only: only ever called from
51
+ * resolveWindowsShell. Hard-coded `;` separator and `\` path join regardless
52
+ * of host OS so unit tests that simulate Windows on a Linux CI runner produce
53
+ * canonical Windows paths.
54
+ */
55
+ function findOnPath(name) {
56
+ const exts = process.env["PATHEXT"]?.split(";").filter(Boolean) ?? [
57
+ ".COM",
58
+ ".EXE",
59
+ ".BAT",
60
+ ".CMD",
61
+ ];
62
+ const dirs = (process.env["PATH"] ?? "").split(";").filter(Boolean);
63
+ for (const dir of dirs) {
64
+ const base = dir.endsWith("\\") || dir.endsWith("/") ? dir.slice(0, -1) : dir;
65
+ for (const ext of [...exts, ""]) {
66
+ const candidate = `${base}\\${name}${ext}`;
67
+ if (existsSync(candidate))
68
+ return candidate;
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+ function resolveWindowsShell() {
74
+ // Explicit override — set AO_SHELL to an absolute path or shell name
75
+ // (e.g. "powershell.exe", "pwsh", "cmd.exe", "bash"). Args are inferred
76
+ // from the basename so cmd / bash / sh are usable, not just PowerShell.
77
+ const override = process.env["AO_SHELL"];
78
+ if (override) {
79
+ return { cmd: override, args: inferShellArgsFlag(override) };
80
+ }
81
+ // Prefer pwsh (PowerShell Core, cross-platform). PATH-walk via existsSync
82
+ // rather than execFileSync — a missing pwsh would otherwise block the event
83
+ // loop for the spawn timeout on every cold start (this resolver is sync).
84
+ const pwshPath = findOnPath("pwsh");
85
+ if (pwshPath) {
86
+ return { cmd: pwshPath, args: (c) => ["-Command", c] };
87
+ }
88
+ // Fall back to powershell.exe (Windows PowerShell, always on Win 10+).
89
+ // Use the absolute path because the spawning process may have a degraded
90
+ // PATH that doesn't include C:\Windows\System32 (e.g. Next.js dashboard
91
+ // children spawned without full system PATH inheritance). Without this,
92
+ // we'd fall through to cmd.exe — which breaks any launch command that uses
93
+ // PowerShell syntax (e.g. Codex's `& 'codex' ...`).
94
+ const systemRoot = process.env["SystemRoot"] || "C:\\Windows";
95
+ const psAbsolute = `${systemRoot}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
96
+ if (existsSync(psAbsolute)) {
97
+ return { cmd: psAbsolute, args: (c) => ["-Command", c] };
98
+ }
99
+ // Try PATH lookup as a final PowerShell attempt (unusual installs).
100
+ const psPathLookup = findOnPath("powershell");
101
+ if (psPathLookup) {
102
+ return { cmd: psPathLookup, args: (c) => ["-Command", c] };
103
+ }
104
+ // Last resort: cmd.exe. Note that agent launch commands often use PowerShell
105
+ // syntax (e.g. the `&` call operator) and will fail under cmd.exe. Setting
106
+ // AO_SHELL is the supported escape hatch.
107
+ const comspec = process.env["ComSpec"] || "cmd.exe";
108
+ return { cmd: comspec, args: (c) => ["/c", c] };
109
+ }
110
+ function getShell() {
111
+ if (cachedShell)
112
+ return cachedShell;
113
+ if (isWindows()) {
114
+ cachedShell = resolveWindowsShell();
115
+ }
116
+ else {
117
+ // Always use /bin/sh, not $SHELL. postCreate commands and runtime launches are
118
+ // non-interactive; using $SHELL would break if the user's login shell is
119
+ // non-POSIX (e.g. fish, nushell). /bin/sh is guaranteed POSIX-compliant on all Unix systems.
120
+ cachedShell = { cmd: "/bin/sh", args: (c) => ["-c", c] };
121
+ }
122
+ return cachedShell;
123
+ }
124
+ // -- Process tree kill --
125
+ async function killProcessTree(pid, signal = "SIGTERM") {
126
+ // pid=0 means "current process group" on Unix (-0 === 0 in JS), which would
127
+ // kill AO itself. pid<0 is never valid. Guard both.
128
+ if (pid <= 0)
129
+ return;
130
+ if (isWindows()) {
131
+ // Always use /F (force) on Windows. taskkill without /F sends WM_CLOSE, which
132
+ // only works for GUI windows; headless Node.js console processes may ignore it,
133
+ // leaving orphaned processes. Callers that do SIGTERM→wait→SIGKILL escalation
134
+ // are unaffected: the SIGKILL step simply finds the process already dead.
135
+ const args = ["/T", "/F", "/PID", String(pid)];
136
+ try {
137
+ await execFileAsync("taskkill", args, { windowsHide: true });
138
+ }
139
+ catch {
140
+ // Process may already be dead
141
+ }
142
+ }
143
+ else {
144
+ // Unix: negative PID kills the process group
145
+ try {
146
+ process.kill(-pid, signal);
147
+ }
148
+ catch {
149
+ // Process group may not exist, try direct kill
150
+ try {
151
+ process.kill(pid, signal);
152
+ }
153
+ catch {
154
+ // Already dead
155
+ }
156
+ }
157
+ }
158
+ }
159
+ // -- Port-based PID discovery --
160
+ async function findPidByPort(port) {
161
+ try {
162
+ if (isWindows()) {
163
+ // netstat -ano shows all connections with PIDs
164
+ const { stdout } = await execFileAsync("netstat", ["-ano"], { windowsHide: true });
165
+ const portPattern = new RegExp(`:${port}(?!\\d)`);
166
+ for (const line of stdout.split("\n")) {
167
+ // Match LISTENING state on the target local port exactly
168
+ const parts = line.trim().split(/\s+/);
169
+ const localAddress = parts[1];
170
+ if (line.includes("LISTENING") && localAddress && portPattern.test(localAddress)) {
171
+ const pid = parts[parts.length - 1];
172
+ if (pid && /^\d+$/.test(pid))
173
+ return pid;
174
+ }
175
+ }
176
+ return null;
177
+ }
178
+ else {
179
+ // Unix: lsof
180
+ const { stdout } = await execFileAsync("lsof", ["-ti", `:${port}`, "-sTCP:LISTEN"]);
181
+ const pid = stdout.trim().split("\n")[0]?.trim();
182
+ if (!pid || !/^\d+$/.test(pid))
183
+ return null;
184
+ return pid;
185
+ }
186
+ }
187
+ catch {
188
+ return null;
189
+ }
190
+ }
191
+ function getEnvDefaults() {
192
+ if (isWindows()) {
193
+ return {
194
+ HOME: process.env["USERPROFILE"] || homedir(),
195
+ SHELL: getShell().cmd,
196
+ TMPDIR: process.env["TEMP"] || process.env["TMP"] || "C:\\Windows\\Temp",
197
+ PATH: process.env["PATH"] || "",
198
+ USER: process.env["USERNAME"] || userInfo().username,
199
+ };
200
+ }
201
+ return {
202
+ HOME: process.env["HOME"] || homedir(),
203
+ SHELL: process.env["SHELL"] || "/bin/bash",
204
+ TMPDIR: process.env["TMPDIR"] || "/tmp",
205
+ PATH: process.env["PATH"] || "/usr/local/bin:/usr/bin:/bin",
206
+ USER: process.env["USER"] || userInfo().username,
207
+ };
208
+ }
209
+
210
+ export { findPidByPort, getDefaultRuntime, getEnvDefaults, getNodePtyPrebuildsSubdir, getShell, isLinux, isMac, isWindows, killProcessTree };
211
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sources":["../src/platform.ts"],"sourcesContent":[null],"names":["execFileCb"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Plugin Registry — discovers and loads plugins.
3
+ *
4
+ * Plugins can be:
5
+ * 1. Built-in (packages/plugins/*)
6
+ * 2. npm packages (@made-by-moonlight/athene-plugin-*)
7
+ * 3. Local file paths specified in config
8
+ */
9
+ import type { PluginModule, PluginRegistry } from "./types.js";
10
+ export declare function isPluginModule(value: unknown): value is PluginModule;
11
+ export declare function normalizeImportedPluginModule(value: unknown): PluginModule | null;
12
+ export declare function resolvePackageExportsEntry(exportsField: unknown): string | null;
13
+ export declare function resolveLocalPluginEntrypoint(pluginPath: string): string | null;
14
+ export declare function createPluginRegistry(): PluginRegistry;
15
+ //# sourceMappingURL=plugin-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-registry.d.ts","sourceRoot":"","sources":["../src/plugin-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAKV,YAAY,EACZ,cAAc,EAEf,MAAM,YAAY,CAAC;AAoRpB,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAIpE;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CASjF;AAQD,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAsB/E;AAED,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiD9E;AA2BD,wBAAgB,oBAAoB,IAAI,cAAc,CA4MrD"}