@build-astron-co/nimbus 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +628 -0
  3. package/bin/nimbus +38 -0
  4. package/package.json +80 -0
  5. package/src/__tests__/app.test.ts +76 -0
  6. package/src/__tests__/audit.test.ts +877 -0
  7. package/src/__tests__/circuit-breaker.test.ts +116 -0
  8. package/src/__tests__/cli-run.test.ts +115 -0
  9. package/src/__tests__/context-manager.test.ts +502 -0
  10. package/src/__tests__/context.test.ts +242 -0
  11. package/src/__tests__/enterprise.test.ts +401 -0
  12. package/src/__tests__/generator.test.ts +433 -0
  13. package/src/__tests__/hooks.test.ts +582 -0
  14. package/src/__tests__/init.test.ts +436 -0
  15. package/src/__tests__/intent-parser.test.ts +229 -0
  16. package/src/__tests__/llm-router.test.ts +209 -0
  17. package/src/__tests__/lsp.test.ts +293 -0
  18. package/src/__tests__/modes.test.ts +336 -0
  19. package/src/__tests__/permissions.test.ts +338 -0
  20. package/src/__tests__/serve.test.ts +275 -0
  21. package/src/__tests__/sessions.test.ts +227 -0
  22. package/src/__tests__/sharing.test.ts +288 -0
  23. package/src/__tests__/snapshots.test.ts +581 -0
  24. package/src/__tests__/state-db.test.ts +334 -0
  25. package/src/__tests__/stream-with-tools.test.ts +732 -0
  26. package/src/__tests__/subagents.test.ts +176 -0
  27. package/src/__tests__/system-prompt.test.ts +169 -0
  28. package/src/__tests__/tool-converter.test.ts +256 -0
  29. package/src/__tests__/tool-schemas.test.ts +397 -0
  30. package/src/__tests__/tools.test.ts +143 -0
  31. package/src/__tests__/version.test.ts +49 -0
  32. package/src/agent/compaction-agent.ts +227 -0
  33. package/src/agent/context-manager.ts +435 -0
  34. package/src/agent/context.ts +427 -0
  35. package/src/agent/deploy-preview.ts +426 -0
  36. package/src/agent/index.ts +68 -0
  37. package/src/agent/loop.ts +717 -0
  38. package/src/agent/modes.ts +429 -0
  39. package/src/agent/permissions.ts +466 -0
  40. package/src/agent/subagents/base.ts +116 -0
  41. package/src/agent/subagents/cost.ts +51 -0
  42. package/src/agent/subagents/explore.ts +42 -0
  43. package/src/agent/subagents/general.ts +54 -0
  44. package/src/agent/subagents/index.ts +102 -0
  45. package/src/agent/subagents/infra.ts +59 -0
  46. package/src/agent/subagents/security.ts +69 -0
  47. package/src/agent/system-prompt.ts +436 -0
  48. package/src/app.ts +122 -0
  49. package/src/audit/activity-log.ts +290 -0
  50. package/src/audit/compliance-checker.ts +540 -0
  51. package/src/audit/cost-tracker.ts +318 -0
  52. package/src/audit/index.ts +23 -0
  53. package/src/audit/security-scanner.ts +596 -0
  54. package/src/auth/guard.ts +75 -0
  55. package/src/auth/index.ts +56 -0
  56. package/src/auth/oauth.ts +455 -0
  57. package/src/auth/providers.ts +470 -0
  58. package/src/auth/sso.ts +113 -0
  59. package/src/auth/store.ts +505 -0
  60. package/src/auth/types.ts +187 -0
  61. package/src/build.ts +141 -0
  62. package/src/cli/index.ts +16 -0
  63. package/src/cli/init.ts +854 -0
  64. package/src/cli/openapi-spec.ts +356 -0
  65. package/src/cli/run.ts +237 -0
  66. package/src/cli/serve-auth.ts +80 -0
  67. package/src/cli/serve.ts +462 -0
  68. package/src/cli/web.ts +67 -0
  69. package/src/cli.ts +1417 -0
  70. package/src/clients/core-engine-client.ts +227 -0
  71. package/src/clients/enterprise-client.ts +334 -0
  72. package/src/clients/generator-client.ts +351 -0
  73. package/src/clients/git-client.ts +627 -0
  74. package/src/clients/github-client.ts +410 -0
  75. package/src/clients/helm-client.ts +504 -0
  76. package/src/clients/index.ts +80 -0
  77. package/src/clients/k8s-client.ts +497 -0
  78. package/src/clients/llm-client.ts +161 -0
  79. package/src/clients/rest-client.ts +130 -0
  80. package/src/clients/service-discovery.ts +33 -0
  81. package/src/clients/terraform-client.ts +482 -0
  82. package/src/clients/tools-client.ts +1843 -0
  83. package/src/clients/ws-client.ts +115 -0
  84. package/src/commands/analyze/index.ts +352 -0
  85. package/src/commands/apply/helm.ts +473 -0
  86. package/src/commands/apply/index.ts +213 -0
  87. package/src/commands/apply/k8s.ts +454 -0
  88. package/src/commands/apply/terraform.ts +582 -0
  89. package/src/commands/ask.ts +167 -0
  90. package/src/commands/audit/index.ts +238 -0
  91. package/src/commands/auth-cloud.ts +294 -0
  92. package/src/commands/auth-list.ts +134 -0
  93. package/src/commands/auth-profile.ts +121 -0
  94. package/src/commands/auth-status.ts +141 -0
  95. package/src/commands/aws/ec2.ts +501 -0
  96. package/src/commands/aws/iam.ts +397 -0
  97. package/src/commands/aws/index.ts +133 -0
  98. package/src/commands/aws/lambda.ts +396 -0
  99. package/src/commands/aws/rds.ts +439 -0
  100. package/src/commands/aws/s3.ts +439 -0
  101. package/src/commands/aws/vpc.ts +393 -0
  102. package/src/commands/aws-discover.ts +649 -0
  103. package/src/commands/aws-terraform.ts +805 -0
  104. package/src/commands/azure/aks.ts +376 -0
  105. package/src/commands/azure/functions.ts +253 -0
  106. package/src/commands/azure/index.ts +116 -0
  107. package/src/commands/azure/storage.ts +478 -0
  108. package/src/commands/azure/vm.ts +355 -0
  109. package/src/commands/billing/index.ts +256 -0
  110. package/src/commands/chat.ts +314 -0
  111. package/src/commands/config.ts +346 -0
  112. package/src/commands/cost/cloud-cost-estimator.ts +266 -0
  113. package/src/commands/cost/estimator.ts +79 -0
  114. package/src/commands/cost/index.ts +594 -0
  115. package/src/commands/cost/parsers/terraform.ts +273 -0
  116. package/src/commands/cost/parsers/types.ts +25 -0
  117. package/src/commands/cost/pricing/aws.ts +544 -0
  118. package/src/commands/cost/pricing/azure.ts +499 -0
  119. package/src/commands/cost/pricing/gcp.ts +396 -0
  120. package/src/commands/cost/pricing/index.ts +40 -0
  121. package/src/commands/demo.ts +250 -0
  122. package/src/commands/doctor.ts +794 -0
  123. package/src/commands/drift/index.ts +439 -0
  124. package/src/commands/explain.ts +277 -0
  125. package/src/commands/feedback.ts +389 -0
  126. package/src/commands/fix.ts +324 -0
  127. package/src/commands/fs/index.ts +402 -0
  128. package/src/commands/gcp/compute.ts +325 -0
  129. package/src/commands/gcp/functions.ts +271 -0
  130. package/src/commands/gcp/gke.ts +438 -0
  131. package/src/commands/gcp/iam.ts +344 -0
  132. package/src/commands/gcp/index.ts +129 -0
  133. package/src/commands/gcp/storage.ts +284 -0
  134. package/src/commands/generate-helm.ts +1249 -0
  135. package/src/commands/generate-k8s.ts +1560 -0
  136. package/src/commands/generate-terraform.ts +1460 -0
  137. package/src/commands/gh/index.ts +863 -0
  138. package/src/commands/git/index.ts +1343 -0
  139. package/src/commands/helm/index.ts +1126 -0
  140. package/src/commands/help.ts +539 -0
  141. package/src/commands/history.ts +142 -0
  142. package/src/commands/import.ts +868 -0
  143. package/src/commands/index.ts +367 -0
  144. package/src/commands/init.ts +1046 -0
  145. package/src/commands/k8s/index.ts +1137 -0
  146. package/src/commands/login.ts +631 -0
  147. package/src/commands/logout.ts +83 -0
  148. package/src/commands/onboarding.ts +228 -0
  149. package/src/commands/plan/display.ts +279 -0
  150. package/src/commands/plan/index.ts +599 -0
  151. package/src/commands/preview.ts +452 -0
  152. package/src/commands/questionnaire.ts +1270 -0
  153. package/src/commands/resume.ts +55 -0
  154. package/src/commands/team/index.ts +346 -0
  155. package/src/commands/template.ts +232 -0
  156. package/src/commands/tf/index.ts +1034 -0
  157. package/src/commands/upgrade.ts +550 -0
  158. package/src/commands/usage/index.ts +134 -0
  159. package/src/commands/version.ts +170 -0
  160. package/src/compat/index.ts +2 -0
  161. package/src/compat/runtime.ts +12 -0
  162. package/src/compat/sqlite.ts +107 -0
  163. package/src/config/index.ts +17 -0
  164. package/src/config/manager.ts +530 -0
  165. package/src/config/safety-policy.ts +358 -0
  166. package/src/config/schema.ts +125 -0
  167. package/src/config/types.ts +527 -0
  168. package/src/context/context-db.ts +199 -0
  169. package/src/demo/index.ts +349 -0
  170. package/src/demo/scenarios/full-journey.ts +229 -0
  171. package/src/demo/scenarios/getting-started.ts +127 -0
  172. package/src/demo/scenarios/helm-release.ts +341 -0
  173. package/src/demo/scenarios/k8s-deployment.ts +194 -0
  174. package/src/demo/scenarios/terraform-vpc.ts +170 -0
  175. package/src/demo/types.ts +92 -0
  176. package/src/engine/cost-estimator.ts +438 -0
  177. package/src/engine/diagram-generator.ts +256 -0
  178. package/src/engine/drift-detector.ts +902 -0
  179. package/src/engine/executor.ts +1035 -0
  180. package/src/engine/index.ts +76 -0
  181. package/src/engine/orchestrator.ts +636 -0
  182. package/src/engine/planner.ts +720 -0
  183. package/src/engine/safety.ts +743 -0
  184. package/src/engine/verifier.ts +770 -0
  185. package/src/enterprise/audit.ts +348 -0
  186. package/src/enterprise/auth.ts +270 -0
  187. package/src/enterprise/billing.ts +822 -0
  188. package/src/enterprise/index.ts +17 -0
  189. package/src/enterprise/teams.ts +443 -0
  190. package/src/generator/best-practices.ts +1608 -0
  191. package/src/generator/helm.ts +630 -0
  192. package/src/generator/index.ts +37 -0
  193. package/src/generator/intent-parser.ts +514 -0
  194. package/src/generator/kubernetes.ts +976 -0
  195. package/src/generator/terraform.ts +1867 -0
  196. package/src/history/index.ts +8 -0
  197. package/src/history/manager.ts +322 -0
  198. package/src/history/types.ts +34 -0
  199. package/src/hooks/config.ts +432 -0
  200. package/src/hooks/engine.ts +391 -0
  201. package/src/hooks/index.ts +4 -0
  202. package/src/llm/auth-bridge.ts +198 -0
  203. package/src/llm/circuit-breaker.ts +140 -0
  204. package/src/llm/config-loader.ts +201 -0
  205. package/src/llm/cost-calculator.ts +171 -0
  206. package/src/llm/index.ts +8 -0
  207. package/src/llm/model-aliases.ts +115 -0
  208. package/src/llm/provider-registry.ts +63 -0
  209. package/src/llm/providers/anthropic.ts +433 -0
  210. package/src/llm/providers/bedrock.ts +477 -0
  211. package/src/llm/providers/google.ts +405 -0
  212. package/src/llm/providers/ollama.ts +767 -0
  213. package/src/llm/providers/openai-compatible.ts +340 -0
  214. package/src/llm/providers/openai.ts +328 -0
  215. package/src/llm/providers/openrouter.ts +338 -0
  216. package/src/llm/router.ts +1035 -0
  217. package/src/llm/types.ts +232 -0
  218. package/src/lsp/client.ts +298 -0
  219. package/src/lsp/languages.ts +116 -0
  220. package/src/lsp/manager.ts +278 -0
  221. package/src/mcp/client.ts +402 -0
  222. package/src/mcp/index.ts +5 -0
  223. package/src/mcp/manager.ts +133 -0
  224. package/src/nimbus.ts +214 -0
  225. package/src/plugins/index.ts +27 -0
  226. package/src/plugins/loader.ts +334 -0
  227. package/src/plugins/manager.ts +376 -0
  228. package/src/plugins/types.ts +284 -0
  229. package/src/scanners/cicd-scanner.ts +258 -0
  230. package/src/scanners/cloud-scanner.ts +466 -0
  231. package/src/scanners/framework-scanner.ts +469 -0
  232. package/src/scanners/iac-scanner.ts +388 -0
  233. package/src/scanners/index.ts +539 -0
  234. package/src/scanners/language-scanner.ts +276 -0
  235. package/src/scanners/package-manager-scanner.ts +277 -0
  236. package/src/scanners/types.ts +172 -0
  237. package/src/sessions/manager.ts +365 -0
  238. package/src/sessions/types.ts +44 -0
  239. package/src/sharing/sync.ts +296 -0
  240. package/src/sharing/viewer.ts +97 -0
  241. package/src/snapshots/index.ts +2 -0
  242. package/src/snapshots/manager.ts +530 -0
  243. package/src/state/artifacts.ts +147 -0
  244. package/src/state/audit.ts +137 -0
  245. package/src/state/billing.ts +240 -0
  246. package/src/state/checkpoints.ts +117 -0
  247. package/src/state/config.ts +67 -0
  248. package/src/state/conversations.ts +14 -0
  249. package/src/state/credentials.ts +154 -0
  250. package/src/state/db.ts +58 -0
  251. package/src/state/index.ts +26 -0
  252. package/src/state/messages.ts +115 -0
  253. package/src/state/projects.ts +123 -0
  254. package/src/state/schema.ts +236 -0
  255. package/src/state/sessions.ts +147 -0
  256. package/src/state/teams.ts +200 -0
  257. package/src/telemetry.ts +108 -0
  258. package/src/tools/aws-ops.ts +952 -0
  259. package/src/tools/azure-ops.ts +579 -0
  260. package/src/tools/file-ops.ts +593 -0
  261. package/src/tools/gcp-ops.ts +625 -0
  262. package/src/tools/git-ops.ts +773 -0
  263. package/src/tools/github-ops.ts +799 -0
  264. package/src/tools/helm-ops.ts +943 -0
  265. package/src/tools/index.ts +17 -0
  266. package/src/tools/k8s-ops.ts +819 -0
  267. package/src/tools/schemas/converter.ts +184 -0
  268. package/src/tools/schemas/devops.ts +612 -0
  269. package/src/tools/schemas/index.ts +73 -0
  270. package/src/tools/schemas/standard.ts +1144 -0
  271. package/src/tools/schemas/types.ts +705 -0
  272. package/src/tools/terraform-ops.ts +862 -0
  273. package/src/types/ambient.d.ts +193 -0
  274. package/src/types/config.ts +83 -0
  275. package/src/types/drift.ts +116 -0
  276. package/src/types/enterprise.ts +335 -0
  277. package/src/types/index.ts +20 -0
  278. package/src/types/plan.ts +44 -0
  279. package/src/types/request.ts +65 -0
  280. package/src/types/response.ts +54 -0
  281. package/src/types/service.ts +51 -0
  282. package/src/ui/App.tsx +997 -0
  283. package/src/ui/DeployPreview.tsx +169 -0
  284. package/src/ui/Header.tsx +68 -0
  285. package/src/ui/InputBox.tsx +350 -0
  286. package/src/ui/MessageList.tsx +585 -0
  287. package/src/ui/PermissionPrompt.tsx +151 -0
  288. package/src/ui/StatusBar.tsx +158 -0
  289. package/src/ui/ToolCallDisplay.tsx +409 -0
  290. package/src/ui/chat-ui.ts +853 -0
  291. package/src/ui/index.ts +33 -0
  292. package/src/ui/ink/index.ts +711 -0
  293. package/src/ui/streaming.ts +176 -0
  294. package/src/ui/types.ts +57 -0
  295. package/src/utils/analytics.ts +72 -0
  296. package/src/utils/cost-warning.ts +27 -0
  297. package/src/utils/env.ts +46 -0
  298. package/src/utils/errors.ts +69 -0
  299. package/src/utils/event-bus.ts +38 -0
  300. package/src/utils/index.ts +24 -0
  301. package/src/utils/logger.ts +171 -0
  302. package/src/utils/rate-limiter.ts +121 -0
  303. package/src/utils/service-auth.ts +49 -0
  304. package/src/utils/validation.ts +53 -0
  305. package/src/version.ts +4 -0
  306. package/src/watcher/index.ts +163 -0
  307. package/src/wizard/approval.ts +383 -0
  308. package/src/wizard/index.ts +25 -0
  309. package/src/wizard/prompts.ts +338 -0
  310. package/src/wizard/types.ts +171 -0
  311. package/src/wizard/ui.ts +556 -0
  312. package/src/wizard/wizard.ts +304 -0
  313. package/tsconfig.json +24 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Engine — barrel exports
