duoops 0.1.7 → 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 (64) hide show
  1. package/README.md +151 -63
  2. package/data/aws_machine_power_profiles.json +54 -0
  3. package/data/cpu_physical_specs.json +105 -0
  4. package/data/cpu_power_profiles.json +275 -0
  5. package/data/gcp_machine_power_profiles.json +1802 -0
  6. package/data/runtime-pue-mappings.json +183 -0
  7. package/dist/commands/ask.d.ts +3 -0
  8. package/dist/commands/ask.js +9 -3
  9. package/dist/commands/autofix-ci.d.ts +13 -0
  10. package/dist/commands/autofix-ci.js +114 -0
  11. package/dist/commands/autofix.d.ts +5 -0
  12. package/dist/commands/autofix.js +11 -0
  13. package/dist/commands/config.d.ts +10 -0
  14. package/dist/commands/config.js +47 -0
  15. package/dist/commands/init.js +50 -27
  16. package/dist/commands/mcp/deploy.d.ts +13 -0
  17. package/dist/commands/mcp/deploy.js +139 -0
  18. package/dist/commands/measure/calculate.js +2 -2
  19. package/dist/commands/portal.js +428 -11
  20. package/dist/lib/ai/agent.d.ts +6 -2
  21. package/dist/lib/ai/agent.js +51 -57
  22. package/dist/lib/ai/tools/editing.js +28 -13
  23. package/dist/lib/ai/tools/gitlab.d.ts +4 -0
  24. package/dist/lib/ai/tools/gitlab.js +166 -11
  25. package/dist/lib/ai/tools/measure.js +7 -3
  26. package/dist/lib/ai/tools/types.d.ts +3 -0
  27. package/dist/lib/ai/tools/types.js +1 -0
  28. package/dist/lib/config.d.ts +10 -0
  29. package/dist/lib/gcloud.d.ts +7 -0
  30. package/dist/lib/gcloud.js +105 -0
  31. package/dist/lib/gitlab/pipelines-service.d.ts +23 -0
  32. package/dist/lib/gitlab/pipelines-service.js +146 -0
  33. package/dist/lib/gitlab/runner-service.d.ts +11 -0
  34. package/dist/lib/gitlab/runner-service.js +15 -0
  35. package/dist/lib/portal/settings.d.ts +3 -0
  36. package/dist/lib/portal/settings.js +48 -0
  37. package/dist/lib/scaffold.d.ts +5 -0
  38. package/dist/lib/scaffold.js +32 -0
  39. package/dist/portal/assets/HomeDashboard-DlkwSyKx.js +1 -0
  40. package/dist/portal/assets/JobDetailsDrawer-7kXXMSH8.js +1 -0
  41. package/dist/portal/assets/JobsDashboard-D4pNc9TM.js +1 -0
  42. package/dist/portal/assets/MetricsDashboard-BcgzvzBz.js +1 -0
  43. package/dist/portal/assets/PipelinesDashboard-BNrSM9GB.js +1 -0
  44. package/dist/portal/assets/allPaths-CXDKahbk.js +1 -0
  45. package/dist/portal/assets/allPathsLoader-BF5PAx2c.js +2 -0
  46. package/dist/portal/assets/cache-YerT0Slh.js +6 -0
  47. package/dist/portal/assets/core-Cz8f3oSB.js +19 -0
  48. package/dist/portal/assets/{index-B6bzT1Vv.js → index-B9sNUqEC.js} +1 -1
  49. package/dist/portal/assets/index-BWa_E8Y7.css +1 -0
  50. package/dist/portal/assets/index-Bp4RqK05.js +1 -0
  51. package/dist/portal/assets/index-DW6Qp0d6.js +64 -0
  52. package/dist/portal/assets/index-Uc4Xhv31.js +1 -0
  53. package/dist/portal/assets/progressBar-C4SmnGeZ.js +1 -0
  54. package/dist/portal/assets/splitPathsBySizeLoader-C-T9_API.js +1 -0
  55. package/dist/portal/index.html +2 -2
  56. package/oclif.manifest.json +282 -93
  57. package/package.json +2 -1
  58. package/templates/.gitlab/duo/flows/duoops.yaml +114 -0
  59. package/templates/agents/agent.yml +45 -0
  60. package/templates/duoops-autofix-component.yml +52 -0
  61. package/templates/flows/flow.yml +283 -0
  62. package/dist/portal/assets/MetricsDashboard-DIsoz4Sl.js +0 -71
  63. package/dist/portal/assets/index-BP8FwWqA.css +0 -1
  64. package/dist/portal/assets/index-DkVG3jel.js +0 -70
