@a5c-ai/agent-runtime 5.0.1-staging.016f0b0e8119

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 (170) hide show
  1. package/README.md +23 -0
  2. package/dist/apiResult.d.ts +19 -0
  3. package/dist/apiResult.d.ts.map +1 -0
  4. package/dist/apiResult.js +16 -0
  5. package/dist/background/state.d.ts +14 -0
  6. package/dist/background/state.d.ts.map +1 -0
  7. package/dist/background/state.js +25 -0
  8. package/dist/backgroundProcessRegistry.d.ts +66 -0
  9. package/dist/backgroundProcessRegistry.d.ts.map +1 -0
  10. package/dist/backgroundProcessRegistry.js +202 -0
  11. package/dist/cost/claudeCodeParser.d.ts +81 -0
  12. package/dist/cost/claudeCodeParser.d.ts.map +1 -0
  13. package/dist/cost/claudeCodeParser.js +232 -0
  14. package/dist/cost/collector.d.ts +42 -0
  15. package/dist/cost/collector.d.ts.map +1 -0
  16. package/dist/cost/collector.js +105 -0
  17. package/dist/cost/effectCost.d.ts +23 -0
  18. package/dist/cost/effectCost.d.ts.map +1 -0
  19. package/dist/cost/effectCost.js +26 -0
  20. package/dist/cost/index.d.ts +19 -0
  21. package/dist/cost/index.d.ts.map +1 -0
  22. package/dist/cost/index.js +39 -0
  23. package/dist/cost/journal.d.ts +40 -0
  24. package/dist/cost/journal.d.ts.map +1 -0
  25. package/dist/cost/journal.js +137 -0
  26. package/dist/cost/types.d.ts +164 -0
  27. package/dist/cost/types.d.ts.map +1 -0
  28. package/dist/cost/types.js +228 -0
  29. package/dist/daemon/automationExecutor.d.ts +16 -0
  30. package/dist/daemon/automationExecutor.d.ts.map +1 -0
  31. package/dist/daemon/automationExecutor.js +222 -0
  32. package/dist/daemon/config.d.ts +8 -0
  33. package/dist/daemon/config.d.ts.map +1 -0
  34. package/dist/daemon/config.js +209 -0
  35. package/dist/daemon/daemonLog.d.ts +13 -0
  36. package/dist/daemon/daemonLog.d.ts.map +1 -0
  37. package/dist/daemon/daemonLog.js +64 -0
  38. package/dist/daemon/fileWatcher.d.ts +9 -0
  39. package/dist/daemon/fileWatcher.d.ts.map +1 -0
  40. package/dist/daemon/fileWatcher.js +141 -0
  41. package/dist/daemon/index.d.ts +13 -0
  42. package/dist/daemon/index.d.ts.map +1 -0
  43. package/dist/daemon/index.js +22 -0
  44. package/dist/daemon/lifecycle.d.ts +12 -0
  45. package/dist/daemon/lifecycle.d.ts.map +1 -0
  46. package/dist/daemon/lifecycle.js +257 -0
  47. package/dist/daemon/loop.d.ts +21 -0
  48. package/dist/daemon/loop.d.ts.map +1 -0
  49. package/dist/daemon/loop.js +196 -0
  50. package/dist/daemon/timerScheduler.d.ts +13 -0
  51. package/dist/daemon/timerScheduler.d.ts.map +1 -0
  52. package/dist/daemon/timerScheduler.js +122 -0
  53. package/dist/daemon/types.d.ts +93 -0
  54. package/dist/daemon/types.d.ts.map +1 -0
  55. package/dist/daemon/types.js +25 -0
  56. package/dist/daemon/webhookListener.d.ts +6 -0
  57. package/dist/daemon/webhookListener.d.ts.map +1 -0
  58. package/dist/daemon/webhookListener.js +110 -0
  59. package/dist/execution/index.d.ts +8 -0
  60. package/dist/execution/index.d.ts.map +1 -0
  61. package/dist/execution/index.js +12 -0
  62. package/dist/execution/modes/docker.d.ts +21 -0
  63. package/dist/execution/modes/docker.d.ts.map +1 -0
  64. package/dist/execution/modes/docker.js +125 -0
  65. package/dist/execution/modes/index.d.ts +10 -0
  66. package/dist/execution/modes/index.d.ts.map +1 -0
  67. package/dist/execution/modes/index.js +14 -0
  68. package/dist/execution/modes/kubernetes.d.ts +29 -0
  69. package/dist/execution/modes/kubernetes.d.ts.map +1 -0
  70. package/dist/execution/modes/kubernetes.js +121 -0
  71. package/dist/execution/modes/local.d.ts +23 -0
  72. package/dist/execution/modes/local.d.ts.map +1 -0
  73. package/dist/execution/modes/local.js +102 -0
  74. package/dist/execution/modes/ssh.d.ts +23 -0
  75. package/dist/execution/modes/ssh.d.ts.map +1 -0
  76. package/dist/execution/modes/ssh.js +134 -0
  77. package/dist/execution/provider.d.ts +32 -0
  78. package/dist/execution/provider.d.ts.map +1 -0
  79. package/dist/execution/provider.js +90 -0
  80. package/dist/execution/types.d.ts +105 -0
  81. package/dist/execution/types.d.ts.map +1 -0
  82. package/dist/execution/types.js +9 -0
  83. package/dist/index.d.ts +11 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +42 -0
  86. package/dist/observability/health.d.ts +19 -0
  87. package/dist/observability/health.d.ts.map +1 -0
  88. package/dist/observability/health.js +129 -0
  89. package/dist/observability/index.d.ts +6 -0
  90. package/dist/observability/index.d.ts.map +1 -0
  91. package/dist/observability/index.js +20 -0
  92. package/dist/observability/runStatus.d.ts +44 -0
  93. package/dist/observability/runStatus.d.ts.map +1 -0
  94. package/dist/observability/runStatus.js +169 -0
  95. package/dist/observability/timeline.d.ts +11 -0
  96. package/dist/observability/timeline.d.ts.map +1 -0
  97. package/dist/observability/timeline.js +176 -0
  98. package/dist/observability/types.d.ts +62 -0
  99. package/dist/observability/types.d.ts.map +1 -0
  100. package/dist/observability/types.js +8 -0
  101. package/dist/observability/webhooks.d.ts +68 -0
  102. package/dist/observability/webhooks.d.ts.map +1 -0
  103. package/dist/observability/webhooks.js +132 -0
  104. package/dist/resources/budget-tracker.d.ts +56 -0
  105. package/dist/resources/budget-tracker.d.ts.map +1 -0
  106. package/dist/resources/budget-tracker.js +131 -0
  107. package/dist/resources/concurrency-guard.d.ts +55 -0
  108. package/dist/resources/concurrency-guard.d.ts.map +1 -0
  109. package/dist/resources/concurrency-guard.js +132 -0
  110. package/dist/resources/index.d.ts +12 -0
  111. package/dist/resources/index.d.ts.map +1 -0
  112. package/dist/resources/index.js +20 -0
  113. package/dist/resources/manager.d.ts +49 -0
  114. package/dist/resources/manager.d.ts.map +1 -0
  115. package/dist/resources/manager.js +111 -0
  116. package/dist/resources/timeout-cascade.d.ts +56 -0
  117. package/dist/resources/timeout-cascade.d.ts.map +1 -0
  118. package/dist/resources/timeout-cascade.js +145 -0
  119. package/dist/resources/types.d.ts +108 -0
  120. package/dist/resources/types.d.ts.map +1 -0
  121. package/dist/resources/types.js +9 -0
  122. package/dist/session/context.d.ts +22 -0
  123. package/dist/session/context.d.ts.map +1 -0
  124. package/dist/session/context.js +113 -0
  125. package/dist/session/continuityState.d.ts +39 -0
  126. package/dist/session/continuityState.d.ts.map +1 -0
  127. package/dist/session/continuityState.js +164 -0
  128. package/dist/session/cost.d.ts +63 -0
  129. package/dist/session/cost.d.ts.map +1 -0
  130. package/dist/session/cost.js +194 -0
  131. package/dist/session/discovery.d.ts +22 -0
  132. package/dist/session/discovery.d.ts.map +1 -0
  133. package/dist/session/discovery.js +35 -0
  134. package/dist/session/history.d.ts +30 -0
  135. package/dist/session/history.d.ts.map +1 -0
  136. package/dist/session/history.js +143 -0
  137. package/dist/session/index.d.ts +20 -0
  138. package/dist/session/index.d.ts.map +1 -0
  139. package/dist/session/index.js +78 -0
  140. package/dist/session/memoryExtraction.d.ts +65 -0
  141. package/dist/session/memoryExtraction.d.ts.map +1 -0
  142. package/dist/session/memoryExtraction.js +201 -0
  143. package/dist/session/parse.d.ts +45 -0
  144. package/dist/session/parse.d.ts.map +1 -0
  145. package/dist/session/parse.js +170 -0
  146. package/dist/session/persistence.d.ts +46 -0
  147. package/dist/session/persistence.d.ts.map +1 -0
  148. package/dist/session/persistence.js +180 -0
  149. package/dist/session/types.d.ts +267 -0
  150. package/dist/session/types.d.ts.map +1 -0
  151. package/dist/session/types.js +45 -0
  152. package/dist/session/write.d.ts +61 -0
  153. package/dist/session/write.d.ts.map +1 -0
  154. package/dist/session/write.js +213 -0
  155. package/dist/telemetry/audit-log.d.ts +56 -0
  156. package/dist/telemetry/audit-log.d.ts.map +1 -0
  157. package/dist/telemetry/audit-log.js +59 -0
  158. package/dist/telemetry/index.d.ts +9 -0
  159. package/dist/telemetry/index.d.ts.map +1 -0
  160. package/dist/telemetry/index.js +15 -0
  161. package/dist/telemetry/provider.d.ts +39 -0
  162. package/dist/telemetry/provider.d.ts.map +1 -0
  163. package/dist/telemetry/provider.js +91 -0
  164. package/dist/telemetry/span-tree.d.ts +46 -0
  165. package/dist/telemetry/span-tree.d.ts.map +1 -0
  166. package/dist/telemetry/span-tree.js +93 -0
  167. package/dist/telemetry/types.d.ts +85 -0
  168. package/dist/telemetry/types.d.ts.map +1 -0
  169. package/dist/telemetry/types.js +21 -0
  170. package/package.json +90 -0
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ /**
3
+ * Run Health Model (GAP-STATE-008).
4
+ *
5
+ * Computes a point-in-time health snapshot from journal events.
6
+ * Pure function — no file I/O, takes events as input.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.computeRunHealthFromEvents = computeRunHealthFromEvents;
10
+ // ---------------------------------------------------------------------------
11
+ // Defaults
12
+ // ---------------------------------------------------------------------------
13
+ const DEFAULT_CONFIG = {
14
+ stuckThresholdMs: 300_000, // 5 minutes
15
+ degradedErrorRate: 0.3,
16
+ failedErrorRate: 0.7,
17
+ maxPendingAge: 600_000, // 10 minutes
18
+ };
19
+ /**
20
+ * Compute a health snapshot from an array of journal events.
21
+ */
22
+ function computeRunHealthFromEvents(events, options) {
23
+ const config = { ...DEFAULT_CONFIG, ...options?.config };
24
+ const now = options?.now ?? Date.now();
25
+ // Track effects
26
+ const requestedAt = new Map(); // effectId → timestamp ms
27
+ const resolvedEffects = new Set();
28
+ let failedEffects = 0;
29
+ let totalLatency = 0;
30
+ let latencyCount = 0;
31
+ let lastActivityAt = null;
32
+ let hasRunFailed = false;
33
+ const iterations = new Set();
34
+ for (const event of events) {
35
+ lastActivityAt = event.recordedAt;
36
+ const ts = new Date(event.recordedAt).getTime();
37
+ if (event.type === "RUN_FAILED") {
38
+ hasRunFailed = true;
39
+ }
40
+ if (event.type === "EFFECT_REQUESTED") {
41
+ const effectId = typeof event.data.effectId === "string" ? event.data.effectId : undefined;
42
+ if (effectId) {
43
+ requestedAt.set(effectId, ts);
44
+ }
45
+ const iteration = typeof event.data.iteration === "number" ? event.data.iteration : undefined;
46
+ if (iteration != null) {
47
+ iterations.add(iteration);
48
+ }
49
+ }
50
+ if (event.type === "EFFECT_RESOLVED") {
51
+ const effectId = typeof event.data.effectId === "string" ? event.data.effectId : undefined;
52
+ if (effectId) {
53
+ resolvedEffects.add(effectId);
54
+ const reqTs = requestedAt.get(effectId);
55
+ if (reqTs != null) {
56
+ totalLatency += ts - reqTs;
57
+ latencyCount++;
58
+ }
59
+ const status = typeof event.data.status === "string" ? event.data.status : undefined;
60
+ if (status === "error") {
61
+ failedEffects++;
62
+ }
63
+ }
64
+ }
65
+ }
66
+ // Compute metrics
67
+ const totalEffects = requestedAt.size;
68
+ const resolvedCount = resolvedEffects.size;
69
+ const pendingCount = totalEffects - resolvedCount;
70
+ const errorRate = resolvedCount > 0 ? failedEffects / resolvedCount : 0;
71
+ const avgEffectLatencyMs = latencyCount > 0 ? Math.round(totalLatency / latencyCount) : 0;
72
+ // Oldest pending effect age
73
+ let oldestPendingAgeMs = 0;
74
+ for (const [effectId, reqTs] of requestedAt) {
75
+ if (!resolvedEffects.has(effectId)) {
76
+ const age = now - reqTs;
77
+ if (age > oldestPendingAgeMs) {
78
+ oldestPendingAgeMs = age;
79
+ }
80
+ }
81
+ }
82
+ const metrics = {
83
+ errorRate,
84
+ avgEffectLatencyMs,
85
+ pendingCount,
86
+ oldestPendingAgeMs,
87
+ iterationCount: iterations.size,
88
+ lastActivityAt,
89
+ totalEffects,
90
+ resolvedEffects: resolvedCount,
91
+ failedEffects,
92
+ };
93
+ // Determine status and issues
94
+ const issues = [];
95
+ let status = "healthy";
96
+ if (hasRunFailed) {
97
+ status = "failed";
98
+ issues.push("Run failed: RUN_FAILED event detected");
99
+ }
100
+ else if (errorRate >= config.failedErrorRate && resolvedCount > 0) {
101
+ status = "failed";
102
+ issues.push(`High error rate: ${(errorRate * 100).toFixed(1)}% exceeds failed threshold (${(config.failedErrorRate * 100).toFixed(1)}%)`);
103
+ }
104
+ else if (lastActivityAt != null &&
105
+ now - new Date(lastActivityAt).getTime() > config.stuckThresholdMs &&
106
+ pendingCount > 0) {
107
+ status = "stuck";
108
+ const idleMs = now - new Date(lastActivityAt).getTime();
109
+ issues.push(`Run stuck: no activity for ${Math.round(idleMs / 1000)}s (threshold: ${Math.round(config.stuckThresholdMs / 1000)}s)`);
110
+ }
111
+ else if (errorRate >= config.degradedErrorRate && resolvedCount > 0) {
112
+ status = "degraded";
113
+ issues.push(`Elevated error rate: ${(errorRate * 100).toFixed(1)}% exceeds degraded threshold (${(config.degradedErrorRate * 100).toFixed(1)}%)`);
114
+ }
115
+ // Additional issues (additive, don't change status)
116
+ if (oldestPendingAgeMs > config.maxPendingAge &&
117
+ status !== "failed") {
118
+ issues.push(`Oldest pending effect age: ${Math.round(oldestPendingAgeMs / 1000)}s exceeds max pending age (${Math.round(config.maxPendingAge / 1000)}s)`);
119
+ if (status === "healthy") {
120
+ status = "degraded";
121
+ }
122
+ }
123
+ return {
124
+ status,
125
+ metrics,
126
+ issues,
127
+ computedAt: new Date(now).toISOString(),
128
+ };
129
+ }
@@ -0,0 +1,6 @@
1
+ export { buildPhaseTimeline, buildPhaseTimelineFromEvents } from "./timeline";
2
+ export { computeRunHealthFromEvents } from "./health";
3
+ export { getRunHealthSnapshot, getOrchestrationStatus, getPendingWorkItems, type OrchestrationStatus, type OrchestrationPhase, type PendingWorkItem, } from "./runStatus";
4
+ export type { PhaseTimeline, PhaseEntry, PhaseName, Milestone, IterationTimeline, RunHealthSnapshot, RunHealthStatus, RunHealthMetrics, HealthConfig, } from "./types";
5
+ export { registerWebhook, unregisterWebhook, listWebhooks, buildWebhookEvent, evaluateAlertLevel, filterRegistrations, type AlertLevel, type WebhookEventType, type WebhookRegistration, type WebhookEvent, type WebhookDeliveryResult, type WebhookRegistry, type WebhookRegistrationInput, WEBHOOK_SCHEMA_VERSION, } from "./webhooks";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,aAAa,EACb,UAAU,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAC7B,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WEBHOOK_SCHEMA_VERSION = exports.filterRegistrations = exports.evaluateAlertLevel = exports.buildWebhookEvent = exports.listWebhooks = exports.unregisterWebhook = exports.registerWebhook = exports.getPendingWorkItems = exports.getOrchestrationStatus = exports.getRunHealthSnapshot = exports.computeRunHealthFromEvents = exports.buildPhaseTimelineFromEvents = exports.buildPhaseTimeline = void 0;
4
+ var timeline_1 = require("./timeline");
5
+ Object.defineProperty(exports, "buildPhaseTimeline", { enumerable: true, get: function () { return timeline_1.buildPhaseTimeline; } });
6
+ Object.defineProperty(exports, "buildPhaseTimelineFromEvents", { enumerable: true, get: function () { return timeline_1.buildPhaseTimelineFromEvents; } });
7
+ var health_1 = require("./health");
8
+ Object.defineProperty(exports, "computeRunHealthFromEvents", { enumerable: true, get: function () { return health_1.computeRunHealthFromEvents; } });
9
+ var runStatus_1 = require("./runStatus");
10
+ Object.defineProperty(exports, "getRunHealthSnapshot", { enumerable: true, get: function () { return runStatus_1.getRunHealthSnapshot; } });
11
+ Object.defineProperty(exports, "getOrchestrationStatus", { enumerable: true, get: function () { return runStatus_1.getOrchestrationStatus; } });
12
+ Object.defineProperty(exports, "getPendingWorkItems", { enumerable: true, get: function () { return runStatus_1.getPendingWorkItems; } });
13
+ var webhooks_1 = require("./webhooks");
14
+ Object.defineProperty(exports, "registerWebhook", { enumerable: true, get: function () { return webhooks_1.registerWebhook; } });
15
+ Object.defineProperty(exports, "unregisterWebhook", { enumerable: true, get: function () { return webhooks_1.unregisterWebhook; } });
16
+ Object.defineProperty(exports, "listWebhooks", { enumerable: true, get: function () { return webhooks_1.listWebhooks; } });
17
+ Object.defineProperty(exports, "buildWebhookEvent", { enumerable: true, get: function () { return webhooks_1.buildWebhookEvent; } });
18
+ Object.defineProperty(exports, "evaluateAlertLevel", { enumerable: true, get: function () { return webhooks_1.evaluateAlertLevel; } });
19
+ Object.defineProperty(exports, "filterRegistrations", { enumerable: true, get: function () { return webhooks_1.filterRegistrations; } });
20
+ Object.defineProperty(exports, "WEBHOOK_SCHEMA_VERSION", { enumerable: true, get: function () { return webhooks_1.WEBHOOK_SCHEMA_VERSION; } });
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Run status and inspection APIs (GAP-OBS-001, GAP-UX-005, GAP-UX-006).
3
+ *
4
+ * - getRunHealthSnapshot: wraps computeRunHealthFromEvents with journal loading
5
+ * - getOrchestrationStatus: structured status view combining metadata, health, effects
6
+ * - getPendingWorkItems: detailed inspection of pending effects
7
+ */
8
+ import type { RunHealthSnapshot } from "./types";
9
+ /**
10
+ * Compute a health snapshot for a run by loading its journal.
11
+ */
12
+ export declare function getRunHealthSnapshot(runDir: string): Promise<RunHealthSnapshot>;
13
+ export type OrchestrationPhase = "created" | "running" | "waiting" | "completed" | "failed";
14
+ export interface OrchestrationStatus {
15
+ runId: string;
16
+ processId: string;
17
+ phase: OrchestrationPhase;
18
+ iterationCount: number;
19
+ totalEffects: number;
20
+ pendingEffects: number;
21
+ resolvedEffects: number;
22
+ failedEffects: number;
23
+ health: RunHealthSnapshot;
24
+ createdAt: string;
25
+ lastActivityAt: string | null;
26
+ }
27
+ /**
28
+ * Get structured orchestration status for a run.
29
+ */
30
+ export declare function getOrchestrationStatus(runDir: string): Promise<OrchestrationStatus>;
31
+ export interface PendingWorkItem {
32
+ effectId: string;
33
+ taskId?: string;
34
+ kind?: string;
35
+ title?: string;
36
+ requestedAt: string;
37
+ ageMs: number;
38
+ labels?: string[];
39
+ }
40
+ /**
41
+ * List pending (unresolved) effects with rich detail.
42
+ */
43
+ export declare function getPendingWorkItems(runDir: string): Promise<PendingWorkItem[]>;
44
+ //# sourceMappingURL=runStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runStatus.d.ts","sourceRoot":"","sources":["../../src/observability/runStatus.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAMjD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC,CAG5B;AAMD,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,SAAS,GACT,SAAS,GACT,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC,CAqC9B;AAMD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,EAAE,CAAC,CA4E5B"}
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ /**
3
+ * Run status and inspection APIs (GAP-OBS-001, GAP-UX-005, GAP-UX-006).
4
+ *
5
+ * - getRunHealthSnapshot: wraps computeRunHealthFromEvents with journal loading
6
+ * - getOrchestrationStatus: structured status view combining metadata, health, effects
7
+ * - getPendingWorkItems: detailed inspection of pending effects
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.getRunHealthSnapshot = getRunHealthSnapshot;
44
+ exports.getOrchestrationStatus = getOrchestrationStatus;
45
+ exports.getPendingWorkItems = getPendingWorkItems;
46
+ const node_fs_1 = require("node:fs");
47
+ const path = __importStar(require("node:path"));
48
+ const babysitter_sdk_1 = require("@a5c-ai/babysitter-sdk");
49
+ const health_1 = require("./health");
50
+ // ---------------------------------------------------------------------------
51
+ // GAP-OBS-001: Run Health Snapshot
52
+ // ---------------------------------------------------------------------------
53
+ /**
54
+ * Compute a health snapshot for a run by loading its journal.
55
+ */
56
+ async function getRunHealthSnapshot(runDir) {
57
+ const events = await (0, babysitter_sdk_1.loadJournal)(runDir);
58
+ return (0, health_1.computeRunHealthFromEvents)(events);
59
+ }
60
+ /**
61
+ * Get structured orchestration status for a run.
62
+ */
63
+ async function getOrchestrationStatus(runDir) {
64
+ const [metadata, events] = await Promise.all([
65
+ (0, babysitter_sdk_1.readRunMetadata)(runDir),
66
+ (0, babysitter_sdk_1.loadJournal)(runDir),
67
+ ]);
68
+ const health = (0, health_1.computeRunHealthFromEvents)(events);
69
+ // Determine phase from events
70
+ let phase = "created";
71
+ const hasCompleted = events.some((e) => e.type === "RUN_COMPLETED");
72
+ const hasFailed = events.some((e) => e.type === "RUN_FAILED");
73
+ const hasPending = health.metrics.pendingCount > 0;
74
+ if (hasFailed) {
75
+ phase = "failed";
76
+ }
77
+ else if (hasCompleted) {
78
+ phase = "completed";
79
+ }
80
+ else if (hasPending) {
81
+ phase = "waiting";
82
+ }
83
+ else if (events.length > 1) {
84
+ phase = "running";
85
+ }
86
+ return {
87
+ runId: metadata.runId,
88
+ processId: metadata.processId,
89
+ phase,
90
+ iterationCount: health.metrics.iterationCount,
91
+ totalEffects: health.metrics.totalEffects,
92
+ pendingEffects: health.metrics.pendingCount,
93
+ resolvedEffects: health.metrics.resolvedEffects,
94
+ failedEffects: health.metrics.failedEffects,
95
+ health,
96
+ createdAt: metadata.createdAt,
97
+ lastActivityAt: health.metrics.lastActivityAt,
98
+ };
99
+ }
100
+ /**
101
+ * List pending (unresolved) effects with rich detail.
102
+ */
103
+ async function getPendingWorkItems(runDir) {
104
+ const events = await (0, babysitter_sdk_1.loadJournal)(runDir);
105
+ const now = Date.now();
106
+ // Track requested and resolved effect IDs
107
+ const requested = new Map();
108
+ const resolved = new Set();
109
+ for (const event of events) {
110
+ if (event.type === "EFFECT_REQUESTED") {
111
+ const effectId = typeof event.data.effectId === "string"
112
+ ? event.data.effectId
113
+ : undefined;
114
+ if (effectId) {
115
+ requested.set(effectId, {
116
+ effectId,
117
+ requestedAt: event.recordedAt,
118
+ data: event.data,
119
+ });
120
+ }
121
+ }
122
+ if (event.type === "EFFECT_RESOLVED") {
123
+ const effectId = typeof event.data.effectId === "string"
124
+ ? event.data.effectId
125
+ : undefined;
126
+ if (effectId) {
127
+ resolved.add(effectId);
128
+ }
129
+ }
130
+ }
131
+ // Build pending items
132
+ const items = [];
133
+ for (const [effectId, req] of requested) {
134
+ if (resolved.has(effectId))
135
+ continue;
136
+ const reqTs = new Date(req.requestedAt).getTime();
137
+ // Try to read task definition for richer details
138
+ let title;
139
+ let kind;
140
+ let taskId;
141
+ let labels;
142
+ try {
143
+ const taskPath = path.join(runDir, "tasks", effectId, "task.json");
144
+ const raw = await node_fs_1.promises.readFile(taskPath, "utf-8");
145
+ const taskDef = JSON.parse(raw);
146
+ title = typeof taskDef.title === "string" ? taskDef.title : undefined;
147
+ kind = typeof taskDef.kind === "string" ? taskDef.kind : undefined;
148
+ taskId = typeof taskDef.taskId === "string" ? taskDef.taskId : undefined;
149
+ labels = Array.isArray(taskDef.labels) ? taskDef.labels : undefined;
150
+ }
151
+ catch {
152
+ // Task def may not exist for all effect types
153
+ kind = typeof req.data.kind === "string" ? req.data.kind : undefined;
154
+ taskId = typeof req.data.taskId === "string" ? req.data.taskId : undefined;
155
+ }
156
+ items.push({
157
+ effectId,
158
+ taskId,
159
+ kind,
160
+ title,
161
+ requestedAt: req.requestedAt,
162
+ ageMs: now - reqTs,
163
+ labels,
164
+ });
165
+ }
166
+ // Sort by age descending (oldest first)
167
+ items.sort((a, b) => b.ageMs - a.ageMs);
168
+ return items;
169
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * GAP-OBS-NEW-002: Phase Timeline Visualization.
3
+ *
4
+ * Synthesizes phase timeline data from journal events. Identifies planning,
5
+ * execution, verification, and completion phases with duration metrics.
6
+ */
7
+ import { type JournalEvent } from "@a5c-ai/babysitter-sdk";
8
+ import type { PhaseTimeline } from "./types";
9
+ export declare function buildPhaseTimelineFromEvents(events: JournalEvent[]): PhaseTimeline;
10
+ export declare function buildPhaseTimeline(runDir: string): Promise<PhaseTimeline>;
11
+ //# sourceMappingURL=timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/observability/timeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EACV,aAAa,EAKd,MAAM,SAAS,CAAC;AA2BjB,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,CA6HlF;AAoCD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAG/E"}
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * GAP-OBS-NEW-002: Phase Timeline Visualization.
4
+ *
5
+ * Synthesizes phase timeline data from journal events. Identifies planning,
6
+ * execution, verification, and completion phases with duration metrics.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.buildPhaseTimelineFromEvents = buildPhaseTimelineFromEvents;
10
+ exports.buildPhaseTimeline = buildPhaseTimeline;
11
+ const babysitter_sdk_1 = require("@a5c-ai/babysitter-sdk");
12
+ const VERIFICATION_TASK_IDS = new Set([
13
+ "typecheck",
14
+ "lint",
15
+ "run-tests",
16
+ "adversarial-review",
17
+ ]);
18
+ function ms(a, b) {
19
+ return new Date(b).getTime() - new Date(a).getTime();
20
+ }
21
+ function makePhase(name, startedAt, endedAt) {
22
+ return {
23
+ name,
24
+ startedAt,
25
+ endedAt,
26
+ durationMs: endedAt ? ms(startedAt, endedAt) : null,
27
+ };
28
+ }
29
+ function isVerificationEvent(event) {
30
+ const taskId = event.data.taskId;
31
+ return taskId != null && VERIFICATION_TASK_IDS.has(taskId);
32
+ }
33
+ function buildPhaseTimelineFromEvents(events) {
34
+ if (events.length === 0) {
35
+ return {
36
+ phases: [],
37
+ milestones: [],
38
+ iterations: [],
39
+ currentPhase: "planning",
40
+ totalDurationMs: null,
41
+ };
42
+ }
43
+ const phases = [];
44
+ const milestones = [];
45
+ let currentPhase = "planning";
46
+ const firstEvent = events[0];
47
+ const lastEvent = events[events.length - 1];
48
+ // Find key transition points
49
+ const firstEffectReq = events.find((e) => e.type === "EFFECT_REQUESTED");
50
+ const runCompleted = events.find((e) => e.type === "RUN_COMPLETED");
51
+ const runFailed = events.find((e) => e.type === "RUN_FAILED");
52
+ // Find first verification event (typecheck/lint/test/review)
53
+ const firstVerificationReq = events.find((e) => e.type === "EFFECT_REQUESTED" && isVerificationEvent(e));
54
+ const lastVerificationResolved = [...events]
55
+ .reverse()
56
+ .find((e) => e.type === "EFFECT_RESOLVED" && isVerificationEvent(e));
57
+ // Phase 1: Planning — from RUN_CREATED to first EFFECT_REQUESTED
58
+ if (firstEvent.type === "RUN_CREATED") {
59
+ const planEnd = firstEffectReq?.recordedAt ?? null;
60
+ phases.push(makePhase("planning", firstEvent.recordedAt, planEnd));
61
+ if (planEnd) {
62
+ currentPhase = "execution";
63
+ }
64
+ }
65
+ // Phase 2: Execution — from first EFFECT_REQUESTED to verification start (or last resolved)
66
+ if (firstEffectReq) {
67
+ // Find the last non-verification EFFECT_RESOLVED as fallback execution end
68
+ const lastNonVerifResolved = [...events]
69
+ .reverse()
70
+ .find((e) => e.type === "EFFECT_RESOLVED" && !isVerificationEvent(e));
71
+ const execEnd = firstVerificationReq?.recordedAt
72
+ ?? runCompleted?.recordedAt
73
+ ?? runFailed?.recordedAt
74
+ ?? lastNonVerifResolved?.recordedAt
75
+ ?? null;
76
+ phases.push(makePhase("execution", firstEffectReq.recordedAt, execEnd));
77
+ currentPhase = execEnd ? (firstVerificationReq ? "verification" : "execution") : "execution";
78
+ }
79
+ // Phase 3: Verification — quality gates
80
+ if (firstVerificationReq) {
81
+ const verEnd = lastVerificationResolved?.recordedAt
82
+ ?? runCompleted?.recordedAt
83
+ ?? runFailed?.recordedAt
84
+ ?? null;
85
+ phases.push(makePhase("verification", firstVerificationReq.recordedAt, verEnd));
86
+ currentPhase = verEnd ? "completion" : "verification";
87
+ }
88
+ // Phase 4: Completion
89
+ if (runCompleted) {
90
+ phases.push(makePhase("completion", runCompleted.recordedAt, runCompleted.recordedAt));
91
+ currentPhase = "completed";
92
+ }
93
+ else if (runFailed) {
94
+ phases.push(makePhase("completion", runFailed.recordedAt, runFailed.recordedAt));
95
+ currentPhase = "failed";
96
+ }
97
+ // Extract milestones
98
+ for (const event of events) {
99
+ if (event.type === "EFFECT_RESOLVED" && event.data.kind === "breakpoint") {
100
+ milestones.push({
101
+ type: "breakpoint",
102
+ label: event.data.title ?? `Breakpoint ${event.data.effectId}`,
103
+ occurredAt: event.recordedAt,
104
+ data: event.data,
105
+ });
106
+ }
107
+ if (event.type === "EFFECT_RESOLVED" &&
108
+ (event.data.taskId === "adversarial-review")) {
109
+ milestones.push({
110
+ type: "quality-gate",
111
+ label: `Quality review: ${event.data.taskId}`,
112
+ occurredAt: event.recordedAt,
113
+ data: event.data,
114
+ });
115
+ }
116
+ if (event.type === "RUN_COMPLETED") {
117
+ milestones.push({
118
+ type: "run-completed",
119
+ label: "Run completed",
120
+ occurredAt: event.recordedAt,
121
+ });
122
+ }
123
+ if (event.type === "RUN_FAILED") {
124
+ milestones.push({
125
+ type: "run-failed",
126
+ label: "Run failed",
127
+ occurredAt: event.recordedAt,
128
+ data: event.data,
129
+ });
130
+ }
131
+ }
132
+ // Build iteration breakdowns
133
+ const iterations = buildIterations(events);
134
+ const totalDurationMs = events.length >= 2 ? ms(firstEvent.recordedAt, lastEvent.recordedAt) : null;
135
+ return {
136
+ phases,
137
+ milestones,
138
+ iterations,
139
+ currentPhase,
140
+ totalDurationMs,
141
+ };
142
+ }
143
+ function buildIterations(events) {
144
+ const iterationMap = new Map();
145
+ for (const event of events) {
146
+ const iter = event.data.iteration;
147
+ if (iter != null) {
148
+ let group = iterationMap.get(iter);
149
+ if (!group) {
150
+ group = [];
151
+ iterationMap.set(iter, group);
152
+ }
153
+ group.push(event);
154
+ }
155
+ }
156
+ const iterations = [];
157
+ for (const [iteration, iterEvents] of iterationMap) {
158
+ if (iterEvents.length === 0)
159
+ continue;
160
+ const first = iterEvents[0];
161
+ const last = iterEvents[iterEvents.length - 1];
162
+ const endedAt = last.type === "EFFECT_RESOLVED" ? last.recordedAt : null;
163
+ iterations.push({
164
+ iteration,
165
+ phases: [], // Per-iteration phase breakdown could be added later
166
+ startedAt: first.recordedAt,
167
+ endedAt,
168
+ durationMs: endedAt ? ms(first.recordedAt, endedAt) : null,
169
+ });
170
+ }
171
+ return iterations.sort((a, b) => a.iteration - b.iteration);
172
+ }
173
+ async function buildPhaseTimeline(runDir) {
174
+ const events = await (0, babysitter_sdk_1.loadJournal)(runDir);
175
+ return buildPhaseTimelineFromEvents(events);
176
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Observability types.
3
+ *
4
+ * GAP-OBS-NEW-002: Phase Timeline types.
5
+ * GAP-STATE-008: Run Health Model types.
6
+ */
7
+ export type RunHealthStatus = "healthy" | "degraded" | "stuck" | "failed";
8
+ export interface RunHealthMetrics {
9
+ errorRate: number;
10
+ avgEffectLatencyMs: number;
11
+ pendingCount: number;
12
+ oldestPendingAgeMs: number;
13
+ iterationCount: number;
14
+ lastActivityAt: string | null;
15
+ totalEffects: number;
16
+ resolvedEffects: number;
17
+ failedEffects: number;
18
+ }
19
+ export interface RunHealthSnapshot {
20
+ status: RunHealthStatus;
21
+ metrics: RunHealthMetrics;
22
+ issues: string[];
23
+ computedAt: string;
24
+ }
25
+ export interface HealthConfig {
26
+ /** Threshold for detecting stuck runs (default: 300000ms = 5min). */
27
+ stuckThresholdMs: number;
28
+ /** Error rate above which run is 'degraded' (default: 0.3). */
29
+ degradedErrorRate: number;
30
+ /** Error rate above which run is 'failed' (default: 0.7). */
31
+ failedErrorRate: number;
32
+ /** Max age for pending effects before generating issue (default: 600000ms = 10min). */
33
+ maxPendingAge: number;
34
+ }
35
+ export type PhaseName = "planning" | "execution" | "verification" | "completion";
36
+ export interface PhaseEntry {
37
+ name: PhaseName;
38
+ startedAt: string;
39
+ endedAt: string | null;
40
+ durationMs: number | null;
41
+ }
42
+ export interface Milestone {
43
+ type: "breakpoint" | "quality-gate" | "run-completed" | "run-failed";
44
+ label: string;
45
+ occurredAt: string;
46
+ data?: Record<string, unknown>;
47
+ }
48
+ export interface IterationTimeline {
49
+ iteration: number;
50
+ phases: PhaseEntry[];
51
+ startedAt: string;
52
+ endedAt: string | null;
53
+ durationMs: number | null;
54
+ }
55
+ export interface PhaseTimeline {
56
+ phases: PhaseEntry[];
57
+ milestones: Milestone[];
58
+ iterations: IterationTimeline[];
59
+ currentPhase: PhaseName | "completed" | "failed";
60
+ totalDurationMs: number | null;
61
+ }
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/observability/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,eAAe,EAAE,MAAM,CAAC;IACxB,uFAAuF;IACvF,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,YAAY,CAAC;AAEjF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,eAAe,GAAG,YAAY,CAAC;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,YAAY,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACjD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * Observability types.
4
+ *
5
+ * GAP-OBS-NEW-002: Phase Timeline types.
6
+ * GAP-STATE-008: Run Health Model types.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });