@jterrats/open-orchestra 0.1.0 → 0.3.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 (208) hide show
  1. package/AGENTS.md +90 -0
  2. package/CHANGELOG.md +104 -0
  3. package/CLAUDE.md +103 -0
  4. package/README.md +173 -22
  5. package/dist/assets/web-console.js +743 -0
  6. package/dist/autonomous-workflow.d.ts +45 -0
  7. package/dist/autonomous-workflow.js +386 -0
  8. package/dist/autonomous-workflow.js.map +1 -0
  9. package/dist/benchmark.d.ts +8 -0
  10. package/dist/benchmark.js +193 -0
  11. package/dist/benchmark.js.map +1 -0
  12. package/dist/burndown.d.ts +3 -0
  13. package/dist/burndown.js +141 -0
  14. package/dist/burndown.js.map +1 -0
  15. package/dist/clarification.d.ts +6 -0
  16. package/dist/clarification.js +88 -0
  17. package/dist/clarification.js.map +1 -0
  18. package/dist/cli.js +221 -4
  19. package/dist/cli.js.map +1 -1
  20. package/dist/collaboration-flows.d.ts +5 -0
  21. package/dist/collaboration-flows.js +256 -0
  22. package/dist/collaboration-flows.js.map +1 -0
  23. package/dist/command-manifest.d.ts +11 -0
  24. package/dist/command-manifest.js +52 -0
  25. package/dist/command-manifest.js.map +1 -0
  26. package/dist/commands.d.ts +39 -0
  27. package/dist/commands.js +1069 -2
  28. package/dist/commands.js.map +1 -1
  29. package/dist/constants.d.ts +4 -0
  30. package/dist/constants.js +22 -0
  31. package/dist/constants.js.map +1 -1
  32. package/dist/defaults.d.ts +7 -11
  33. package/dist/defaults.js +7 -625
  34. package/dist/defaults.js.map +1 -1
  35. package/dist/delegation-decision.d.ts +14 -0
  36. package/dist/delegation-decision.js +391 -0
  37. package/dist/delegation-decision.js.map +1 -0
  38. package/dist/detect-commands.d.ts +3 -0
  39. package/dist/detect-commands.js +28 -0
  40. package/dist/detect-commands.js.map +1 -0
  41. package/dist/diagram-validation.d.ts +36 -0
  42. package/dist/diagram-validation.js +118 -0
  43. package/dist/diagram-validation.js.map +1 -0
  44. package/dist/fs-utils.d.ts +2 -0
  45. package/dist/fs-utils.js +75 -6
  46. package/dist/fs-utils.js.map +1 -1
  47. package/dist/github.d.ts +11 -0
  48. package/dist/github.js +48 -0
  49. package/dist/github.js.map +1 -0
  50. package/dist/health-checks.d.ts +28 -0
  51. package/dist/health-checks.js +219 -0
  52. package/dist/health-checks.js.map +1 -0
  53. package/dist/health-commands.d.ts +2 -0
  54. package/dist/health-commands.js +18 -0
  55. package/dist/health-commands.js.map +1 -0
  56. package/dist/instruction-apply.d.ts +34 -0
  57. package/dist/instruction-apply.js +150 -0
  58. package/dist/instruction-apply.js.map +1 -0
  59. package/dist/instruction-blocks.d.ts +22 -0
  60. package/dist/instruction-blocks.js +120 -0
  61. package/dist/instruction-blocks.js.map +1 -0
  62. package/dist/instruction-imports.d.ts +12 -0
  63. package/dist/instruction-imports.js +45 -0
  64. package/dist/instruction-imports.js.map +1 -0
  65. package/dist/instruction-stale.d.ts +9 -0
  66. package/dist/instruction-stale.js +106 -0
  67. package/dist/instruction-stale.js.map +1 -0
  68. package/dist/instruction-types.d.ts +66 -0
  69. package/dist/instruction-types.js +2 -0
  70. package/dist/instruction-types.js.map +1 -0
  71. package/dist/instruction-updates.d.ts +4 -0
  72. package/dist/instruction-updates.js +5 -0
  73. package/dist/instruction-updates.js.map +1 -0
  74. package/dist/knowledge-base.d.ts +10 -0
  75. package/dist/knowledge-base.js +117 -0
  76. package/dist/knowledge-base.js.map +1 -0
  77. package/dist/mcp-oauth-proxy.d.ts +39 -0
  78. package/dist/mcp-oauth-proxy.js +80 -0
  79. package/dist/mcp-oauth-proxy.js.map +1 -0
  80. package/dist/pr-review.d.ts +20 -0
  81. package/dist/pr-review.js +142 -0
  82. package/dist/pr-review.js.map +1 -0
  83. package/dist/project-detection.d.ts +22 -0
  84. package/dist/project-detection.js +174 -0
  85. package/dist/project-detection.js.map +1 -0
  86. package/dist/prompt-registry.d.ts +56 -0
  87. package/dist/prompt-registry.js +163 -0
  88. package/dist/prompt-registry.js.map +1 -0
  89. package/dist/release-candidate.d.ts +41 -0
  90. package/dist/release-candidate.js +196 -0
  91. package/dist/release-candidate.js.map +1 -0
  92. package/dist/release-commands.d.ts +4 -0
  93. package/dist/release-commands.js +50 -0
  94. package/dist/release-commands.js.map +1 -0
  95. package/dist/roles/ai-support-roles.d.ts +11 -0
  96. package/dist/roles/ai-support-roles.js +67 -0
  97. package/dist/roles/ai-support-roles.js.map +1 -0
  98. package/dist/roles/core-roles.d.ts +11 -0
  99. package/dist/roles/core-roles.js +144 -0
  100. package/dist/roles/core-roles.js.map +1 -0
  101. package/dist/roles/engineering-roles.d.ts +11 -0
  102. package/dist/roles/engineering-roles.js +176 -0
  103. package/dist/roles/engineering-roles.js.map +1 -0
  104. package/dist/roles/governance-roles.d.ts +11 -0
  105. package/dist/roles/governance-roles.js +117 -0
  106. package/dist/roles/governance-roles.js.map +1 -0
  107. package/dist/roles/index.d.ts +11 -0
  108. package/dist/roles/index.js +17 -0
  109. package/dist/roles/index.js.map +1 -0
  110. package/dist/roles/platform-ops-roles.d.ts +11 -0
  111. package/dist/roles/platform-ops-roles.js +158 -0
  112. package/dist/roles/platform-ops-roles.js.map +1 -0
  113. package/dist/roles/qa-ux-roles.d.ts +11 -0
  114. package/dist/roles/qa-ux-roles.js +193 -0
  115. package/dist/roles/qa-ux-roles.js.map +1 -0
  116. package/dist/roles/release-ops-roles.d.ts +11 -0
  117. package/dist/roles/release-ops-roles.js +109 -0
  118. package/dist/roles/release-ops-roles.js.map +1 -0
  119. package/dist/runtime-adapters.d.ts +6 -0
  120. package/dist/runtime-adapters.js +88 -0
  121. package/dist/runtime-adapters.js.map +1 -0
  122. package/dist/runtime-bootstrap.d.ts +12 -0
  123. package/dist/runtime-bootstrap.js +136 -0
  124. package/dist/runtime-bootstrap.js.map +1 -0
  125. package/dist/skills.d.ts +36 -0
  126. package/dist/skills.js +665 -0
  127. package/dist/skills.js.map +1 -0
  128. package/dist/subagent-protocol.d.ts +41 -0
  129. package/dist/subagent-protocol.js +179 -0
  130. package/dist/subagent-protocol.js.map +1 -0
  131. package/dist/telemetry-consent.d.ts +24 -0
  132. package/dist/telemetry-consent.js +95 -0
  133. package/dist/telemetry-consent.js.map +1 -0
  134. package/dist/telemetry-export.d.ts +14 -0
  135. package/dist/telemetry-export.js +126 -0
  136. package/dist/telemetry-export.js.map +1 -0
  137. package/dist/telemetry-records.d.ts +3 -0
  138. package/dist/telemetry-records.js +96 -0
  139. package/dist/telemetry-records.js.map +1 -0
  140. package/dist/telemetry-redaction.d.ts +9 -0
  141. package/dist/telemetry-redaction.js +55 -0
  142. package/dist/telemetry-redaction.js.map +1 -0
  143. package/dist/telemetry-types.d.ts +52 -0
  144. package/dist/telemetry-types.js +2 -0
  145. package/dist/telemetry-types.js.map +1 -0
  146. package/dist/telemetry.d.ts +4 -0
  147. package/dist/telemetry.js +4 -0
  148. package/dist/telemetry.js.map +1 -0
  149. package/dist/types.d.ts +304 -1
  150. package/dist/types.js +1 -1
  151. package/dist/types.js.map +1 -1
  152. package/dist/validation.d.ts +3 -1
  153. package/dist/validation.js +28 -5
  154. package/dist/validation.js.map +1 -1
  155. package/dist/web-api.js +167 -3
  156. package/dist/web-api.js.map +1 -1
  157. package/dist/web-console.js +6 -160
  158. package/dist/web-console.js.map +1 -1
  159. package/dist/workflow-gates.js +4 -2
  160. package/dist/workflow-gates.js.map +1 -1
  161. package/dist/workflow-services.js +143 -67
  162. package/dist/workflow-services.js.map +1 -1
  163. package/dist/workflow-templates.d.ts +10 -0
  164. package/dist/workflow-templates.js +141 -0
  165. package/dist/workflow-templates.js.map +1 -0
  166. package/dist/workspace-classification.d.ts +5 -0
  167. package/dist/workspace-classification.js +127 -0
  168. package/dist/workspace-classification.js.map +1 -0
  169. package/dist/workspace-validator.js +11 -1
  170. package/dist/workspace-validator.js.map +1 -1
  171. package/dist/workspace.d.ts +8 -4
  172. package/dist/workspace.js +111 -4
  173. package/dist/workspace.js.map +1 -1
  174. package/docs/autonomous-workflow.md +165 -0
  175. package/docs/benchmark.md +219 -0
  176. package/docs/dev-team-specialist-role-profiles.md +171 -0
  177. package/docs/mcp-oauth-proxy-evaluation.md +44 -0
  178. package/docs/multi-agent-orchestrator-backlog.md +413 -1
  179. package/docs/open-orchestra-dogfooding-findings.md +66 -0
  180. package/docs/orchestra-mvp.md +161 -3
  181. package/docs/runtime-adapters.md +86 -0
  182. package/docs/runtime-llm-flow.md +124 -0
  183. package/docs/setup-agents-dogfooding-findings.md +101 -0
  184. package/docs/skill-loading-strategy.md +114 -0
  185. package/docs/source-of-truth-and-agent-learning.md +83 -0
  186. package/package.json +9 -5
  187. package/rules/agent-roles.mdc +30 -0
  188. package/rules/ai-assisted-development.mdc +22 -0
  189. package/skills/agent-learning/SKILL.md +24 -0
  190. package/skills/agent-learning/manifest.json +40 -0
  191. package/skills/backlog-sync/SKILL.md +24 -0
  192. package/skills/backlog-sync/manifest.json +41 -0
  193. package/skills/diagram-export/SKILL.md +35 -0
  194. package/skills/diagram-export/manifest.json +40 -0
  195. package/skills/model-evaluation/SKILL.md +25 -0
  196. package/skills/model-evaluation/manifest.json +41 -0
  197. package/skills/playwright-evidence/SKILL.md +28 -0
  198. package/skills/playwright-evidence/manifest.json +46 -0
  199. package/skills/pr-review/SKILL.md +23 -0
  200. package/skills/pr-review/manifest.json +43 -0
  201. package/skills/prompt-registry/SKILL.md +24 -0
  202. package/skills/prompt-registry/manifest.json +45 -0
  203. package/skills/release-readiness/SKILL.md +25 -0
  204. package/skills/release-readiness/manifest.json +45 -0
  205. package/skills/source-of-truth/SKILL.md +24 -0
  206. package/skills/source-of-truth/manifest.json +47 -0
  207. package/skills/static-analysis/SKILL.md +26 -0
  208. package/skills/static-analysis/manifest.json +46 -0
