@deriest/ai-engineering-company 1.15.2

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 (237) hide show
  1. package/CHANGELOG.md +807 -0
  2. package/LICENSE +8 -0
  3. package/README.md +291 -0
  4. package/assets/knowledge/.gitkeep +0 -0
  5. package/assets/offices/architecture/README.md +32 -0
  6. package/assets/offices/engineering/README.md +53 -0
  7. package/assets/offices/governance/README.md +30 -0
  8. package/assets/offices/product/README.md +37 -0
  9. package/assets/organization/organization.json +260 -0
  10. package/assets/organization/validation.md +107 -0
  11. package/assets/prompts/.gitkeep +0 -0
  12. package/assets/templates/.gitkeep +0 -0
  13. package/assets/workers/architect/AGENTS.md +49 -0
  14. package/assets/workers/architect/SOUL.md +21 -0
  15. package/assets/workers/architect/config.json +7 -0
  16. package/assets/workers/backend-engineer/AGENTS.md +67 -0
  17. package/assets/workers/backend-engineer/HEARTBEAT.md +5 -0
  18. package/assets/workers/backend-engineer/IDENTITY.md +27 -0
  19. package/assets/workers/backend-engineer/SOUL.md +24 -0
  20. package/assets/workers/backend-engineer/TOOLS.md +44 -0
  21. package/assets/workers/backend-engineer/USER.md +21 -0
  22. package/assets/workers/backend-engineer/company/scripts/wp3/harness-spec.md +31 -0
  23. package/assets/workers/backend-engineer/company/scripts/wp3/lib/semver-range.js +81 -0
  24. package/assets/workers/backend-engineer/company/scripts/wp3/lib/test-mr4.js +6 -0
  25. package/assets/workers/backend-engineer/config.json +7 -0
  26. package/assets/workers/backend-engineer/openclaw-workspace-state.json +4 -0
  27. package/assets/workers/designer/AGENTS.md +49 -0
  28. package/assets/workers/designer/SOUL.md +20 -0
  29. package/assets/workers/designer/config.json +7 -0
  30. package/assets/workers/dispatcher/AGENTS.md +158 -0
  31. package/assets/workers/dispatcher/HEARTBEAT.md +5 -0
  32. package/assets/workers/dispatcher/IDENTITY.md +6 -0
  33. package/assets/workers/dispatcher/ROUTING.md +136 -0
  34. package/assets/workers/dispatcher/SOUL.md +18 -0
  35. package/assets/workers/dispatcher/TOOLS.md +32 -0
  36. package/assets/workers/dispatcher/USER.md +15 -0
  37. package/assets/workers/dispatcher/config.json +7 -0
  38. package/assets/workers/dispatcher/openclaw-workspace-state.json +4 -0
  39. package/assets/workers/frontend-engineer/AGENTS.md +53 -0
  40. package/assets/workers/frontend-engineer/SOUL.md +23 -0
  41. package/assets/workers/frontend-engineer/config.json +7 -0
  42. package/assets/workers/governor/AGENTS.md +57 -0
  43. package/assets/workers/governor/SOUL.md +20 -0
  44. package/assets/workers/governor/config.json +7 -0
  45. package/assets/workers/infrastructure-engineer/AGENTS.md +51 -0
  46. package/assets/workers/infrastructure-engineer/SOUL.md +21 -0
  47. package/assets/workers/infrastructure-engineer/config.json +7 -0
  48. package/assets/workers/product-manager/AGENTS.md +52 -0
  49. package/assets/workers/product-manager/HEARTBEAT.md +5 -0
  50. package/assets/workers/product-manager/IDENTITY.md +27 -0
  51. package/assets/workers/product-manager/SOUL.md +20 -0
  52. package/assets/workers/product-manager/TOOLS.md +44 -0
  53. package/assets/workers/product-manager/USER.md +21 -0
  54. package/assets/workers/product-manager/config.json +7 -0
  55. package/assets/workers/product-manager/openclaw-workspace-state.json +4 -0
  56. package/assets/workers/qa-engineer/AGENTS.md +50 -0
  57. package/assets/workers/qa-engineer/HEARTBEAT.md +5 -0
  58. package/assets/workers/qa-engineer/IDENTITY.md +27 -0
  59. package/assets/workers/qa-engineer/SOUL.md +22 -0
  60. package/assets/workers/qa-engineer/TOOLS.md +44 -0
  61. package/assets/workers/qa-engineer/USER.md +21 -0
  62. package/assets/workers/qa-engineer/config.json +7 -0
  63. package/assets/workers/qa-engineer/openclaw-workspace-state.json +4 -0
  64. package/assets/workers/researcher/AGENTS.md +50 -0
  65. package/assets/workers/researcher/HEARTBEAT.md +5 -0
  66. package/assets/workers/researcher/IDENTITY.md +27 -0
  67. package/assets/workers/researcher/SOUL.md +20 -0
  68. package/assets/workers/researcher/TOOLS.md +44 -0
  69. package/assets/workers/researcher/USER.md +21 -0
  70. package/assets/workers/researcher/config.json +7 -0
  71. package/assets/workers/researcher/openclaw-workspace-state.json +4 -0
  72. package/config/offices.json +19 -0
  73. package/config/policies.json +10 -0
  74. package/config/workflows.json +9 -0
  75. package/dist/audit-logger.d.ts +49 -0
  76. package/dist/audit-logger.d.ts.map +1 -0
  77. package/dist/audit-logger.js +131 -0
  78. package/dist/audit-logger.js.map +1 -0
  79. package/dist/cli.d.ts +17 -0
  80. package/dist/cli.d.ts.map +1 -0
  81. package/dist/cli.js +218 -0
  82. package/dist/cli.js.map +1 -0
  83. package/dist/commands/aicompany.d.ts +12 -0
  84. package/dist/commands/aicompany.d.ts.map +1 -0
  85. package/dist/commands/aicompany.js +101 -0
  86. package/dist/commands/aicompany.js.map +1 -0
  87. package/dist/decision-queue.d.ts +31 -0
  88. package/dist/decision-queue.d.ts.map +1 -0
  89. package/dist/decision-queue.js +86 -0
  90. package/dist/decision-queue.js.map +1 -0
  91. package/dist/dispatch-service.d.ts +43 -0
  92. package/dist/dispatch-service.d.ts.map +1 -0
  93. package/dist/dispatch-service.js +569 -0
  94. package/dist/dispatch-service.js.map +1 -0
  95. package/dist/dispatcher.d.ts +24 -0
  96. package/dist/dispatcher.d.ts.map +1 -0
  97. package/dist/dispatcher.js +84 -0
  98. package/dist/dispatcher.js.map +1 -0
  99. package/dist/file-queue-backend.d.ts +16 -0
  100. package/dist/file-queue-backend.d.ts.map +1 -0
  101. package/dist/file-queue-backend.js +93 -0
  102. package/dist/file-queue-backend.js.map +1 -0
  103. package/dist/gateway.d.ts +14 -0
  104. package/dist/gateway.d.ts.map +1 -0
  105. package/dist/gateway.js +138 -0
  106. package/dist/gateway.js.map +1 -0
  107. package/dist/index.d.ts +4 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/index.js +277 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/lease-provider.d.ts +31 -0
  112. package/dist/lease-provider.d.ts.map +1 -0
  113. package/dist/lease-provider.js +4 -0
  114. package/dist/lease-provider.js.map +1 -0
  115. package/dist/memory-lease-provider.d.ts +10 -0
  116. package/dist/memory-lease-provider.d.ts.map +1 -0
  117. package/dist/memory-lease-provider.js +54 -0
  118. package/dist/memory-lease-provider.js.map +1 -0
  119. package/dist/memory-queue-backend.d.ts +16 -0
  120. package/dist/memory-queue-backend.d.ts.map +1 -0
  121. package/dist/memory-queue-backend.js +93 -0
  122. package/dist/memory-queue-backend.js.map +1 -0
  123. package/dist/metrics-registry.d.ts +58 -0
  124. package/dist/metrics-registry.d.ts.map +1 -0
  125. package/dist/metrics-registry.js +195 -0
  126. package/dist/metrics-registry.js.map +1 -0
  127. package/dist/openclaw.plugin.json +29 -0
  128. package/dist/org-engine.d.ts +134 -0
  129. package/dist/org-engine.d.ts.map +1 -0
  130. package/dist/org-engine.js +129 -0
  131. package/dist/org-engine.js.map +1 -0
  132. package/dist/pipeline-checkpoint.d.ts +44 -0
  133. package/dist/pipeline-checkpoint.d.ts.map +1 -0
  134. package/dist/pipeline-checkpoint.js +90 -0
  135. package/dist/pipeline-checkpoint.js.map +1 -0
  136. package/dist/pipeline-engine.d.ts +53 -0
  137. package/dist/pipeline-engine.d.ts.map +1 -0
  138. package/dist/pipeline-engine.js +47 -0
  139. package/dist/pipeline-engine.js.map +1 -0
  140. package/dist/prompt-assembler.d.ts +13 -0
  141. package/dist/prompt-assembler.d.ts.map +1 -0
  142. package/dist/prompt-assembler.js +84 -0
  143. package/dist/prompt-assembler.js.map +1 -0
  144. package/dist/queue-backend.d.ts +44 -0
  145. package/dist/queue-backend.d.ts.map +1 -0
  146. package/dist/queue-backend.js +4 -0
  147. package/dist/queue-backend.js.map +1 -0
  148. package/dist/redis-lease-provider.d.ts +16 -0
  149. package/dist/redis-lease-provider.d.ts.map +1 -0
  150. package/dist/redis-lease-provider.js +96 -0
  151. package/dist/redis-lease-provider.js.map +1 -0
  152. package/dist/redis-queue-backend.d.ts +23 -0
  153. package/dist/redis-queue-backend.d.ts.map +1 -0
  154. package/dist/redis-queue-backend.js +131 -0
  155. package/dist/redis-queue-backend.js.map +1 -0
  156. package/dist/src/cli.d.ts +11 -0
  157. package/dist/src/cli.d.ts.map +1 -0
  158. package/dist/src/cli.js +100 -0
  159. package/dist/src/cli.js.map +1 -0
  160. package/dist/src/dispatch-service.d.ts +25 -0
  161. package/dist/src/dispatch-service.d.ts.map +1 -0
  162. package/dist/src/dispatch-service.js +201 -0
  163. package/dist/src/dispatch-service.js.map +1 -0
  164. package/dist/src/dispatcher.d.ts +23 -0
  165. package/dist/src/dispatcher.d.ts.map +1 -0
  166. package/dist/src/dispatcher.js +66 -0
  167. package/dist/src/dispatcher.js.map +1 -0
  168. package/dist/src/gateway.d.ts +10 -0
  169. package/dist/src/gateway.d.ts.map +1 -0
  170. package/dist/src/gateway.js +66 -0
  171. package/dist/src/gateway.js.map +1 -0
  172. package/dist/src/index.d.ts +8 -0
  173. package/dist/src/index.d.ts.map +1 -0
  174. package/dist/src/index.js +85 -0
  175. package/dist/src/index.js.map +1 -0
  176. package/dist/src/org-engine.d.ts +134 -0
  177. package/dist/src/org-engine.d.ts.map +1 -0
  178. package/dist/src/org-engine.js +129 -0
  179. package/dist/src/org-engine.js.map +1 -0
  180. package/dist/src/pipeline-engine.d.ts +53 -0
  181. package/dist/src/pipeline-engine.d.ts.map +1 -0
  182. package/dist/src/pipeline-engine.js +47 -0
  183. package/dist/src/pipeline-engine.js.map +1 -0
  184. package/dist/src/prompt-assembler.d.ts +13 -0
  185. package/dist/src/prompt-assembler.d.ts.map +1 -0
  186. package/dist/src/prompt-assembler.js +84 -0
  187. package/dist/src/prompt-assembler.js.map +1 -0
  188. package/dist/src/task-state.d.ts +27 -0
  189. package/dist/src/task-state.d.ts.map +1 -0
  190. package/dist/src/task-state.js +49 -0
  191. package/dist/src/task-state.js.map +1 -0
  192. package/dist/src/tools.d.ts +9 -0
  193. package/dist/src/tools.d.ts.map +1 -0
  194. package/dist/src/tools.js +107 -0
  195. package/dist/src/tools.js.map +1 -0
  196. package/dist/src/types.d.ts +99 -0
  197. package/dist/src/types.d.ts.map +1 -0
  198. package/dist/src/types.js +4 -0
  199. package/dist/src/types.js.map +1 -0
  200. package/dist/src/validation.d.ts +11 -0
  201. package/dist/src/validation.d.ts.map +1 -0
  202. package/dist/src/validation.js +69 -0
  203. package/dist/src/validation.js.map +1 -0
  204. package/dist/src/workboard-gateway.d.ts +82 -0
  205. package/dist/src/workboard-gateway.d.ts.map +1 -0
  206. package/dist/src/workboard-gateway.js +76 -0
  207. package/dist/src/workboard-gateway.js.map +1 -0
  208. package/dist/src/worker-engine.d.ts +38 -0
  209. package/dist/src/worker-engine.d.ts.map +1 -0
  210. package/dist/src/worker-engine.js +73 -0
  211. package/dist/src/worker-engine.js.map +1 -0
  212. package/dist/task-state.d.ts +27 -0
  213. package/dist/task-state.d.ts.map +1 -0
  214. package/dist/task-state.js +62 -0
  215. package/dist/task-state.js.map +1 -0
  216. package/dist/tools.d.ts +11 -0
  217. package/dist/tools.d.ts.map +1 -0
  218. package/dist/tools.js +183 -0
  219. package/dist/tools.js.map +1 -0
  220. package/dist/types.d.ts +99 -0
  221. package/dist/types.d.ts.map +1 -0
  222. package/dist/types.js +4 -0
  223. package/dist/types.js.map +1 -0
  224. package/dist/validation.d.ts +11 -0
  225. package/dist/validation.d.ts.map +1 -0
  226. package/dist/validation.js +69 -0
  227. package/dist/validation.js.map +1 -0
  228. package/dist/workboard-gateway.d.ts +82 -0
  229. package/dist/workboard-gateway.d.ts.map +1 -0
  230. package/dist/workboard-gateway.js +76 -0
  231. package/dist/workboard-gateway.js.map +1 -0
  232. package/dist/worker-engine.d.ts +38 -0
  233. package/dist/worker-engine.d.ts.map +1 -0
  234. package/dist/worker-engine.js +73 -0
  235. package/dist/worker-engine.js.map +1 -0
  236. package/openclaw.plugin.json +42 -0
  237. package/package.json +50 -0