3
+ *
4
+ * Re-exports all classes, interfaces, and key types from every engine module.
5
+ * Consumers can import from '@nimbus/engine' (or 'src/engine') without
6
+ * needing to know which sub-module a symbol lives in.
7
+ */
8
+
9
+ // ==========================================
10
+ // Planner
11
+ // ==========================================
12
+ export { Planner } from './planner';
13
+ export type { AgentTask, AgentPlan, PlanStep, PlanDependency, Risk } from './planner';
14
+
15
+ // ==========================================
16
+ // Orchestrator (also re-exports shared types)
17
+ // ==========================================
18
+ export { AgentOrchestrator } from './orchestrator';
19
+ export type {
20
+ ExecutionResult,
21
+ ExecutionArtifact,
22
+ ExecutionLog,
23
+ VerificationResult,
24
+ VerificationCheck,
25
+ AgentEvent,
26
+ } from './orchestrator';
27
+
28
+ // ==========================================
29
+ // Executor
30
+ // ==========================================
31
+ export { Executor } from './executor';
32
+
33
+ // ==========================================
34
+ // Verifier
35
+ // ==========================================
36
+ export { Verifier } from './verifier';
37
+
38
+ // ==========================================
39
+ // Safety Manager
40
+ // ==========================================
41
+ export { SafetyManager } from './safety';
42
+ export type { SafetyCheck, SafetyCheckResult } from './safety';
43
+
44
+ // ==========================================
45
+ // Drift Detector
46
+ // ==========================================
47
+ export { DriftDetector } from './drift-detector';
48
+ export type {
49
+ DriftDetectionOptions,
50
+ DriftReport,
51
+ DriftSummary,
52
+ ResourceDrift,
53
+ DriftItem,
54
+ DriftType,
55
+ DriftSeverity,
56
+ DriftProvider,
57
+ } from './drift-detector';
58
+
59
+ // ==========================================
60
+ // Cost Estimator
61
+ // ==========================================
62
+ export { CostEstimator } from './cost-estimator';
63
+ export type {
64
+ CostEstimationInput,
65
+ CostEstimate,
66
+ ComponentCostBreakdown,
67
+ KnownComponent,
68
+ EnvironmentTier,
69
+ CloudProvider,
70
+ } from './cost-estimator';
71
+
72
+ // ==========================================
73
+ // Diagram Generator
74
+ // ==========================================
75
+ export { DiagramGenerator } from './diagram-generator';
76
+ export type { DiagramComponent, DiagramConnection, DiagramOptions } from './diagram-generator';
@@ -0,0 +1,636 @@
1
+ import { logger } from '../utils';
2
+ import { Planner, type AgentTask, type AgentPlan } from './planner';
3
+ import { Executor } from './executor';
4
+ import { Verifier } from './verifier';
5
+ import { SafetyManager } from './safety';
6
+
7
+ // ==========================================
8
+ // Re-export shared types for use by executor and other modules
9
+ // ==========================================
10
+
11
+ export type { AgentTask, AgentPlan, PlanStep, PlanDependency, Risk } from './planner';
12
+
13
+ export interface ExecutionResult {
14
+ id: string;
15
+ plan_id: string;
16
+ step_id: string;
17
+ status: 'success' | 'failure' | 'partial';
18
+ started_at: Date;
19
+ completed_at: Date;
20
+ duration: number;
21
+ outputs?: Record<string, unknown>;
22
+ artifacts?: ExecutionArtifact[];
23
+ logs?: ExecutionLog[];
24
+ error?: {
25
+ code: string;
26
+ message: string;
27
+ details?: Record<string, unknown>;
28
+ stack_trace?: string;
29
+ };
30
+ }
31
+
32
+ export interface ExecutionArtifact {
33
+ id: string;
34
+ type: 'terraform' | 'kubernetes' | 'script' | 'config' | 'documentation';
35
+ name: string;
36
+ path: string;
37
+ size: number;
38
+ checksum: string;
39
+ created_at: Date;
40
+ }
41
+
42
+ export interface ExecutionLog {
43
+ timestamp: Date;
44
+ level: 'debug' | 'info' | 'warn' | 'error';
45
+ message: string;
46
+ context?: Record<string, unknown>;
47
+ }
48
+
49
+ export interface VerificationResult {
50
+ id: string;
51
+ execution_id: string;
52
+ status: 'passed' | 'failed' | 'warning';
53
+ started_at: Date;
54
+ completed_at: Date;
55
+ checks: VerificationCheck[];
56
+ summary: {
57
+ total_checks: number;
58
+ passed: number;
59
+ failed: number;
60
+ warnings: number;
61
+ };
62
+ }
63
+
64
+ export interface VerificationCheck {
65
+ id: string;
66
+ type: 'security' | 'compliance' | 'functionality' | 'performance' | 'cost';
67
+ name: string;
68
+ description: string;
69
+ status: 'passed' | 'failed' | 'warning' | 'skipped';
70
+ expected?: unknown;
71
+ actual?: unknown;
72
+ error?: string;
73
+ remediation?: string;
74
+ }
75
+
76
+ export interface AgentEvent {
77
+ id: string;
78
+ task_id: string;
79
+ type:
80
+ | 'task_created'
81
+ | 'plan_generated'
82
+ | 'plan_approved'
83
+ | 'execution_started'
84
+ | 'step_completed'
85
+ | 'verification_completed'
86
+ | 'task_completed'
87
+ | 'task_failed'
88
+ | 'task_cancelled';
89
+ timestamp: Date;
90
+ data?: Record<string, unknown>;
91
+ user_id?: string;
92
+ }
93
+
94
+ // ==========================================
95
+ // Orchestrator
96
+ // ==========================================
97
+
98
+ export class AgentOrchestrator {
99
+ private planner: Planner;
100
+ private executor: Executor;
101
+ private verifier: Verifier;
102
+ private safetyManager: SafetyManager;
103
+
104
+ private tasks: Map<string, AgentTask>;
105
+ private plans: Map<string, AgentPlan>;
106
+ private events: AgentEvent[];
107
+
108
+ constructor() {
109
+ this.planner = new Planner();
110
+ this.executor = new Executor();
111
+ this.verifier = new Verifier();
112
+ this.safetyManager = new SafetyManager();
113
+
114
+ this.tasks = new Map();
115
+ this.plans = new Map();
116
+ this.events = [];
117
+
118
+ logger.info('Agent Orchestrator initialized');
119
+ }
120
+
121
+ /**
122
+ * Create a new task
123
+ */
124
+ async createTask(taskInput: {
125
+ type: 'generate' | 'deploy' | 'verify' | 'rollback' | 'analyze';
126
+ user_id: string;
127
+ priority?: 'low' | 'medium' | 'high' | 'critical';
128
+ context: {
129
+ provider: 'aws' | 'gcp' | 'azure';
130
+ environment: string;
131
+ region?: string;
132
+ components: string[];
133
+ requirements?: Record<string, unknown>;
134
+ };
135
+ metadata?: Record<string, unknown>;
136
+ }): Promise<AgentTask> {
137
+ const task: AgentTask = {
138
+ id: this.generateTaskId(),
139
+ type: taskInput.type,
140
+ status: 'pending',
141
+ priority: taskInput.priority || 'medium',
142
+ user_id: taskInput.user_id,
143
+ created_at: new Date(),
144
+ updated_at: new Date(),
145
+ context: taskInput.context,
146
+ execution: {},
147
+ metadata: taskInput.metadata,
148
+ };
149
+
150
+ this.tasks.set(task.id, task);
151
+ this.emitEvent({
152
+ id: this.generateEventId(),
153
+ task_id: task.id,
154
+ type: 'task_created',
155
+ timestamp: new Date(),
156
+ user_id: task.user_id,
157
+ data: { task },
158
+ });
159
+
160
+ logger.info(`Created task ${task.id}: ${task.type} for ${task.context.components.join(', ')}`);
161
+
162
+ return task;
163
+ }
164
+
165
+ /**
166
+ * Execute a task (full workflow)
167
+ */
168
+ async executeTask(taskId: string): Promise<{
169
+ task: AgentTask;
170
+ plan: AgentPlan;
171
+ executionResults: ExecutionResult[];
172
+ verificationResult: VerificationResult;
173
+ }> {
174
+ const task = this.tasks.get(taskId);
175
+ if (!task) {
176
+ throw new Error(`Task not found: ${taskId}`);
177
+ }
178
+
179
+ logger.info(`Starting task execution: ${taskId}`);
180
+
181
+ try {
182
+ // Step 1: Generate plan
183
+ task.status = 'planning';
184
+ task.updated_at = new Date();
185
+
186
+ const plan = await this.planner.generatePlan(task);
187
+ this.plans.set(plan.id, plan);
188
+ task.execution.plan_id = plan.id;
189
+
190
+ this.emitEvent({
191
+ id: this.generateEventId(),
192
+ task_id: task.id,
193
+ type: 'plan_generated',
194
+ timestamp: new Date(),
195
+ data: { plan_id: plan.id, steps: plan.steps.length },
196
+ });
197
+
198
+ logger.info(`Generated plan ${plan.id} with ${plan.steps.length} steps`);
199
+
200
+ // Step 2: Run pre-execution safety checks
201
+ const safetyChecks = await this.safetyManager.runPreExecutionChecks(task, plan);
202
+
203
+ if (!safetyChecks.passed) {
204
+ task.status = 'failed';
205
+ task.result = {
206
+ success: false,
207
+ errors: safetyChecks.blockers.map(b => b.message),
208
+ };
209
+ task.updated_at = new Date();
210
+
211
+ logger.error(`Safety checks failed for task ${taskId}`, safetyChecks.blockers);
212
+ throw new Error('Pre-execution safety checks failed');
213
+ }
214
+
215
+ // Step 3: Approve plan if required
216
+ if (plan.requires_approval && !plan.approved_by) {
217
+ task.status = 'pending';
218
+ task.updated_at = new Date();
219
+
220
+ logger.info(`Task ${taskId} requires approval before execution`);
221
+ // In production, this would notify user and wait for approval
222
+ // For now, auto-approve non-critical tasks
223
+ if (plan.risk_level !== 'critical') {
224
+ plan.approved_by = 'system';
225
+ plan.approved_at = new Date();
226
+ plan.status = 'approved';
227
+
228
+ this.emitEvent({
229
+ id: this.generateEventId(),
230
+ task_id: task.id,
231
+ type: 'plan_approved',
232
+ timestamp: new Date(),
233
+ data: { plan_id: plan.id, approved_by: 'system' },
234
+ });
235
+ } else {
236
+ throw new Error('Critical plan requires manual approval');
237
+ }
238
+ }
239
+
240
+ // Step 4: Execute plan
241
+ task.status = 'executing';
242
+ task.updated_at = new Date();
243
+
244
+ this.emitEvent({
245
+ id: this.generateEventId(),
246
+ task_id: task.id,
247
+ type: 'execution_started',
248
+ timestamp: new Date(),
249
+ data: { plan_id: plan.id },
250
+ });
251
+
252
+ logger.info(`Executing plan ${plan.id}`);
253
+
254
+ const executionResults = await this.executor.executePlan(plan);
255
+ task.execution.execution_id = executionResults[0]?.id;
256
+
257
+ // Check if execution succeeded
258
+ const executionFailed = executionResults.some(r => r.status === 'failure');
259
+
260
+ if (executionFailed) {
261
+ task.status = 'failed';
262
+ task.result = {
263
+ success: false,
264
+ errors: executionResults.filter(r => r.error).map(r => r.error!.message),
265
+ };
266
+ task.updated_at = new Date();
267
+
268
+ logger.error(`Execution failed for task ${taskId}`);
269
+ throw new Error('Execution failed');
270
+ }
271
+
272
+ // Emit step completed events
273
+ for (const result of executionResults) {
274
+ this.emitEvent({
275
+ id: this.generateEventId(),
276
+ task_id: task.id,
277
+ type: 'step_completed',
278
+ timestamp: new Date(),
279
+ data: {
280
+ step_id: result.step_id,
281
+ status: result.status,
282
+ duration: result.duration,
283
+ },
284
+ });
285
+ }
286
+
287
+ // Step 5: Verify execution
288
+ task.status = 'verifying';
289
+ task.updated_at = new Date();
290
+
291
+ logger.info(`Verifying execution results`);
292
+
293
+ const verificationResult = await this.verifier.verifyExecution(executionResults, {
294
+ ...task.context,
295
+ environment: task.context.environment,
296
+ });
297
+ task.execution.verification_id = verificationResult.id;
298
+
299
+ this.emitEvent({
300
+ id: this.generateEventId(),
301
+ task_id: task.id,
302
+ type: 'verification_completed',
303
+ timestamp: new Date(),
304
+ data: {
305
+ verification_id: verificationResult.id,
306
+ status: verificationResult.status,
307
+ checks_passed: verificationResult.summary.passed,
308
+ checks_failed: verificationResult.summary.failed,
309
+ },
310
+ });
311
+
312
+ // Step 6: Run post-execution safety checks
313
+ await this.safetyManager.runPostExecutionChecks({
314
+ task,
315
+ plan,
316
+ execution_results: executionResults,
317
+ verification_result: verificationResult,
318
+ });
319
+
320
+ // Step 7: Complete task
321
+ task.status = 'completed';
322
+ task.completed_at = new Date();
323
+ task.updated_at = new Date();
324
+ task.result = {
325
+ success: true,
326
+ outputs: executionResults.reduce((acc, r) => ({ ...acc, ...r.outputs }), {}),
327
+ artifacts: executionResults.flatMap(r => r.artifacts?.map(a => a.name) || []),
328
+ };
329
+
330
+ plan.status = 'completed';
331
+
332
+ this.emitEvent({
333
+ id: this.generateEventId(),
334
+ task_id: task.id,
335
+ type: 'task_completed',
336
+ timestamp: new Date(),
337
+ data: {
338
+ duration: task.completed_at.getTime() - task.created_at.getTime(),
339
+ verification_status: verificationResult.status,
340
+ },
341
+ });
342
+
343
+ logger.info(`Task ${taskId} completed successfully`);
344
+
345
+ return {
346
+ task,
347
+ plan,
348
+ executionResults,
349
+ verificationResult,
350
+ };
351
+ } catch (error) {
352
+ task.status = 'failed';
353
+ task.updated_at = new Date();
354
+ task.result = {
355
+ success: false,
356
+ errors: [(error as Error).message],
357
+ };
358
+
359
+ this.emitEvent({
360
+ id: this.generateEventId(),
361
+ task_id: task.id,
362
+ type: 'task_failed',
363
+ timestamp: new Date(),
364
+ data: {
365
+ error: (error as Error).message,
366
+ },
367
+ });
368
+
369
+ logger.error(`Task ${taskId} failed`, error);
370
+ throw error;
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Resume a task from its last checkpoint
376
+ */
377
+ async resumeTask(taskId: string): Promise<{
378
+ task: AgentTask;
379
+ executionResults: ExecutionResult[];
380
+ }> {
381
+ const task = this.tasks.get(taskId);
382
+ if (!task) {
383
+ throw new Error(`Task not found: ${taskId}`);
384
+ }
385
+
386
+ if (!task.execution.plan_id) {
387
+ throw new Error(`Task ${taskId} has no associated plan. Cannot resume.`);
388
+ }
389
+
390
+ const plan = this.plans.get(task.execution.plan_id);
391
+ if (!plan) {
392
+ throw new Error(`Plan ${task.execution.plan_id} not found. Cannot resume.`);
393
+ }
394
+
395
+ logger.info(`Resuming task ${taskId} with plan ${plan.id}`);
396
+
397
+ // Update task status
398
+ task.status = 'executing';
399
+ task.updated_at = new Date();
400
+
401
+ this.emitEvent({
402
+ id: this.generateEventId(),
403
+ task_id: task.id,
404
+ type: 'execution_started',
405
+ timestamp: new Date(),
406
+ data: { plan_id: plan.id, resumed: true },
407
+ });
408
+
409
+ // Re-execute the plan; the executor will pick up from the checkpoint
410
+ const executionResults = await this.executor.executePlan(plan);
411
+
412
+ // Check if execution succeeded
413
+ const executionFailed = executionResults.some(r => r.status === 'failure');
414
+
415
+ if (executionFailed) {
416
+ task.status = 'failed';
417
+ task.result = {
418
+ success: false,
419
+ errors: executionResults.filter(r => r.error).map(r => r.error!.message),
420
+ };
421
+ task.updated_at = new Date();
422
+
423
+ this.emitEvent({
424
+ id: this.generateEventId(),
425
+ task_id: task.id,
426
+ type: 'task_failed',
427
+ timestamp: new Date(),
428
+ data: { error: 'Resumed execution failed' },
429
+ });
430
+
431
+ throw new Error('Resumed execution failed');
432
+ }
433
+
434
+ // Mark task as completed
435
+ task.status = 'completed';
436
+ task.completed_at = new Date();
437
+ task.updated_at = new Date();
438
+ task.result = {
439
+ success: true,
440
+ outputs: executionResults.reduce((acc, r) => ({ ...acc, ...r.outputs }), {}),
441
+ artifacts: executionResults.flatMap(r => r.artifacts?.map(a => a.name) || []),
442
+ };
443
+
444
+ this.emitEvent({
445
+ id: this.generateEventId(),
446
+ task_id: task.id,
447
+ type: 'task_completed',
448
+ timestamp: new Date(),
449
+ data: {
450
+ duration: task.completed_at.getTime() - task.created_at.getTime(),
451
+ resumed: true,
452
+ },
453
+ });
454
+
455
+ logger.info(`Resumed task ${taskId} completed successfully`);
456
+
457
+ return {
458
+ task,
459
+ executionResults,
460
+ };
461
+ }
462
+
463
+ /**
464
+ * Get task by ID
465
+ */
466
+ getTask(taskId: string): AgentTask | undefined {
467
+ return this.tasks.get(taskId);
468
+ }
469
+
470
+ /**
471
+ * Get plan by ID
472
+ */
473
+ getPlan(planId: string): AgentPlan | undefined {
474
+ return this.plans.get(planId);
475
+ }
476
+
477
+ /**
478
+ * List all tasks
479
+ */
480
+ listTasks(filters?: {
481
+ user_id?: string;
482
+ status?: AgentTask['status'];
483
+ type?: AgentTask['type'];
484
+ }): AgentTask[] {
485
+ let tasks = Array.from(this.tasks.values());
486
+
487
+ if (filters?.user_id) {
488
+ tasks = tasks.filter(t => t.user_id === filters.user_id);
489
+ }
490
+
491
+ if (filters?.status) {
492
+ tasks = tasks.filter(t => t.status === filters.status);
493
+ }
494
+
495
+ if (filters?.type) {
496
+ tasks = tasks.filter(t => t.type === filters.type);
497
+ }
498
+
499
+ return tasks.sort((a, b) => b.created_at.getTime() - a.created_at.getTime());
500
+ }
501
+
502
+ /**
503
+ * Cancel a task
504
+ */
505
+ async cancelTask(taskId: string): Promise<void> {
506
+ const task = this.tasks.get(taskId);
507
+ if (!task) {
508
+ throw new Error(`Task not found: ${taskId}`);
509
+ }
510
+
511
+ if (task.status === 'completed' || task.status === 'failed') {
512
+ throw new Error(`Cannot cancel task in ${task.status} status`);
513
+ }
514
+
515
+ task.status = 'cancelled';
516
+ task.updated_at = new Date();
517
+
518
+ this.emitEvent({
519
+ id: this.generateEventId(),
520
+ task_id: task.id,
521
+ type: 'task_cancelled',
522
+ timestamp: new Date(),
523
+ });
524
+
525
+ logger.info(`Task ${taskId} cancelled`);
526
+ }
527
+
528
+ /**
529
+ * Get task events
530
+ */
531
+ getTaskEvents(taskId: string): AgentEvent[] {
532
+ return this.events.filter(e => e.task_id === taskId);
533
+ }
534
+
535
+ /**
536
+ * Get all events
537
+ */
538
+ getAllEvents(): AgentEvent[] {
539
+ return [...this.events].sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
540
+ }
541
+
542
+ /**
543
+ * Get task statistics
544
+ */
545
+ getStatistics(): {
546
+ total_tasks: number;
547
+ by_status: Record<string, number>;
548
+ by_type: Record<string, number>;
549
+ average_duration: number;
550
+ success_rate: number;
551
+ } {
552
+ const tasks = Array.from(this.tasks.values());
553
+
554
+ const byStatus: Record<string, number> = {};
555
+ const byType: Record<string, number> = {};
556
+ let totalDuration = 0;
557
+ let completedTasks = 0;
558
+ let successfulTasks = 0;
559
+
560
+ for (const task of tasks) {
561
+ byStatus[task.status] = (byStatus[task.status] || 0) + 1;
562
+ byType[task.type] = (byType[task.type] || 0) + 1;
563
+
564
+ if (task.completed_at) {
565
+ completedTasks++;
566
+ totalDuration += task.completed_at.getTime() - task.created_at.getTime();
567
+
568
+ if (task.result?.success) {
569
+ successfulTasks++;
570
+ }
571
+ }
572
+ }
573
+
574
+ return {
575
+ total_tasks: tasks.length,
576
+ by_status: byStatus,
577
+ by_type: byType,
578
+ average_duration: completedTasks > 0 ? totalDuration / completedTasks : 0,
579
+ success_rate: completedTasks > 0 ? (successfulTasks / completedTasks) * 100 : 0,
580
+ };
581
+ }
582
+
583
+ /**
584
+ * Emit event
585
+ */
586
+ private emitEvent(event: AgentEvent): void {
587
+ this.events.push(event);
588
+
589
+ // Keep only last 1000 events
590
+ if (this.events.length > 1000) {
591
+ this.events = this.events.slice(-1000);
592
+ }
593
+ }
594
+
595
+ /**
596
+ * Generate task ID
597
+ */
598
+ private generateTaskId(): string {
599
+ return `task_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
600
+ }
601
+
602
+ /**
603
+ * Generate event ID
604
+ */
605
+ private generateEventId(): string {
606
+ return `event_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
607
+ }
608
+
609
+ /**
610
+ * Get planner instance (for direct access)
611
+ */
612
+ getPlanner(): Planner {
613
+ return this.planner;
614
+ }
615
+
616
+ /**
617
+ * Get executor instance (for direct access)
618
+ */
619
+ getExecutor(): Executor {
620
+ return this.executor;
621
+ }
622
+
623
+ /**
624
+ * Get verifier instance (for direct access)
625
+ */
626
+ getVerifier(): Verifier {
627
+ return this.verifier;
628
+ }
629
+
630
+ /**
631
+ * Get safety manager instance (for direct access)
632
+ */
633
+ getSafetyManager(): SafetyManager {
634
+ return this.safetyManager;
635
+ }
636
+ }