@@ -0,0 +1,283 @@
1
+ name: "DuoOps Pipeline Doctor"
2
+ description: "Multi-stage CI/CD pipeline healing: fetches failures, diagnoses root cause, applies a fix commit, validates the CI config, and reports sustainability insights — all posted back to the merge request."
3
+ public: true
4
+ definition:
5
+ version: v1
6
+ environment: ambient
7
+
8
+ components:
9
+ - name: "fetch_failures"
10
+ type: DeterministicStepComponent
11
+ inputs:
12
+ - from: "context:goal"
13
+ as: "merge_request_url"
14
+ tool_name: "get_pipeline_errors"
15
+ ui_log_events:
16
+ - on_tool_execution_success
17
+ - on_tool_execution_failed
18
+
19
+ - name: "diagnose"
20
+ type: AgentComponent
21
+ prompt_id: "duoops_diagnose_prompt"
22
+ inputs:
23
+ - "context:goal"
24
+ - from: "context:fetch_failures.tool_responses"
25
+ as: "pipeline_errors"
26
+ toolset:
27
+ - get_job_logs
28
+ - get_pipeline_errors
29
+ - get_pipeline_failing_jobs
30
+ - get_merge_request
31
+ - list_merge_request_diffs
32
+ - get_repository_file
33
+ - read_file
34
+ - read_files
35
+ - find_files
36
+ - grep
37
+ - list_dir
38
+ - get_commit_diff
39
+ ui_log_events:
40
+ - on_agent_final_answer
41
+ - on_tool_execution_success
42
+
43
+ - name: "validate_ci_config"
44
+ type: OneOffComponent
45
+ prompt_id: "duoops_validate_prompt"
46
+ inputs:
47
+ - "context:goal"
48
+ - from: "context:diagnose.agent_output"
49
+ as: "diagnosis"
50
+ toolset:
51
+ - ci_linter
52
+ - get_repository_file
53
+ max_correction_attempts: 3
54
+ ui_log_events:
55
+ - on_tool_execution_success
56
+ - on_tool_call_input
57
+
58
+ - name: "apply_fix"
59
+ type: AgentComponent
60
+ prompt_id: "duoops_apply_fix_prompt"
61
+ inputs:
62
+ - "context:goal"
63
+ - from: "context:diagnose.agent_output"
64
+ as: "diagnosis"
65
+ - from: "context:validate_ci_config.tool_responses"
66
+ as: "ci_lint_result"
67
+ toolset:
68
+ - read_file
69
+ - read_files
70
+ - get_repository_file
71
+ - find_files
72
+ - grep
73
+ - edit_file
74
+ - create_file_with_contents
75
+ - create_commit
76
+ - ci_linter
77
+ ui_log_events:
78
+ - on_agent_final_answer
79
+ - on_tool_execution_success
80
+
81
+ - name: "report_and_sustainability"
82
+ type: AgentComponent
83
+ prompt_id: "duoops_report_prompt"
84
+ inputs:
85
+ - "context:goal"
86
+ - from: "context:diagnose.agent_output"
87
+ as: "diagnosis"
88
+ - from: "context:validate_ci_config.tool_responses"
89
+ as: "ci_lint_result"
90
+ - from: "context:apply_fix.agent_output"
91
+ as: "fix_result"
92
+ toolset:
93
+ - get_merge_request
94
+ - get_job_logs
95
+ - get_pipeline_failing_jobs
96
+ - list_merge_request_diffs
97
+ - create_merge_request_note
98
+ ui_log_events:
99
+ - on_agent_final_answer
100
+ - on_tool_execution_success
101
+
102
+ prompts:
103
+ - prompt_id: "duoops_diagnose_prompt"
104
+ name: "DuoOps Diagnosis Agent"
105
+ unit_primitives: []
106
+ prompt_template:
107
+ system: |
108
+ You are DuoOps, an expert CI/CD diagnostician for GitLab pipelines.
109
+
110
+ A pipeline has failed. You receive the initial error summary from a prior deterministic step. Your task is to perform a deep root-cause analysis:
111
+
112
+ 1. Fetch full logs for EVERY failed job using get_job_logs.
113
+ 2. Read the .gitlab-ci.yml and any included CI config files.
114
+ 3. Read the source files referenced in error messages.
115
+ 4. Check the MR diff to see what changed and whether the change caused the failure.
116
+ 5. Identify the root cause with high confidence.
117
+
118
+ Your output MUST be a structured diagnosis in this exact format:
119
+
120
+ ROOT_CAUSE: <one-line summary>
121
+ FAILED_JOBS: <comma-separated job names>
122
+ CATEGORY: <one of: code_error | ci_config | dependency | infrastructure | test_failure | permissions>
123
+ FIXABLE: <yes | no | partial>
124
+ FILES_TO_FIX: <comma-separated file paths, or "none">
125
+ DETAILS: <2-5 sentences explaining the failure and the fix strategy>
126
+
127
+ Be precise. Reference exact job names, line numbers, and error messages.
128
+ Do NOT post anything to the merge request — a later step handles reporting.
129
+ user: |
130
+ {{goal}}
131
+
132
+ Pipeline error context from deterministic fetch:
133
+ {{pipeline_errors}}
134
+ placeholder: history
135
+ params:
136
+ timeout: 120
137
+
138
+ - prompt_id: "duoops_validate_prompt"
139
+ name: "DuoOps CI Validator"
140
+ unit_primitives: []
141
+ prompt_template:
142
+ system: |
143
+ You are a CI configuration validator. You have access to the ci_linter tool and the repository file reader.
144
+
145
+ Your task:
146
+ 1. Fetch the .gitlab-ci.yml from the repository using get_repository_file with the path ".gitlab-ci.yml".
147
+ 2. Run ci_linter on the content to check for syntax errors.
148
+ 3. If the diagnosis mentions CI config issues, this validation is critical.
149
+
150
+ Return the linter result as-is. Do not embellish or add commentary.
151
+ user: |
152
+ {{goal}}
153
+
154
+ Diagnosis from prior step:
155
+ {{diagnosis}}
156
+ placeholder: history
157
+ params:
158
+ timeout: 60
159
+
160
+ - prompt_id: "duoops_apply_fix_prompt"
161
+ name: "DuoOps Fix Agent"
162
+ unit_primitives: []
163
+ prompt_template:
164
+ system: |
165
+ You are DuoOps, a CI/CD fix agent. You receive a diagnosis and CI lint results from prior steps.
166
+
167
+ Your task is to apply a fix commit to the current MR branch:
168
+
169
+ 1. Review the diagnosis to understand what files need changing.
170
+ 2. Read the current content of each file that needs modification.
171
+ 3. Use edit_file to make the necessary changes. Be surgical — change only what is needed.
172
+ 4. If the diagnosis says FIXABLE is "no", do NOT attempt a fix. Output "NO_FIX_APPLIED: <reason>" and stop.
173
+ 5. If the CI linter flagged errors in .gitlab-ci.yml, fix those too.
174
+ 6. Once all edits are made, use create_commit to commit the changes with a clear message prefixed with "fix(ci): ".
175
+ 7. If you create a commit, run ci_linter one more time on the updated .gitlab-ci.yml to confirm validity.
176
+
177
+ Output your result in this format:
178
+ FIX_STATUS: <applied | skipped | partial>
179
+ COMMIT_SHA: <sha if applied, "none" if skipped>
180
+ FILES_CHANGED: <comma-separated list>
181
+ SUMMARY: <one sentence describing the fix>
182
+
183
+ Be conservative. Only fix what you are confident about. Do not introduce new issues.
184
+ user: |
185
+ {{goal}}
186
+
187
+ Diagnosis:
188
+ {{diagnosis}}
189
+
190
+ CI Lint Result:
191
+ {{ci_lint_result}}
192
+ placeholder: history
193
+ params:
194
+ timeout: 180
195
+
196
+ - prompt_id: "duoops_report_prompt"
197
+ name: "DuoOps Reporter"
198
+ unit_primitives: []
199
+ prompt_template:
200
+ system: |
201
+ You are DuoOps, the final reporting agent. You compile the results from all prior steps into a single, clear merge request note.
202
+
203
+ You receive:
204
+ - The root-cause diagnosis
205
+ - The CI lint validation result
206
+ - The fix application result (commit SHA or skip reason)
207
+
208
+ Your task:
209
+ 1. Compose a merge request note using create_merge_request_note with ALL the information below.
210
+ 2. Analyze the failing jobs for sustainability concerns: redundant steps, missing caches, oversized images, parallelizable stages, unnecessary artifact uploads, jobs that could use `rules:changes` to skip when irrelevant files change.
211
+
212
+ Structure the MR note EXACTLY as follows:
213
+
214
+ ## 🔍 Root Cause Analysis
215
+ <What failed and why. Reference job names and error messages.>
216
+
217
+ ## 🔧 Applied Fix
218
+ <If a fix commit was created, mention the SHA and what was changed.>
219
+ <If no fix was applied, explain why and provide manual remediation steps.>
220
+
221
+ ## ✅ CI Config Validation
222
+ <Lint status of .gitlab-ci.yml — valid or errors found.>
223
+
224
+ ## 🌱 Sustainability Insights
225
+ <Concrete recommendations to reduce CI carbon footprint:>
226
+ - Cache optimization opportunities
227
+ - Image size reduction
228
+ - Job deduplication / rules:changes gating
229
+ - Stage parallelization
230
+ - Runner sizing recommendations
231
+
232
+ ## 📋 Next Steps
233
+ <What the developer should do: push again, review the fix commit, or apply manual changes.>
234
+
235
+ ---
236
+ *Generated by [DuoOps](https://gitlab.com/youneslaaroussi/duoops) — Explainable & Sustainable CI*
237
+
238
+ Keep the note concise but actionable. Every recommendation must be specific to this project.
239
+ user: |
240
+ {{goal}}
241
+
242
+ Diagnosis:
243
+ {{diagnosis}}
244
+
245
+ CI Lint Result:
246
+ {{ci_lint_result}}
247
+
248
+ Fix Result:
249
+ {{fix_result}}
250
+ placeholder: history
251
+ params:
252
+ timeout: 120
253
+
254
+ routers:
255
+ - from: "fetch_failures"
256
+ condition:
257
+ input: "context:fetch_failures.execution_result"
258
+ routes:
259
+ "success": "diagnose"
260
+ "failed": "diagnose"
261
+
262
+ - from: "diagnose"
263
+ condition:
264
+ input: "context:diagnose.agent_output"
265
+ routes:
266
+ "FIXABLE: no": "report_and_sustainability"
267
+ "default": "validate_ci_config"
268
+
269
+ - from: "validate_ci_config"
270
+ condition:
271
+ input: "context:validate_ci_config.execution_result"
272
+ routes:
273
+ "success": "apply_fix"
274
+ "failed": "apply_fix"
275
+
276
+ - from: "apply_fix"
277
+ to: "report_and_sustainability"
278
+
279
+ - from: "report_and_sustainability"
280
+ to: "end"
281
+
282
+ flow:
283
+ entry_point: "fetch_failures"