package/dist/index.js ADDED
@@ -0,0 +1,277 @@
1
+ import * as os from "node:os";
2
+ import * as path from "node:path";
3
+ import { dispatchGatewayMethod } from "openclaw/plugin-sdk/gateway-method-runtime";
4
+ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
5
+ import { registerAiCompanyCli } from "./cli.js";
6
+ import { handleAiCompanyCommand } from "./commands/aicompany.js";
7
+ import { AuditLogger } from "./audit-logger.js";
8
+ import { DecisionQueue } from "./decision-queue.js";
9
+ import { DispatchService } from "./dispatch-service.js";
10
+ import { Dispatcher } from "./dispatcher.js";
11
+ import { registerAiCompanyGatewayMethods } from "./gateway.js";
12
+ import { MemoryLeaseProvider } from "./memory-lease-provider.js";
13
+ import { MemoryQueueBackend } from "./memory-queue-backend.js";
14
+ import { RedisLeaseProvider } from "./redis-lease-provider.js";
15
+ import { RedisQueueBackend } from "./redis-queue-backend.js";
16
+ import { MetricsRegistry } from "./metrics-registry.js";
17
+ import { OrgEngine } from "./org-engine.js";
18
+ import { PipelineCheckpoint } from "./pipeline-checkpoint.js";
19
+ import { PipelineEngine } from "./pipeline-engine.js";
20
+ import { TaskStateManager } from "./task-state.js";
21
+ import { createAiCompanyTools } from "./tools.js";
22
+ import { WorkboardGateway } from "./workboard-gateway.js";
23
+ import { WorkerEngine } from "./worker-engine.js";
24
+ // All metrics explicitly declared — no auto-registration
25
+ const METRIC_DECLARATIONS = [
26
+ // Counters
27
+ { name: "dispatch_total", type: "counter", help: "Total dispatches" },
28
+ { name: "dispatch_by_source_gateway", type: "counter" },
29
+ { name: "dispatch_by_source_cli", type: "counter" },
30
+ { name: "dispatch_by_source_tool", type: "counter" },
31
+ { name: "dispatch_by_source_command", type: "counter" },
32
+ { name: "dispatch_by_status_success", type: "counter" },
33
+ { name: "dispatch_by_status_error", type: "counter" },
34
+ { name: "dispatch_by_status_rejected", type: "counter" },
35
+ { name: "pipeline_started_total", type: "counter" },
36
+ { name: "pipeline_completed_total", type: "counter" },
37
+ { name: "pipeline_failed_total", type: "counter" },
38
+ { name: "stage_started_total", type: "counter" },
39
+ { name: "stage_completed_total", type: "counter" },
40
+ { name: "stage_failed_total", type: "counter" },
41
+ { name: "approval_requested_total", type: "counter" },
42
+ { name: "approval_decided_total", type: "counter" },
43
+ { name: "approval_timeout_total", type: "counter" },
44
+ { name: "audit_events_total", type: "counter" },
45
+ { name: "audit_write_errors_total", type: "counter" },
46
+ { name: "rpc_total", type: "counter" },
47
+ { name: "rpc_errors_total", type: "counter" },
48
+ // Gauges
49
+ { name: "queue_depth", type: "gauge" },
50
+ { name: "active_pipelines", type: "gauge" },
51
+ // Histograms
52
+ { name: "dispatch_duration_ms", type: "histogram" },
53
+ { name: "stage_duration_ms", type: "histogram" },
54
+ { name: "approval_latency_ms", type: "histogram" },
55
+ { name: "approval_pending_duration_ms", type: "histogram" },
56
+ // Timers
57
+ { name: "pipeline_duration_ms", type: "timer" },
58
+ ];
59
+ const plugin = definePluginEntry({
60
+ id: "ai-engineering-company",
61
+ name: "AI Engineering Company",
62
+ description: "Management layer that orchestrates AI agents for engineering tasks",
63
+ register(api) {
64
+ api.logger.info("Initializing AI Engineering Company Plugin");
65
+ const rootDir = api.rootDir || process.cwd();
66
+ const config = api.pluginConfig || {};
67
+ const officesPath = path.resolve(rootDir, config.offices || "config/offices.json");
68
+ const orgPath = path.resolve(rootDir, config.organization || "assets/organization/organization.json");
69
+ const workflowsPath = path.resolve(rootDir, config.workflows || "config/workflows.json");
70
+ const workersPath = path.resolve(rootDir, config.workers || "assets/workers");
71
+ // Metrics: instantiate, load persisted values (gauges NOT restored)
72
+ const metrics = new MetricsRegistry(METRIC_DECLARATIONS);
73
+ const metricsStorePath = path.resolve(rootDir, ".openclaw/metrics.json");
74
+ metrics.load(metricsStorePath);
75
+ const orgEngine = new OrgEngine(officesPath, orgPath);
76
+ const pipelineEngine = new PipelineEngine(workflowsPath);
77
+ const workerEngine = new WorkerEngine(workersPath);
78
+ // Workboard integration: Gateway RPC client via SDK dispatchGatewayMethod.
79
+ // Works when called from gateway method handlers (scope is set).
80
+ // Falls back to degraded mode when scope is unavailable (tool/CLI contexts).
81
+ const workboardGateway = new WorkboardGateway({
82
+ gateway: {
83
+ callMethod: async (method, params) => {
84
+ const response = await dispatchGatewayMethod(method, params);
85
+ return {
86
+ ok: response.ok,
87
+ data: response.payload,
88
+ error: response.error,
89
+ };
90
+ },
91
+ },
92
+ boardId: config.boardId ?? "ai-company",
93
+ });
94
+ // ponytail: remove cast when SDK types include session on PluginRuntimeCore
95
+ const session = api.runtime.session
96
+ ?? api.runtime.agent?.session;
97
+ // WP-24: Node identity resolution
98
+ const nodeId = config.nodeId || os.hostname();
99
+ // WP-24: Redis activation (opt-in)
100
+ const redisUrl = process.env.AI_COMPANY_REDIS_URL || config.redis?.url;
101
+ const redisPrefix = config.redis?.prefix || "ai-company:";
102
+ let queueBackend;
103
+ let leaseProvider;
104
+ let redisClose = null;
105
+ if (redisUrl) {
106
+ try {
107
+ const rqb = new RedisQueueBackend(redisUrl, redisPrefix);
108
+ const rlp = new RedisLeaseProvider(redisUrl, redisPrefix);
109
+ queueBackend = rqb;
110
+ leaseProvider = rlp;
111
+ redisClose = async () => { await rqb.close(); await rlp.close(); };
112
+ api.logger.info(`[distributed] Redis enabled at ${redisUrl.replace(/\/\/.*@/, "//***@")}`);
113
+ }
114
+ catch (err) {
115
+ api.logger.warn(`[distributed] Redis unavailable at ${redisUrl}. Falling back to single-node mode. Error: ${err.message}`);
116
+ queueBackend = new MemoryQueueBackend();
117
+ leaseProvider = new MemoryLeaseProvider();
118
+ }
119
+ }
120
+ else {
121
+ queueBackend = new MemoryQueueBackend();
122
+ leaseProvider = new MemoryLeaseProvider();
123
+ }
124
+ const taskState = new TaskStateManager();
125
+ const decisionQueue = new DecisionQueue(metrics, queueBackend);
126
+ const decisionStorePath = path.resolve(rootDir, ".openclaw/decisions.json");
127
+ decisionQueue.load(decisionStorePath);
128
+ // ponytail: 24h cleanup window — make configurable via plugin config if needed
129
+ decisionQueue.cleanup(24 * 60 * 60 * 1000);
130
+ decisionQueue.save();
131
+ // Recompute queue_depth from live state (never restore persisted gauge)
132
+ // WP-24: pendingCount is now async — computed from live state
133
+ decisionQueue.pendingCount().then(count => metrics.gauge("queue_depth", count)).catch(() => { });
134
+ const auditLogger = new AuditLogger(path.resolve(rootDir, ".openclaw/audit"), metrics);
135
+ const dispatcher = new Dispatcher(workerEngine, orgEngine, pipelineEngine);
136
+ const pipelineCheckpoint = new PipelineCheckpoint();
137
+ const checkpointStorePath = path.resolve(rootDir, ".openclaw/pipeline-checkpoints.json");
138
+ pipelineCheckpoint.load(checkpointStorePath);
139
+ // Report interrupted pipelines on startup
140
+ const interrupted = pipelineCheckpoint.list("running").concat(pipelineCheckpoint.list("awaiting_approval"));
141
+ if (interrupted.length > 0) {
142
+ api.logger.info(`[recovery] ${interrupted.length} interrupted pipeline(s) detected. Run 'ai-company recover' for details.`);
143
+ }
144
+ pipelineCheckpoint.cleanup(24 * 60 * 60 * 1000);
145
+ pipelineCheckpoint.save();
146
+ // Re-enqueue awaiting_approval checkpoints into DecisionQueue
147
+ const awaitingApproval = pipelineCheckpoint.list("awaiting_approval");
148
+ for (const cp of awaitingApproval) {
149
+ const stageEntry = cp.stages[cp.currentStageIndex];
150
+ if (stageEntry && !decisionQueue.get(cp.sessionKey)) {
151
+ decisionQueue.enqueue(cp.sessionKey, stageEntry.stage, stageEntry.worker, cp.objective);
152
+ }
153
+ }
154
+ // Recompute active_pipelines from live state (never restore persisted gauge)
155
+ metrics.gauge("active_pipelines", taskState.list("running").length);
156
+ const dispatchService = new DispatchService(api.runtime.subagent, session, workboardGateway, workerEngine, taskState, dispatcher, orgEngine, workersPath, decisionQueue, auditLogger, undefined, // approvalTimeoutMs default
157
+ pipelineCheckpoint, metrics, leaseProvider, nodeId);
158
+ // Subscribe to DecisionQueue decision events for audit logging
159
+ decisionQueue.on("decision", (evt) => {
160
+ auditLogger.write({
161
+ ts: new Date().toISOString(),
162
+ sessionKey: evt.sessionKey,
163
+ event: evt.status === "approved" ? "approved" : "rejected",
164
+ decisionStatus: evt.status,
165
+ reason: evt.reason,
166
+ operator: evt.operator,
167
+ });
168
+ });
169
+ // CLI commands: openclaw ai-company dispatch|status|result|audit
170
+ api.registerCli(async ({ program }) => {
171
+ registerAiCompanyCli({
172
+ program,
173
+ dispatchService,
174
+ session,
175
+ log: (msg) => api.logger.info(msg),
176
+ decisionQueue,
177
+ auditLogger,
178
+ pipelineCheckpoint,
179
+ });
180
+ }, {
181
+ descriptors: [
182
+ {
183
+ name: "ai-company",
184
+ description: "AI Engineering Company operator commands",
185
+ hasSubcommands: true,
186
+ },
187
+ ],
188
+ });
189
+ // Agent tools: dispatch, status, result
190
+ const tools = createAiCompanyTools({ dispatchService, session, decisionQueue });
191
+ for (const tool of tools) {
192
+ api.registerTool(tool);
193
+ }
194
+ // Gateway RPC: dispatch, status, result, approvals
195
+ registerAiCompanyGatewayMethods({ api, dispatchService, session, decisionQueue, metrics });
196
+ // Slash command: /aicompany <task>
197
+ api.registerCommand({
198
+ name: "aicompany",
199
+ description: "Dispatch a natural-language engineering task to the AI Engineering Company",
200
+ acceptsArgs: true,
201
+ handler: handleAiCompanyCommand({ dispatchService, dispatcher }),
202
+ });
203
+ // Lifecycle cleanup registration.
204
+ // ponytail: init logic (engines, workboard) should run in a gateway_start hook.
205
+ // Move to registerHook when that API is available.
206
+ api.lifecycle.registerRuntimeLifecycle({
207
+ id: "ai-engineering-company-init",
208
+ cleanup: async () => {
209
+ decisionQueue.save();
210
+ pipelineCheckpoint.save();
211
+ metrics.save();
212
+ if (redisClose)
213
+ await redisClose();
214
+ },
215
+ });
216
+ },
217
+ });
218
+ // Attach tool-plugin metadata so `openclaw plugins build` can extract manifest info.
219
+ Object.defineProperty(plugin, Symbol.for("openclaw.plugin-sdk.tool-plugin.metadata"), {
220
+ value: {
221
+ id: "ai-engineering-company",
222
+ name: "AI Engineering Company",
223
+ description: "Management layer that orchestrates AI agents for engineering tasks",
224
+ activation: { onStartup: true },
225
+ configSchema: {
226
+ type: "object",
227
+ properties: {
228
+ offices: { type: "string", description: "Path to offices.json config" },
229
+ workflows: { type: "string", description: "Path to workflows.json config" },
230
+ workers: { type: "string", description: "Path to workers directory" },
231
+ boardId: { type: "string", description: "Workboard board ID for task cards" },
232
+ },
233
+ },
234
+ tools: [
235
+ {
236
+ name: "ai_company_dispatch",
237
+ label: "AI Company Dispatch",
238
+ description: "Submit a task to the AI Engineering Company Dispatcher agent.",
239
+ parameters: {
240
+ type: "object",
241
+ properties: {
242
+ message: { type: "string", description: "Task description for the Dispatcher agent." },
243
+ wait: { type: "boolean", description: "Wait for completion (default: true)." },
244
+ timeout: { type: "number", description: "Max wait time in milliseconds (default: 900000)." },
245
+ },
246
+ required: ["message"],
247
+ },
248
+ },
249
+ {
250
+ name: "ai_company_status",
251
+ label: "AI Company Status",
252
+ description: "Query the status of a dispatched task or list recent dispatches.",
253
+ parameters: {
254
+ type: "object",
255
+ properties: {
256
+ sessionKey: { type: "string", description: "Session key to query. Omit to list recent dispatches." },
257
+ },
258
+ },
259
+ },
260
+ {
261
+ name: "ai_company_result",
262
+ label: "AI Company Result",
263
+ description: "Retrieve the result messages of a completed dispatch.",
264
+ parameters: {
265
+ type: "object",
266
+ properties: {
267
+ sessionKey: { type: "string", description: "Session key of the completed task." },
268
+ limit: { type: "number", description: "Max messages to retrieve (default: 50)." },
269
+ },
270
+ required: ["sessionKey"],
271
+ },
272
+ },
273
+ ],
274
+ },
275
+ });
276
+ export default plugin;
277
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAiC,MAAM,kCAAkC,CAAC;AACpG,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAA0B,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,yDAAyD;AACzD,MAAM,mBAAmB,GAAwB;IAC/C,WAAW;IACX,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,EAAE;IACrE,EAAE,IAAI,EAAE,4BAA4B,EAAE,IAAI,EAAE,SAAS,EAAE;IACvD,EAAE,IAAI,EAAE,wBAAwB,EAAE,IAAI,EAAE,SAAS,EAAE;IACnD,EAAE,IAAI,EAAE,yBAAyB,EAAE,IAAI,EAAE,SAAS,EAAE;IACpD,EAAE,IAAI,EAAE,4BAA4B,EAAE,IAAI,EAAE,SAAS,EAAE;IACvD,EAAE,IAAI,EAAE,4BAA4B,EAAE,IAAI,EAAE,SAAS,EAAE;IACvD,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,SAAS,EAAE;IACrD,EAAE,IAAI,EAAE,6BAA6B,EAAE,IAAI,EAAE,SAAS,EAAE;IACxD,EAAE,IAAI,EAAE,wBAAwB,EAAE,IAAI,EAAE,SAAS,EAAE;IACnD,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,SAAS,EAAE;IACrD,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,SAAS,EAAE;IAClD,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,SAAS,EAAE;IAChD,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,SAAS,EAAE;IAClD,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,SAAS,EAAE;IAC/C,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,SAAS,EAAE;IACrD,EAAE,IAAI,EAAE,wBAAwB,EAAE,IAAI,EAAE,SAAS,EAAE;IACnD,EAAE,IAAI,EAAE,wBAAwB,EAAE,IAAI,EAAE,SAAS,EAAE;IACnD,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,SAAS,EAAE;IAC/C,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,SAAS,EAAE;IACrD,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE;IACtC,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE;IAC7C,SAAS;IACT,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE;IACtC,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,OAAO,EAAE;IAC3C,aAAa;IACb,EAAE,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,WAAW,EAAE;IACnD,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,WAAW,EAAE;IAChD,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,WAAW,EAAE;IAClD,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,WAAW,EAAE;IAC3D,SAAS;IACT,EAAE,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,OAAO,EAAE;CAChD,CAAC;AAEF,MAAM,MAAM,GAAG,iBAAiB,CAAC;IAC/B,EAAE,EAAE,wBAAwB;IAC5B,IAAI,EAAE,wBAAwB;IAC9B,WAAW,EAAE,oEAAoE;IACjF,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QAE9D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;QAEtC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAG,MAAM,CAAC,OAAkB,IAAI,qBAAqB,CAAC,CAAC;QAC/F,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAG,MAAM,CAAC,YAAuB,IAAI,uCAAuC,CAAC,CAAC;QAClH,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAChC,OAAO,EACN,MAAM,CAAC,SAAoB,IAAI,uBAAuB,CACxD,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAG,MAAM,CAAC,OAAkB,IAAI,gBAAgB,CAAC,CAAC;QAE1F,oEAAoE;QACpE,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,mBAAmB,CAAC,CAAC;QACzD,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAE/B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,aAAa,CAAC,CAAC;QACzD,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;QAEnD,2EAA2E;QAC3E,iEAAiE;QACjE,6EAA6E;QAC7E,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC;YAC5C,OAAO,EAAE;gBACP,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;oBACnC,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;oBAC7D,OAAO;wBACL,EAAE,EAAE,QAAQ,CAAC,EAAE;wBACf,IAAI,EAAE,QAAQ,CAAC,OAAkC;wBACjD,KAAK,EAAE,QAAQ,CAAC,KAAK;qBACtB,CAAC;gBACJ,CAAC;aACF;YACD,OAAO,EAAG,MAAM,CAAC,OAAkB,IAAI,YAAY;SACpD,CAAC,CAAC;QAEH,4EAA4E;QAC5E,MAAM,OAAO,GAAI,GAAG,CAAC,OAAqE,CAAC,OAAO;eAC7F,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;QAChC,kCAAkC;QAClC,MAAM,MAAM,GAAI,MAAM,CAAC,MAAiB,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;QAE1D,mCAAmC;QACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAK,MAAM,CAAC,KAA0B,EAAE,GAAG,CAAC;QAC7F,MAAM,WAAW,GAAI,MAAM,CAAC,KAA6B,EAAE,MAAM,IAAI,aAAa,CAAC;QAEnF,IAAI,YAAoD,CAAC;QACzD,IAAI,aAAuD,CAAC;QAC5D,IAAI,UAAU,GAAiC,IAAI,CAAC;QAEpD,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;gBACzD,MAAM,GAAG,GAAG,IAAI,kBAAkB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;gBAC1D,YAAY,GAAG,GAAG,CAAC;gBACnB,aAAa,GAAG,GAAG,CAAC;gBACpB,UAAU,GAAG,KAAK,IAAI,EAAE,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;gBACnE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kCAAkC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC7F,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,QAAQ,8CAA+C,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;gBACtI,YAAY,GAAG,IAAI,kBAAkB,EAAE,CAAC;gBACxC,aAAa,GAAG,IAAI,mBAAmB,EAAE,CAAC;YAC5C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,YAAY,GAAG,IAAI,kBAAkB,EAAE,CAAC;YACxC,aAAa,GAAG,IAAI,mBAAmB,EAAE,CAAC;QAC5C,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACzC,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC/D,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC;QAC5E,aAAa,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACtC,+EAA+E;QAC/E,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3C,aAAa,CAAC,IAAI,EAAE,CAAC;QAErB,wEAAwE;QACxE,8DAA8D;QAC9D,aAAa,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAEhG,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAC;QACvF,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,YAAY,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;QAC3E,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACpD,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,qCAAqC,CAAC,CAAC;QACzF,kBAAkB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC7C,0CAA0C;QAC1C,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC5G,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,WAAW,CAAC,MAAM,0EAA0E,CAAC,CAAC;QAC9H,CAAC;QACD,kBAAkB,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAChD,kBAAkB,CAAC,IAAI,EAAE,CAAC;QAE1B,8DAA8D;QAC9D,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACtE,KAAK,MAAM,EAAE,IAAI,gBAAgB,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;YACnD,IAAI,UAAU,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpD,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,KAAuE,EAAE,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;YAC5J,CAAC;QACH,CAAC;QAED,6EAA6E;QAC7E,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;QAEpE,MAAM,eAAe,GAAG,IAAI,eAAe,CACzC,GAAG,CAAC,OAAO,CAAC,QAAQ,EACpB,OAAO,EACP,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,aAAa,EACb,WAAW,EACX,SAAS,EAAE,4BAA4B;QACvC,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,MAAM,CACP,CAAC;QAEF,+DAA+D;QAC/D,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,GAAgG,EAAE,EAAE;YAChI,WAAW,CAAC,KAAK,CAAC;gBAChB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBAC5B,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;gBAC1D,cAAc,EAAE,GAAG,CAAC,MAAM;gBAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;aACvB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,iEAAiE;QACjE,GAAG,CAAC,WAAW,CACb,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YACpB,oBAAoB,CAAC;gBACnB,OAAO;gBACP,eAAe;gBACf,OAAO;gBACP,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;gBAClC,aAAa;gBACb,WAAW;gBACX,kBAAkB;aACnB,CAAC,CAAC;QACL,CAAC,EACD;YACE,WAAW,EAAE;gBACX;oBACE,IAAI,EAAE,YAAY;oBAClB,WAAW,EAAE,0CAA0C;oBACvD,cAAc,EAAE,IAAI;iBACrB;aACF;SACF,CACF,CAAC;QAEF,wCAAwC;QACxC,MAAM,KAAK,GAAG,oBAAoB,CAAC,EAAE,eAAe,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;QAChF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAED,mDAAmD;QACnD,+BAA+B,CAAC,EAAE,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC;QAE3F,mCAAmC;QACnC,GAAG,CAAC,eAAe,CAAC;YAClB,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,4EAA4E;YACzF,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,sBAAsB,CAAC,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC;SACjE,CAAC,CAAC;QAEH,kCAAkC;QAClC,gFAAgF;QAChF,mDAAmD;QACnD,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC;YACrC,EAAE,EAAE,6BAA6B;YACjC,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,aAAa,CAAC,IAAI,EAAE,CAAC;gBACrB,kBAAkB,CAAC,IAAI,EAAE,CAAC;gBAC1B,OAAO,CAAC,IAAI,EAAE,CAAC;gBACf,IAAI,UAAU;oBAAE,MAAM,UAAU,EAAE,CAAC;YACrC,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,qFAAqF;AACrF,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,0CAA0C,CAAC,EAAE;IACpF,KAAK,EAAE;QACL,EAAE,EAAE,wBAAwB;QAC5B,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,oEAAoE;QACjF,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;QAC/B,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;gBACvE,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+BAA+B,EAAE;gBAC3E,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE;gBACrE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;aAC9E;SACF;QACD,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,qBAAqB;gBAC3B,KAAK,EAAE,qBAAqB;gBAC5B,WAAW,EAAE,+DAA+D;gBAC5E,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,4CAA4C,EAAE;wBACtF,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,sCAAsC,EAAE;wBAC9E,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kDAAkD,EAAE;qBAC7F;oBACD,QAAQ,EAAE,CAAC,SAAS,CAAC;iBACtB;aACF;YACD;gBACE,IAAI,EAAE,mBAAmB;gBACzB,KAAK,EAAE,mBAAmB;gBAC1B,WAAW,EAAE,kEAAkE;gBAC/E,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uDAAuD,EAAE;qBACrG;iBACF;aACF;YACD;gBACE,IAAI,EAAE,mBAAmB;gBACzB,KAAK,EAAE,mBAAmB;gBAC1B,WAAW,EAAE,uDAAuD;gBACpE,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oCAAoC,EAAE;wBACjF,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;qBAClF;oBACD,QAAQ,EAAE,CAAC,YAAY,CAAC;iBACzB;aACF;SACF;KACF;CACF,CAAC,CAAC;AAEH,eAAe,MAAkC,CAAC"}
@@ -0,0 +1,31 @@
1
+ export interface Lease {
2
+ sessionKey: string;
3
+ nodeId: string;
4
+ acquiredAt: number;
5
+ expiresAt: number;
6
+ }
7
+ export interface LeaseProvider {
8
+ /**
9
+ * Attempt to acquire a lease. Returns true if acquired, false if already held.
10
+ * TTL is in seconds.
11
+ */
12
+ acquire(sessionKey: string, nodeId: string, ttlSeconds: number): Promise<boolean>;
13
+ /**
14
+ * Renew an existing lease. Returns true if renewed, false if not the current owner.
15
+ * TTL is in seconds.
16
+ */
17
+ renew(sessionKey: string, nodeId: string, ttlSeconds: number): Promise<boolean>;
18
+ /**
19
+ * Release a lease. Returns true if released, false if not the current owner.
20
+ */
21
+ release(sessionKey: string, nodeId: string): Promise<boolean>;
22
+ /**
23
+ * Get the current lease for a sessionKey, if any and not expired.
24
+ */
25
+ get(sessionKey: string): Promise<Lease | undefined>;
26
+ /**
27
+ * Remove expired leases. Returns count of removed leases.
28
+ */
29
+ cleanup(): Promise<number>;
30
+ }
31
+ //# sourceMappingURL=lease-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease-provider.d.ts","sourceRoot":"","sources":["../src/lease-provider.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAElF;;;OAGG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhF;;OAEG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9D;;OAEG;IACH,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IAEpD;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5B"}
@@ -0,0 +1,4 @@
1
+ // LeaseProvider interface — abstracts ownership leasing for pipeline execution.
2
+ // Implementations: MemoryLeaseProvider (default).
3
+ export {};
4
+ //# sourceMappingURL=lease-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease-provider.js","sourceRoot":"","sources":["../src/lease-provider.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,kDAAkD"}
@@ -0,0 +1,10 @@
1
+ import type { Lease, LeaseProvider } from "./lease-provider.js";
2
+ export declare class MemoryLeaseProvider implements LeaseProvider {
3
+ private readonly leases;
4
+ acquire(sessionKey: string, nodeId: string, ttlSeconds: number): Promise<boolean>;
5
+ renew(sessionKey: string, nodeId: string, ttlSeconds: number): Promise<boolean>;
6
+ release(sessionKey: string, nodeId: string): Promise<boolean>;
7
+ get(sessionKey: string): Promise<Lease | undefined>;
8
+ cleanup(): Promise<number>;
9
+ }
10
+ //# sourceMappingURL=memory-lease-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-lease-provider.d.ts","sourceRoot":"","sources":["../src/memory-lease-provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEhE,qBAAa,mBAAoB,YAAW,aAAa;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IAEnD,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAejF,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS/E,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS7D,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAQnD,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAW3B"}
@@ -0,0 +1,54 @@
1
+ // MemoryLeaseProvider — default in-memory LeaseProvider implementation.
2
+ // Single-node leases with TTL expiration. No distributed coordination.
3
+ export class MemoryLeaseProvider {
4
+ leases = new Map();
5
+ acquire(sessionKey, nodeId, ttlSeconds) {
6
+ const existing = this.leases.get(sessionKey);
7
+ if (existing && existing.expiresAt > Date.now()) {
8
+ return Promise.resolve(false); // already held
9
+ }
10
+ const now = Date.now();
11
+ this.leases.set(sessionKey, {
12
+ sessionKey,
13
+ nodeId,
14
+ acquiredAt: now,
15
+ expiresAt: now + ttlSeconds * 1000,
16
+ });
17
+ return Promise.resolve(true);
18
+ }
19
+ renew(sessionKey, nodeId, ttlSeconds) {
20
+ const existing = this.leases.get(sessionKey);
21
+ if (!existing || existing.nodeId !== nodeId || existing.expiresAt <= Date.now()) {
22
+ return Promise.resolve(false);
23
+ }
24
+ existing.expiresAt = Date.now() + ttlSeconds * 1000;
25
+ return Promise.resolve(true);
26
+ }
27
+ release(sessionKey, nodeId) {
28
+ const existing = this.leases.get(sessionKey);
29
+ if (!existing || existing.nodeId !== nodeId) {
30
+ return Promise.resolve(false);
31
+ }
32
+ this.leases.delete(sessionKey);
33
+ return Promise.resolve(true);
34
+ }
35
+ get(sessionKey) {
36
+ const existing = this.leases.get(sessionKey);
37
+ if (!existing || existing.expiresAt <= Date.now()) {
38
+ return Promise.resolve(undefined);
39
+ }
40
+ return Promise.resolve(existing);
41
+ }
42
+ cleanup() {
43
+ const now = Date.now();
44
+ let removed = 0;
45
+ for (const [key, lease] of this.leases) {
46
+ if (lease.expiresAt <= now) {
47
+ this.leases.delete(key);
48
+ removed++;
49
+ }
50
+ }
51
+ return Promise.resolve(removed);
52
+ }
53
+ }
54
+ //# sourceMappingURL=memory-lease-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-lease-provider.js","sourceRoot":"","sources":["../src/memory-lease-provider.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,uEAAuE;AAIvE,MAAM,OAAO,mBAAmB;IACb,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAC;IAEnD,OAAO,CAAC,UAAkB,EAAE,MAAc,EAAE,UAAkB;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,QAAQ,IAAI,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAChD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe;QAChD,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE;YAC1B,UAAU;YACV,MAAM;YACN,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,GAAG,GAAG,UAAU,GAAG,IAAI;SACnC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,UAAkB,EAAE,MAAc,EAAE,UAAkB;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAChF,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,GAAG,IAAI,CAAC;QACpD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,CAAC,UAAkB,EAAE,MAAc;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,UAAkB;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAClD,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,OAAO;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,KAAK,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACxB,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import type { DecisionStatus } from "./decision-queue.js";
2
+ import type { QueueBackend, QueueEntry, QueueEntryUpdate } from "./queue-backend.js";
3
+ export declare class MemoryQueueBackend implements QueueBackend {
4
+ private readonly entries;
5
+ private filePath;
6
+ enqueue(entry: QueueEntry): Promise<QueueEntry>;
7
+ get(sessionKey: string): Promise<QueueEntry | undefined>;
8
+ list(filter?: DecisionStatus): Promise<QueueEntry[]>;
9
+ update(sessionKey: string, update: QueueEntryUpdate): Promise<QueueEntry | null>;
10
+ remove(sessionKey: string): Promise<boolean>;
11
+ load(filePath: string): Promise<void>;
12
+ save(filePath?: string): Promise<void>;
13
+ trySave(): Promise<void>;
14
+ cleanup(maxAgeMs: number): Promise<number>;
15
+ }
16
+ //# sourceMappingURL=memory-queue-backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-queue-backend.d.ts","sourceRoot":"","sources":["../src/memory-queue-backend.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAErF,qBAAa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAuB;IAEvC,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAM/C,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIxD,IAAI,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAKpD,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAWhF,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM5C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBrC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAetC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAc3C"}
@@ -0,0 +1,93 @@
1
+ // MemoryQueueBackend — default in-memory QueueBackend implementation.
2
+ // Matches current DecisionQueue behavior exactly.
3
+ import * as fs from "node:fs";
4
+ import * as path from "node:path";
5
+ export class MemoryQueueBackend {
6
+ entries = new Map();
7
+ filePath = null;
8
+ enqueue(entry) {
9
+ this.entries.set(entry.sessionKey, entry);
10
+ this.trySave();
11
+ return Promise.resolve(entry);
12
+ }
13
+ get(sessionKey) {
14
+ return Promise.resolve(this.entries.get(sessionKey));
15
+ }
16
+ list(filter) {
17
+ const all = [...this.entries.values()];
18
+ return Promise.resolve(filter ? all.filter((d) => d.status === filter) : all);
19
+ }
20
+ update(sessionKey, update) {
21
+ const entry = this.entries.get(sessionKey);
22
+ if (!entry)
23
+ return Promise.resolve(null);
24
+ if (update.status !== undefined)
25
+ entry.status = update.status;
26
+ if (update.reason !== undefined)
27
+ entry.reason = update.reason;
28
+ if (update.operator !== undefined)
29
+ entry.operator = update.operator;
30
+ if (update.decidedAt !== undefined)
31
+ entry.decidedAt = update.decidedAt;
32
+ this.trySave();
33
+ return Promise.resolve(entry);
34
+ }
35
+ remove(sessionKey) {
36
+ const result = this.entries.delete(sessionKey);
37
+ if (result)
38
+ this.trySave();
39
+ return Promise.resolve(result);
40
+ }
41
+ load(filePath) {
42
+ this.filePath = filePath;
43
+ try {
44
+ const raw = fs.readFileSync(filePath, "utf-8");
45
+ const parsed = JSON.parse(raw);
46
+ if (!Array.isArray(parsed))
47
+ return Promise.resolve();
48
+ for (const entry of parsed) {
49
+ if (entry && typeof entry.sessionKey === "string" && entry.status === "pending") {
50
+ this.entries.set(entry.sessionKey, entry);
51
+ }
52
+ }
53
+ }
54
+ catch {
55
+ // Missing or corrupt file — start with empty queue
56
+ }
57
+ return Promise.resolve();
58
+ }
59
+ save(filePath) {
60
+ const target = filePath ?? this.filePath;
61
+ if (!target)
62
+ return Promise.resolve();
63
+ const pending = [...this.entries.values()].filter((d) => d.status === "pending");
64
+ const tmpPath = target + ".tmp";
65
+ try {
66
+ fs.mkdirSync(path.dirname(target), { recursive: true });
67
+ fs.writeFileSync(tmpPath, JSON.stringify(pending, null, 2) + "\n", "utf-8");
68
+ fs.renameSync(tmpPath, target);
69
+ }
70
+ catch {
71
+ // Persistence failure — queue remains functional in-memory
72
+ }
73
+ return Promise.resolve();
74
+ }
75
+ trySave() {
76
+ return this.save();
77
+ }
78
+ cleanup(maxAgeMs) {
79
+ const now = Date.now();
80
+ let removed = 0;
81
+ for (const [key, entry] of this.entries) {
82
+ if (entry.status === "pending" && now - entry.requestedAt > maxAgeMs) {
83
+ this.entries.delete(key);
84
+ removed++;
85
+ }
86
+ }
87
+ if (removed > 0) {
88
+ this.trySave();
89
+ }
90
+ return Promise.resolve(removed);
91
+ }
92
+ }
93
+ //# sourceMappingURL=memory-queue-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-queue-backend.js","sourceRoot":"","sources":["../src/memory-queue-backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ export type MetricType = "counter" | "gauge" | "histogram" | "timer";
2
+ export interface MetricDeclaration {
3
+ name: string;
4
+ type: MetricType;
5
+ help?: string;
6
+ buckets?: number[];
7
+ }
8
+ export interface HistogramData {
9
+ buckets: number[];
10
+ counts: number[];
11
+ sum: number;
12
+ count: number;
13
+ }
14
+ export interface TimerData {
15
+ count: number;
16
+ sum: number;
17
+ min: number;
18
+ max: number;
19
+ }
20
+ export type MetricValue = number | HistogramData | TimerData;
21
+ export interface MetricsSnapshot {
22
+ counters: Record<string, number>;
23
+ gauges: Record<string, number>;
24
+ histograms: Record<string, HistogramData>;
25
+ timers: Record<string, TimerData>;
26
+ }
27
+ export declare class MetricsRegistry {
28
+ private readonly declarations;
29
+ private readonly counters;
30
+ private readonly gauges;
31
+ private readonly histograms;
32
+ private readonly timers;
33
+ private filePath;
34
+ constructor(declarations: MetricDeclaration[]);
35
+ private assertDeclared;
36
+ increment(name: string, value?: number): void;
37
+ gauge(name: string, value: number): void;
38
+ observe(name: string, value: number): void;
39
+ startTimer(name: string): () => void;
40
+ getSnapshot(): MetricsSnapshot;
41
+ toJSON(): string;
42
+ /**
43
+ * Load persisted counters, histograms, and timers from JSON.
44
+ * Gauges are NOT restored — they must be recomputed from live state.
45
+ */
46
+ loadFromJSON(json: string): void;
47
+ /**
48
+ * Load from a JSON file. Gracefully handles missing or corrupt files.
49
+ */
50
+ load(filePath: string): void;
51
+ /**
52
+ * Save current snapshot to the configured file path. Atomic write (.tmp + rename).
53
+ */
54
+ save(filePath?: string): void;
55
+ /** Reset all metrics to initial values. Declarations are preserved. */
56
+ reset(): void;
57
+ }
58
+ //# sourceMappingURL=metrics-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-registry.d.ts","sourceRoot":"","sources":["../src/metrics-registry.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC;AAID,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;IACrE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoC;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,YAAY,EAAE,iBAAiB,EAAE;IA+B7C,OAAO,CAAC,cAAc;IAUtB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,IAAI;IAMxC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKxC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAkB1C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI;IAapC,WAAW,IAAI,eAAe;IAgB9B,MAAM,IAAI,MAAM;IAIhB;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAiChC;;OAEG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAU5B;;OAEG;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAa7B,uEAAuE;IACvE,KAAK,IAAI,IAAI;CAgBd"}