package/dist/skills.js ADDED
@@ -0,0 +1,665 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { FILES } from "./constants.js";
6
+ import { exists, readJson, resolveWorkflowPath, writeJson, } from "./fs-utils.js";
7
+ import { appendEvent, loadWorkspace, writeArtifact } from "./workspace.js";
8
+ const PACKAGE_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
9
+ const defaultSkills = [
10
+ {
11
+ id: "prompt-registry",
12
+ name: "Prompt Registry",
13
+ summary: "Read and update .generated-prompts registers for substantial AI-generated artifacts.",
14
+ triggers: [
15
+ "prompt",
16
+ "generated",
17
+ "artifact",
18
+ "code",
19
+ "ui",
20
+ "docs",
21
+ "diagram",
22
+ "eval",
23
+ ],
24
+ roles: [
25
+ "parent",
26
+ "developer",
27
+ "tech_lead",
28
+ "frontend_specialist",
29
+ "backend_specialist",
30
+ "mobile_specialist",
31
+ "sdet",
32
+ "qa",
33
+ "technical_writer",
34
+ "ai_evaluation_engineer",
35
+ ],
36
+ capabilities: [
37
+ "prompt-memory",
38
+ "artifact-traceability",
39
+ "context-continuity",
40
+ ],
41
+ riskAreas: ["maintainability", "governance"],
42
+ sourceGroups: ["agent-memory", "codebase"],
43
+ entry: "skills/prompt-registry/SKILL.md",
44
+ assets: [],
45
+ evidence: ["file"],
46
+ loadBudget: "small",
47
+ instructions: [
48
+ "Before substantial generation, read the relevant .generated-prompts register.",
49
+ "After substantial changes, update one entry with task, role, decisions, evidence, and prompt summary.",
50
+ "Do not update the register for typo-only, formatting-only, or single-line mechanical fixes.",
51
+ ],
52
+ },
53
+ {
54
+ id: "diagram-export",
55
+ name: "Diagram Export",
56
+ summary: "Create, validate, and export architecture, workflow, and sequence diagrams.",
57
+ triggers: [
58
+ "diagram",
59
+ "mermaid",
60
+ "architecture",
61
+ "flow",
62
+ "sequence",
63
+ "draw.io",
64
+ "lucid",
65
+ ],
66
+ roles: [
67
+ "architect",
68
+ "business_analyst",
69
+ "product_manager",
70
+ "tech_lead",
71
+ "technical_writer",
72
+ ],
73
+ capabilities: ["diagramming", "architecture-communication"],
74
+ riskAreas: ["architecture", "documentation"],
75
+ sourceGroups: ["architecture", "product-backlog", "agent-memory"],
76
+ entry: "skills/diagram-export/SKILL.md",
77
+ assets: [],
78
+ evidence: ["file", "report"],
79
+ loadBudget: "normal",
80
+ instructions: [
81
+ "Identify the diagram purpose and authoritative architecture sources before drawing.",
82
+ "Choose the diagram style from the decision matrix before drafting.",
83
+ "Prefer text-native diagrams such as Mermaid unless the project requires another format.",
84
+ "Run orchestra diagrams lint --file <diagram.mmd> before sharing Mermaid diagrams.",
85
+ "Attach lint evidence to the workflow when the diagram supports delivery.",
86
+ ],
87
+ },
88
+ {
89
+ id: "static-analysis",
90
+ name: "Static Analysis",
91
+ summary: "Run and interpret local quality, type, dependency, secret, and security checks.",
92
+ triggers: [
93
+ "lint",
94
+ "typecheck",
95
+ "secret",
96
+ "sast",
97
+ "precommit",
98
+ "dependency",
99
+ "scan",
100
+ "eslint",
101
+ "test",
102
+ ],
103
+ roles: [
104
+ "developer",
105
+ "tech_lead",
106
+ "qa",
107
+ "sdet",
108
+ "security",
109
+ "devops",
110
+ "platform_engineer",
111
+ ],
112
+ capabilities: ["quality-gate", "security-review", "commit-readiness"],
113
+ riskAreas: ["security", "release", "maintainability"],
114
+ sourceGroups: ["codebase", "quality-security", "agent-memory"],
115
+ entry: "skills/static-analysis/SKILL.md",
116
+ assets: ["skills/static-analysis/checklist.md"],
117
+ evidence: ["command", "report"],
118
+ loadBudget: "normal",
119
+ instructions: [
120
+ "Inspect configured local checks before inventing commands.",
121
+ "Run the smallest relevant check first, then the full gate before handoff or commit.",
122
+ "Record command evidence and treat failed required checks as blockers unless explicitly deferred.",
123
+ ],
124
+ },
125
+ {
126
+ id: "pr-review",
127
+ name: "PR Review",
128
+ summary: "Produce review findings, PR summaries, risks, rollout notes, and missing-test gaps.",
129
+ triggers: [
130
+ "pr",
131
+ "pull request",
132
+ "review",
133
+ "diff",
134
+ "merge",
135
+ "release summary",
136
+ ],
137
+ roles: [
138
+ "reviewer_critic",
139
+ "tech_lead",
140
+ "qa",
141
+ "security",
142
+ "release_manager",
143
+ "architect",
144
+ ],
145
+ capabilities: ["review", "risk-summary", "change-summary"],
146
+ riskAreas: ["release", "security", "maintainability"],
147
+ sourceGroups: [
148
+ "codebase",
149
+ "quality-security",
150
+ "product-backlog",
151
+ "agent-memory",
152
+ ],
153
+ entry: "skills/pr-review/SKILL.md",
154
+ assets: [],
155
+ evidence: ["file", "report"],
156
+ loadBudget: "normal",
157
+ instructions: [
158
+ "Review behavior, tests, risks, rollout, rollback, and missing evidence before summaries.",
159
+ "Lead with findings and blockers, then summarize changes.",
160
+ "Reference local files, task context, reviews, and evidence rather than generated claims.",
161
+ ],
162
+ },
163
+ {
164
+ id: "playwright-evidence",
165
+ name: "Playwright Evidence",
166
+ summary: "Plan browser automation and attach screenshots, traces, videos, and reports.",
167
+ triggers: [
168
+ "playwright",
169
+ "browser",
170
+ "e2e",
171
+ "screenshot",
172
+ "trace",
173
+ "video",
174
+ "responsive",
175
+ "web",
176
+ "ui",
177
+ ],
178
+ roles: [
179
+ "qa",
180
+ "sdet",
181
+ "frontend_specialist",
182
+ "ux_ui_designer",
183
+ "ux_researcher_accessibility",
184
+ ],
185
+ capabilities: ["e2e-testing", "browser-evidence", "accessibility-check"],
186
+ riskAreas: ["ux", "release"],
187
+ sourceGroups: [
188
+ "quality-security",
189
+ "codebase",
190
+ "product-backlog",
191
+ "agent-memory",
192
+ ],
193
+ entry: "skills/playwright-evidence/SKILL.md",
194
+ assets: [],
195
+ evidence: ["screenshot", "trace", "video", "report"],
196
+ loadBudget: "normal",
197
+ instructions: [
198
+ "Plan user-value scenarios from acceptance criteria before writing tests.",
199
+ "Use resilient locators and page objects for repeated flows.",
200
+ "Attach screenshots, traces, videos, or reports as evidence for release decisions.",
201
+ ],
202
+ },
203
+ {
204
+ id: "backlog-sync",
205
+ name: "Backlog Sync",
206
+ summary: "Keep GitHub issues, local stories, and workflow tasks aligned.",
207
+ triggers: [
208
+ "backlog",
209
+ "issue",
210
+ "story",
211
+ "epic",
212
+ "github",
213
+ "acceptance criteria",
214
+ "refine",
215
+ ],
216
+ roles: [
217
+ "product_manager",
218
+ "product_owner",
219
+ "business_analyst",
220
+ "planner",
221
+ "parent",
222
+ ],
223
+ capabilities: ["backlog-management", "story-refinement", "scope-control"],
224
+ riskAreas: ["governance", "scope"],
225
+ sourceGroups: ["product-backlog", "project-instructions", "agent-memory"],
226
+ entry: "skills/backlog-sync/SKILL.md",
227
+ assets: [],
228
+ evidence: ["file", "report"],
229
+ loadBudget: "small",
230
+ instructions: [
231
+ "Confirm backlog IDs and acceptance criteria before implementation.",
232
+ "Keep local tasks, docs, and GitHub issues aligned when one changes.",
233
+ "Surface missing refinement as a blocker instead of guessing scope.",
234
+ ],
235
+ },
236
+ {
237
+ id: "release-readiness",
238
+ name: "Release Readiness",
239
+ summary: "Validate gates, rollback, observability, support, and customer-impact evidence.",
240
+ triggers: [
241
+ "release",
242
+ "deploy",
243
+ "rollback",
244
+ "go-live",
245
+ "readiness",
246
+ "downtime",
247
+ "observability",
248
+ ],
249
+ roles: [
250
+ "release_manager",
251
+ "devops",
252
+ "sre",
253
+ "platform_engineer",
254
+ "support_customer_ops",
255
+ "security",
256
+ ],
257
+ capabilities: ["release-gate", "rollback-review", "operational-readiness"],
258
+ riskAreas: ["release", "sre", "devops", "security"],
259
+ sourceGroups: ["devops-runtime", "quality-security", "agent-memory"],
260
+ entry: "skills/release-readiness/SKILL.md",
261
+ assets: [],
262
+ evidence: ["command", "report", "file"],
263
+ loadBudget: "normal",
264
+ instructions: [
265
+ "Validate gates, evidence, locks, reviews, rollback, observability, and support readiness.",
266
+ "Treat missing rollback or unresolved critical QA/security/SRE findings as blockers.",
267
+ "Record release evidence and accepted residual risks explicitly.",
268
+ ],
269
+ },
270
+ {
271
+ id: "model-evaluation",
272
+ name: "Model Evaluation",
273
+ summary: "Run prompt, model, provider-routing, fallback, and rubric evaluations.",
274
+ triggers: [
275
+ "model",
276
+ "llm",
277
+ "prompt",
278
+ "provider",
279
+ "fallback",
280
+ "eval",
281
+ "rubric",
282
+ "routing",
283
+ ],
284
+ roles: ["ai_evaluation_engineer", "toolsmith", "architect", "parent"],
285
+ capabilities: ["llm-evaluation", "provider-routing", "prompt-quality"],
286
+ riskAreas: ["governance", "quality"],
287
+ sourceGroups: ["vendor-docs", "agent-memory", "quality-security"],
288
+ entry: "skills/model-evaluation/SKILL.md",
289
+ assets: [],
290
+ evidence: ["report", "file"],
291
+ loadBudget: "normal",
292
+ instructions: [
293
+ "Define eval objectives, cases, rubric, and expected behavior before changing prompts or routing.",
294
+ "Compare model/provider behavior for material changes and record disagreements.",
295
+ "Avoid storing raw sensitive prompts or responses in provenance artifacts.",
296
+ ],
297
+ },
298
+ {
299
+ id: "source-of-truth",
300
+ name: "Source of Truth",
301
+ summary: "Select authoritative project, vendor, and workflow sources before acting.",
302
+ triggers: [
303
+ "source",
304
+ "documentation",
305
+ "docs",
306
+ "official",
307
+ "verify",
308
+ "truth",
309
+ "context",
310
+ ],
311
+ roles: [
312
+ "parent",
313
+ "planner",
314
+ "context_curator",
315
+ "architect",
316
+ "developer",
317
+ "qa",
318
+ "security",
319
+ "devops",
320
+ ],
321
+ capabilities: ["context-selection", "provenance", "source-resolution"],
322
+ riskAreas: ["governance", "accuracy"],
323
+ sourceGroups: [
324
+ "project-instructions",
325
+ "product-backlog",
326
+ "architecture",
327
+ "codebase",
328
+ "vendor-docs",
329
+ "agent-memory",
330
+ ],
331
+ entry: "skills/source-of-truth/SKILL.md",
332
+ assets: [],
333
+ evidence: ["file", "report"],
334
+ loadBudget: "small",
335
+ instructions: [
336
+ "Select source groups before acting and load only sources relevant to the task.",
337
+ "Prefer local project sources first and official vendor docs for current APIs or tools.",
338
+ "If sources conflict, record the conflict as a blocker or decision.",
339
+ ],
340
+ },
341
+ {
342
+ id: "agent-learning",
343
+ name: "Agent Learning",
344
+ summary: "Record reusable failure lessons and promote repeated lessons into skills or rules.",
345
+ triggers: [
346
+ "failure",
347
+ "failed",
348
+ "error",
349
+ "syntax",
350
+ "escaping",
351
+ "permission",
352
+ "lesson",
353
+ "learn",
354
+ ],
355
+ roles: ["parent", "context_curator", "toolsmith", "developer", "qa"],
356
+ capabilities: ["failure-learning", "memory-hygiene", "repeat-prevention"],
357
+ riskAreas: ["maintainability", "governance"],
358
+ sourceGroups: ["agent-memory", "codebase"],
359
+ entry: "skills/agent-learning/SKILL.md",
360
+ assets: [],
361
+ evidence: ["file"],
362
+ loadBudget: "small",
363
+ instructions: [
364
+ "Search relevant lessons before repeating risky operations.",
365
+ "After reusable failures, record operation, error signature, root cause, fix, prevention, and verification.",
366
+ "Promote repeated lessons into versioned skills or rules after review.",
367
+ ],
368
+ },
369
+ ];
370
+ export function listSkills() {
371
+ return defaultSkills.map((skill) => ({
372
+ ...skill,
373
+ instructions: [...skill.instructions],
374
+ }));
375
+ }
376
+ export async function planSkillsForTask(taskId, root = process.cwd()) {
377
+ const workspace = await loadWorkspace(root);
378
+ const task = workspace.tasks.find((candidate) => candidate.id === taskId);
379
+ if (!task) {
380
+ throw new Error(`unknown task: ${taskId}`);
381
+ }
382
+ const role = workspace.roles.find((candidate) => candidate.id === task.ownerRole);
383
+ const scored = listSkills().map((skill) => scoreSkill(skill, task, role?.capabilities ?? []));
384
+ const selected = scored
385
+ .filter((item) => item.score > 0 || item.skill.id === "source-of-truth")
386
+ .sort((left, right) => right.score - left.score || left.skill.id.localeCompare(right.skill.id));
387
+ const skipped = scored
388
+ .filter((item) => !selected.some((selectedItem) => selectedItem.skill.id === item.skill.id))
389
+ .map(({ skill }) => ({
390
+ skill,
391
+ score: 0,
392
+ rationale: ["No matching task signal, role, capability, or risk area."],
393
+ }));
394
+ return {
395
+ taskId,
396
+ selected: selected.map(toPlanItem),
397
+ skipped: skipped.map(toPlanItem),
398
+ sourceGroups: unique(selected.flatMap((item) => item.skill.sourceGroups)),
399
+ };
400
+ }
401
+ export async function renderSkills({ target, taskId, skillIds, root = process.cwd(), }) {
402
+ const skills = await resolveRenderSkills({ taskId, skillIds, root });
403
+ const sourceGroups = unique(skills.flatMap((skill) => skill.sourceGroups));
404
+ return {
405
+ target,
406
+ taskId,
407
+ skills,
408
+ sourceGroups,
409
+ content: renderForTarget(target, skills, sourceGroups, taskId),
410
+ };
411
+ }
412
+ async function resolveRenderSkills({ taskId, skillIds, root, }) {
413
+ if (skillIds && skillIds.length > 0) {
414
+ const catalog = listSkills();
415
+ return skillIds.map((id) => {
416
+ const skill = catalog.find((candidate) => candidate.id === id);
417
+ if (!skill) {
418
+ throw new Error(`unknown skill: ${id}`);
419
+ }
420
+ return skill;
421
+ });
422
+ }
423
+ if (!taskId) {
424
+ throw new Error("missing --task or --skills");
425
+ }
426
+ const plan = await planSkillsForTask(taskId, root);
427
+ return plan.selected.map((item) => item.skill);
428
+ }
429
+ function scoreSkill(skill, task, roleCapabilities) {
430
+ const text = taskText(task);
431
+ const rationale = [];
432
+ let score = 0;
433
+ if (skill.roles.includes(task.ownerRole)) {
434
+ score += 3;
435
+ rationale.push(`owner role matches ${task.ownerRole}`);
436
+ }
437
+ const matchedTriggers = skill.triggers.filter((trigger) => text.includes(trigger.toLowerCase()));
438
+ if (matchedTriggers.length > 0) {
439
+ score += matchedTriggers.length * 2;
440
+ rationale.push(`task text matches triggers: ${matchedTriggers.join(", ")}`);
441
+ }
442
+ const risks = [
443
+ ...(task.risks ?? []),
444
+ ...(task.riskGate?.impactAreas ?? []),
445
+ ].map((risk) => risk.toLowerCase());
446
+ const matchedRisks = skill.riskAreas.filter((risk) => risks.some((taskRisk) => taskRisk.includes(risk)));
447
+ if (matchedRisks.length > 0) {
448
+ score += matchedRisks.length * 2;
449
+ rationale.push(`risk areas match: ${matchedRisks.join(", ")}`);
450
+ }
451
+ const matchedCapabilities = skill.capabilities.filter((capability) => roleCapabilities.includes(capability));
452
+ if (matchedCapabilities.length > 0) {
453
+ score += matchedCapabilities.length;
454
+ rationale.push(`role capabilities match: ${matchedCapabilities.join(", ")}`);
455
+ }
456
+ if (skill.id === "prompt-registry" && (task.paths?.length ?? 0) > 0) {
457
+ score += 1;
458
+ rationale.push("task touches files, so prompt registry can preserve artifact intent");
459
+ }
460
+ if (skill.id === "source-of-truth" && score === 0) {
461
+ rationale.push("baseline source selection should run for every task");
462
+ }
463
+ return { skill, score, rationale };
464
+ }
465
+ function toPlanItem({ skill, score, rationale, }) {
466
+ return { skill, score, rationale };
467
+ }
468
+ function taskText(task) {
469
+ return [
470
+ task.id,
471
+ task.title,
472
+ task.backlogItem,
473
+ task.goal,
474
+ task.scope,
475
+ task.testStrategy,
476
+ ...(task.acceptanceCriteria ?? []),
477
+ ...(task.assumptions ?? []),
478
+ ...(task.risks ?? []),
479
+ ...(task.paths ?? []),
480
+ ]
481
+ .filter(Boolean)
482
+ .join(" ")
483
+ .toLowerCase();
484
+ }
485
+ function renderForTarget(target, skills, sourceGroups, taskId) {
486
+ if (target === "cursor") {
487
+ return renderMarkdown(skills, sourceGroups, taskId, "Cursor Skill Context", "Use these Open Orchestra skills as task-scoped Cursor rules.");
488
+ }
489
+ if (target === "windsurf") {
490
+ return renderMarkdown(skills, sourceGroups, taskId, "Windsurf Skill Context", "Use these Open Orchestra skills as task-scoped Windsurf rules.");
491
+ }
492
+ if (target === "claude") {
493
+ return renderMarkdown(skills, sourceGroups, taskId, "Claude Skill Context", "Load only these Open Orchestra skills for this task.");
494
+ }
495
+ if (target === "codex") {
496
+ return renderMarkdown(skills, sourceGroups, taskId, "Codex Skill Context", "Apply these Open Orchestra skills while preserving AGENTS.md instructions.");
497
+ }
498
+ if (target === "vscode") {
499
+ return JSON.stringify({ taskId, sourceGroups, skills }, null, 2);
500
+ }
501
+ return renderMarkdown(skills, sourceGroups, taskId, "Open Orchestra Skill Context", "Provider-agnostic skill context for this task.");
502
+ }
503
+ function renderMarkdown(skills, sourceGroups, taskId, title, intro) {
504
+ const lines = [
505
+ `# ${title}`,
506
+ "",
507
+ intro,
508
+ "",
509
+ `Task: ${taskId ?? "explicit skill selection"}`,
510
+ "",
511
+ "## Source Groups",
512
+ "",
513
+ ...sourceGroups.map((group) => `- ${group}`),
514
+ "",
515
+ ];
516
+ for (const skill of skills) {
517
+ lines.push(`## ${skill.name}`, "", `ID: ${skill.id}`, "", skill.summary, "", "### Load From", "", `- ${skill.entry}`, "", "### Procedure", "", ...skill.instructions.map((instruction) => `- ${instruction}`), "", "### Evidence", "", ...skill.evidence.map((evidence) => `- ${evidence}`), "");
518
+ }
519
+ return lines.join("\n");
520
+ }
521
+ export async function readAgentLessons(root = process.cwd()) {
522
+ const lessonsPath = resolveWorkflowPath(root, FILES.agentLessons);
523
+ if (!(await exists(lessonsPath))) {
524
+ return [];
525
+ }
526
+ return (await readFile(lessonsPath, "utf8"))
527
+ .split("\n")
528
+ .filter((line) => line.trim() !== "");
529
+ }
530
+ export async function readSourceOfTruth(root = process.cwd()) {
531
+ return readJson(path.join(root, ".agent-workflow", FILES.sourceOfTruth), []);
532
+ }
533
+ export async function validateSkills(root = PACKAGE_ROOT) {
534
+ const errors = [];
535
+ const warnings = [];
536
+ const ids = new Set();
537
+ for (const skill of listSkills()) {
538
+ if (ids.has(skill.id)) {
539
+ errors.push(`duplicate skill id: ${skill.id}`);
540
+ }
541
+ ids.add(skill.id);
542
+ if (!(await exists(path.join(root, skill.entry)))) {
543
+ errors.push(`missing skill entry: ${skill.entry}`);
544
+ }
545
+ const manifestPath = path.join(root, "skills", skill.id, "manifest.json");
546
+ if (!(await exists(manifestPath))) {
547
+ errors.push(`missing skill manifest: skills/${skill.id}/manifest.json`);
548
+ continue;
549
+ }
550
+ const manifest = await readJson(manifestPath, {});
551
+ if (manifest.id !== skill.id) {
552
+ errors.push(`manifest id mismatch for ${skill.id}`);
553
+ }
554
+ for (const required of [
555
+ "name",
556
+ "summary",
557
+ "triggers",
558
+ "roles",
559
+ "capabilities",
560
+ "sourceGroups",
561
+ "entry",
562
+ "evidence",
563
+ "loadBudget",
564
+ ]) {
565
+ if (!(required in manifest)) {
566
+ errors.push(`manifest ${skill.id} missing ${required}`);
567
+ }
568
+ }
569
+ if (skill.instructions.length === 0) {
570
+ warnings.push(`skill ${skill.id} has no instructions`);
571
+ }
572
+ }
573
+ return { valid: errors.length === 0, errors, warnings };
574
+ }
575
+ export async function recordSkillPlan(plan, root = process.cwd()) {
576
+ if (!(await hasInitializedWorkflowState(root))) {
577
+ return;
578
+ }
579
+ await appendEvent(root, {
580
+ type: "SKILLS_PLANNED",
581
+ taskId: plan.taskId,
582
+ actor: "parent",
583
+ summary: `Selected ${plan.selected.length} skills for ${plan.taskId}`,
584
+ metadata: {
585
+ selectedSkillIds: plan.selected.map((item) => item.skill.id),
586
+ sourceGroups: plan.sourceGroups,
587
+ rationale: Object.fromEntries(plan.selected.map((item) => [item.skill.id, item.rationale])),
588
+ },
589
+ });
590
+ }
591
+ export async function recordSkillRender(rendered, root = process.cwd()) {
592
+ if (!(await hasInitializedWorkflowState(root))) {
593
+ return;
594
+ }
595
+ await appendEvent(root, removeUndefined({
596
+ type: "SKILLS_RENDERED",
597
+ taskId: rendered.taskId,
598
+ actor: "parent",
599
+ summary: `Rendered ${rendered.skills.length} skills for ${rendered.target}`,
600
+ metadata: {
601
+ target: rendered.target,
602
+ selectedSkillIds: rendered.skills.map((skill) => skill.id),
603
+ sourceGroups: rendered.sourceGroups,
604
+ },
605
+ }));
606
+ }
607
+ async function hasInitializedWorkflowState(root) {
608
+ return exists(resolveWorkflowPath(root, FILES.config));
609
+ }
610
+ export async function addAgentLesson(input, root = process.cwd()) {
611
+ const lesson = { timestamp: new Date().toISOString(), ...input };
612
+ await writeFile(resolveWorkflowPath(root, FILES.agentLessons), `${JSON.stringify(lesson)}\n`, { flag: "a" });
613
+ await appendEvent(root, removeUndefined({
614
+ type: "LESSON_RECORDED",
615
+ taskId: lesson.taskId,
616
+ actor: lesson.actor,
617
+ summary: `Recorded lesson: ${lesson.errorSignature}`,
618
+ metadata: { operation: lesson.operation, appliesTo: lesson.appliesTo },
619
+ }));
620
+ return lesson;
621
+ }
622
+ export async function listAgentLessons(root = process.cwd()) {
623
+ const lines = await readAgentLessons(root);
624
+ return lines.map((line) => JSON.parse(line));
625
+ }
626
+ export async function promoteAgentLessons({ to, filter, root = process.cwd(), }) {
627
+ const lessons = (await listAgentLessons(root)).filter((lesson) => {
628
+ if (!filter) {
629
+ return true;
630
+ }
631
+ const text = JSON.stringify(lesson).toLowerCase();
632
+ return text.includes(filter.toLowerCase());
633
+ });
634
+ const content = [
635
+ `# Promoted Agent Lessons (${to})`,
636
+ "",
637
+ ...lessons.flatMap((lesson) => [
638
+ `## ${lesson.operation}`,
639
+ `- Error: ${lesson.errorSignature}`,
640
+ `- Root cause: ${lesson.rootCause}`,
641
+ `- Fix: ${lesson.fix}`,
642
+ `- Prevention: ${lesson.prevention}`,
643
+ "",
644
+ ]),
645
+ ].join("\n");
646
+ const artifact = await writeArtifact(root, "decisions", `promoted-lessons-${to}.md`, content);
647
+ await appendEvent(root, {
648
+ type: "LESSON_PROMOTED",
649
+ actor: "parent",
650
+ summary: `Promoted ${lessons.length} lessons to ${to}`,
651
+ artifacts: [artifact],
652
+ metadata: { to, filter, lessonCount: lessons.length },
653
+ });
654
+ return { artifact, lessons };
655
+ }
656
+ export async function writeSourceOfTruth(entries, root = process.cwd()) {
657
+ await writeJson(path.join(root, ".agent-workflow", FILES.sourceOfTruth), entries);
658
+ }
659
+ function removeUndefined(value) {
660
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
661
+ }
662
+ function unique(values) {
663
+ return [...new Set(values)].sort();
664
+ }
665
+ //# sourceMappingURL=skills.js.map