@jterrats/open-orchestra 0.4.2-beta.2 → 0.5.0-beta.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 (148) hide show
  1. package/README.md +29 -5
  2. package/dist/advisory-artifacts.d.ts +6 -0
  3. package/dist/advisory-artifacts.js +37 -1
  4. package/dist/advisory-artifacts.js.map +1 -1
  5. package/dist/assets/web-console.js +297 -4
  6. package/dist/cli.js +13 -118
  7. package/dist/cli.js.map +1 -1
  8. package/dist/command-manifest.d.ts +3 -0
  9. package/dist/command-manifest.js +132 -42
  10. package/dist/command-manifest.js.map +1 -1
  11. package/dist/command-utils.d.ts +5 -0
  12. package/dist/command-utils.js +23 -0
  13. package/dist/command-utils.js.map +1 -1
  14. package/dist/commands.d.ts +6 -42
  15. package/dist/commands.js +204 -1372
  16. package/dist/commands.js.map +1 -1
  17. package/dist/constants.js +1 -0
  18. package/dist/constants.js.map +1 -1
  19. package/dist/delivery-commands.d.ts +10 -0
  20. package/dist/delivery-commands.js +152 -0
  21. package/dist/delivery-commands.js.map +1 -0
  22. package/dist/github.d.ts +50 -1
  23. package/dist/github.js +234 -0
  24. package/dist/github.js.map +1 -1
  25. package/dist/health-checks.d.ts +1 -0
  26. package/dist/health-checks.js +11 -1
  27. package/dist/health-checks.js.map +1 -1
  28. package/dist/health-commands.js +2 -0
  29. package/dist/health-commands.js.map +1 -1
  30. package/dist/memory.d.ts +2 -1
  31. package/dist/memory.js +71 -10
  32. package/dist/memory.js.map +1 -1
  33. package/dist/package-update-check.d.ts +5 -1
  34. package/dist/package-update-check.js +20 -8
  35. package/dist/package-update-check.js.map +1 -1
  36. package/dist/planning-commands.d.ts +14 -0
  37. package/dist/planning-commands.js +372 -0
  38. package/dist/planning-commands.js.map +1 -0
  39. package/dist/release-candidate.d.ts +2 -0
  40. package/dist/release-candidate.js +9 -14
  41. package/dist/release-candidate.js.map +1 -1
  42. package/dist/release-commands.d.ts +2 -0
  43. package/dist/release-commands.js +58 -6
  44. package/dist/release-commands.js.map +1 -1
  45. package/dist/release-readiness.d.ts +49 -0
  46. package/dist/release-readiness.js +172 -0
  47. package/dist/release-readiness.js.map +1 -0
  48. package/dist/runtime-commands.js +2 -5
  49. package/dist/runtime-commands.js.map +1 -1
  50. package/dist/setup-agents-import.js +1 -3
  51. package/dist/setup-agents-import.js.map +1 -1
  52. package/dist/skills-catalog-service.d.ts +2 -0
  53. package/dist/skills-catalog-service.js +8 -0
  54. package/dist/skills-catalog-service.js.map +1 -0
  55. package/dist/skills-catalog.d.ts +2 -0
  56. package/dist/skills-catalog.js +389 -0
  57. package/dist/skills-catalog.js.map +1 -0
  58. package/dist/skills-commands.js +1 -11
  59. package/dist/skills-commands.js.map +1 -1
  60. package/dist/skills-events.d.ts +9 -0
  61. package/dist/skills-events.js +50 -0
  62. package/dist/skills-events.js.map +1 -0
  63. package/dist/skills-memory.d.ts +18 -0
  64. package/dist/skills-memory.js +127 -0
  65. package/dist/skills-memory.js.map +1 -0
  66. package/dist/skills-planning.d.ts +2 -0
  67. package/dist/skills-planning.js +87 -0
  68. package/dist/skills-planning.js.map +1 -0
  69. package/dist/skills-render.d.ts +14 -0
  70. package/dist/skills-render.js +83 -0
  71. package/dist/skills-render.js.map +1 -0
  72. package/dist/skills-validation.d.ts +2 -0
  73. package/dist/skills-validation.js +49 -0
  74. package/dist/skills-validation.js.map +1 -0
  75. package/dist/skills.d.ts +6 -42
  76. package/dist/skills.js +6 -773
  77. package/dist/skills.js.map +1 -1
  78. package/dist/task-graph-commands.d.ts +14 -0
  79. package/dist/task-graph-commands.js +367 -0
  80. package/dist/task-graph-commands.js.map +1 -0
  81. package/dist/types/context.d.ts +12 -0
  82. package/dist/types/context.js +2 -0
  83. package/dist/types/context.js.map +1 -0
  84. package/dist/types/metrics.d.ts +114 -0
  85. package/dist/types/metrics.js +2 -0
  86. package/dist/types/metrics.js.map +1 -0
  87. package/dist/types/model-config.d.ts +212 -0
  88. package/dist/types/model-config.js +2 -0
  89. package/dist/types/model-config.js.map +1 -0
  90. package/dist/types/runtime.d.ts +93 -0
  91. package/dist/types/runtime.js +2 -0
  92. package/dist/types/runtime.js.map +1 -0
  93. package/dist/types/skills.d.ts +147 -0
  94. package/dist/types/skills.js +2 -0
  95. package/dist/types/skills.js.map +1 -0
  96. package/dist/types/tasks.d.ts +171 -0
  97. package/dist/types/tasks.js +2 -0
  98. package/dist/types/tasks.js.map +1 -0
  99. package/dist/types/workflow-run.d.ts +79 -0
  100. package/dist/types/workflow-run.js +2 -0
  101. package/dist/types/workflow-run.js.map +1 -0
  102. package/dist/types.d.ts +12 -833
  103. package/dist/types.js +1 -1
  104. package/dist/types.js.map +1 -1
  105. package/dist/upgrade-commands.d.ts +2 -0
  106. package/dist/upgrade-commands.js +65 -0
  107. package/dist/upgrade-commands.js.map +1 -0
  108. package/dist/web-api-read-routes.d.ts +5 -0
  109. package/dist/web-api-read-routes.js +37 -0
  110. package/dist/web-api-read-routes.js.map +1 -0
  111. package/dist/web-api.d.ts +1 -3
  112. package/dist/web-api.js +23 -45
  113. package/dist/web-api.js.map +1 -1
  114. package/dist/web-console-sections.d.ts +2 -0
  115. package/dist/web-console-sections.js +7 -0
  116. package/dist/web-console-sections.js.map +1 -0
  117. package/dist/web-console.js +23 -3
  118. package/dist/web-console.js.map +1 -1
  119. package/dist/workflow-approval-service.d.ts +9 -0
  120. package/dist/workflow-approval-service.js +126 -0
  121. package/dist/workflow-approval-service.js.map +1 -0
  122. package/dist/workflow-approval-utils.d.ts +10 -0
  123. package/dist/workflow-approval-utils.js +82 -0
  124. package/dist/workflow-approval-utils.js.map +1 -0
  125. package/dist/workflow-budget-utils.d.ts +7 -0
  126. package/dist/workflow-budget-utils.js +96 -0
  127. package/dist/workflow-budget-utils.js.map +1 -0
  128. package/dist/workflow-evidence-service.d.ts +7 -0
  129. package/dist/workflow-evidence-service.js +100 -0
  130. package/dist/workflow-evidence-service.js.map +1 -0
  131. package/dist/workflow-run-commands.d.ts +8 -0
  132. package/dist/workflow-run-commands.js +479 -0
  133. package/dist/workflow-run-commands.js.map +1 -0
  134. package/dist/workflow-services.d.ts +5 -17
  135. package/dist/workflow-services.js +26 -479
  136. package/dist/workflow-services.js.map +1 -1
  137. package/dist/workflow-summary-service.d.ts +4 -0
  138. package/dist/workflow-summary-service.js +82 -0
  139. package/dist/workflow-summary-service.js.map +1 -0
  140. package/dist/workspace.d.ts +18 -1
  141. package/dist/workspace.js +66 -4
  142. package/dist/workspace.js.map +1 -1
  143. package/docs/orchestra-mvp.md +158 -114
  144. package/docs/package-naming.md +20 -0
  145. package/docs/persona-workflows.md +209 -0
  146. package/docs/runtime-adapters.md +15 -14
  147. package/docs/runtime-llm-flow.md +29 -28
  148. package/package.json +3 -2
package/README.md CHANGED
@@ -4,19 +4,43 @@ Open Orchestra is a local-first, provider-agnostic framework for governed multi-
4
4
 
5
5
  It coordinates agents through task graphs, durable workflow files, handoffs, reviews, evidence, gates, locks, model routing, model provenance, budget controls, and an autonomous multi-phase workflow engine. The public CLI is `orchestra`.
6
6
 
7
+ Package naming: install `@jterrats/open-orchestra`; run the CLI as
8
+ `orchestra`. The shorter `@jterrats/orchestra` package is not the canonical
9
+ published install target.
10
+
7
11
  ## Quick Start
8
12
 
9
13
  ```bash
10
- npm install
11
- npm run build
12
- node bin/orchestra.js init
13
- node bin/orchestra.js status
14
- node bin/orchestra.js roles list --json
14
+ npm install -g @jterrats/open-orchestra
15
+ orchestra init
16
+ orchestra status
17
+ orchestra roles list --json
15
18
  ```
16
19
 
20
+ When developing Open Orchestra from this repository, use `npm install`,
21
+ `npm run build`, and `node bin/orchestra.js ...` to exercise the local source.
22
+
17
23
  For Claude, Codex, Cursor, VS Code, Windsurf, and generic LLM usage, see
18
24
  [docs/runtime-llm-flow.md](docs/runtime-llm-flow.md) and
19
25
  [docs/runtime-adapters.md](docs/runtime-adapters.md).
26
+ To start by job-to-be-done, use the
27
+ [persona workflows guide](docs/persona-workflows.md) for PO refinement,
28
+ developer execution, QA validation, tech lead oversight, and release
29
+ management.
30
+ For package naming rules, see [docs/package-naming.md](docs/package-naming.md).
31
+
32
+ ## Supported Platforms
33
+
34
+ Open Orchestra supports current Node.js LTS/runtime releases on macOS, Linux,
35
+ and Windows. Repository scripts avoid Unix-only shell requirements for the
36
+ core quality and workflow gates; `npm run validate:workflow` runs through a
37
+ Node helper so it works in Windows shells as well as POSIX shells. The CI
38
+ dogfood path validates installed-package init and workflow validation on
39
+ `ubuntu-latest`, `macos-latest`, and `windows-latest`.
40
+
41
+ Known limitations: publish/release automation may still use GitHub-hosted
42
+ Linux shell steps, but local development, validation, and installed CLI
43
+ dogfooding are expected to be cross-platform.
20
44
 
21
45
  ## Autonomous Workflow
22
46
 
@@ -5,7 +5,13 @@ export interface AdvisoryArtifactsResult {
5
5
  id: string;
6
6
  title: string;
7
7
  ownerRole: string;
8
+ goal: string;
9
+ scope: string;
8
10
  acceptanceCriteria: string[];
11
+ assumptions: string[];
12
+ risks: string[];
13
+ paths: string[];
14
+ testStrategy: string;
9
15
  };
10
16
  }
11
17
  export declare function writeAdvisoryArtifacts({ root, classification, }: {
@@ -8,6 +8,7 @@ export async function writeAdvisoryArtifacts({ root, classification, }) {
8
8
  await writeArtifact(root, ADVISORY_DIRECTORY, "README.md", renderAdvisoryReadme(classification)),
9
9
  await writeArtifact(root, ADVISORY_DIRECTORY, "role-guides.md", renderRoleGuides(defaultRoles)),
10
10
  await writeArtifact(root, ADVISORY_DIRECTORY, "decisions.md", renderPortableDecisions()),
11
+ await writeArtifact(root, ADVISORY_DIRECTORY, "conversion.md", renderConversionGuide()),
11
12
  await writeArtifact(root, ADVISORY_DIRECTORY, "project-task.json", `${JSON.stringify(projectTask, null, 2)}\n`),
12
13
  ];
13
14
  return { files, projectTask };
@@ -17,12 +18,18 @@ function advisoryProjectTask() {
17
18
  id: "ADVISORY-CONVERSION",
18
19
  title: "Convert advisory findings into a project task",
19
20
  ownerRole: "product_owner",
21
+ goal: "Convert advisory findings into a project delivery task",
22
+ scope: "Advisory findings, decisions, role guides, and conversion path",
20
23
  acceptanceCriteria: [
21
24
  "Target project is confirmed",
22
25
  "Backlog item and scope are approved",
23
26
  "Risks and assumptions are reviewed",
24
27
  "Evidence from advisory artifacts is linked",
25
28
  ],
29
+ assumptions: ["Target project repository is confirmed before conversion."],
30
+ risks: ["Advisory findings may require project-owner validation."],
31
+ paths: [".agent-workflow/advisory"],
32
+ testStrategy: "Review advisory artifacts and attach project evidence.",
26
33
  };
27
34
  }
28
35
  function renderAdvisoryReadme(classification) {
@@ -42,7 +49,8 @@ root instruction files.
42
49
 
43
50
  1. Refine findings in \`${WORKFLOW_DIR}/advisory/decisions.md\`.
44
51
  2. Review role-specific responsibilities in \`${WORKFLOW_DIR}/advisory/role-guides.md\`.
45
- 3. Convert \`${WORKFLOW_DIR}/advisory/project-task.json\` into a project task after the target repo is confirmed.
52
+ 3. Follow \`${WORKFLOW_DIR}/advisory/conversion.md\` after the target repo is confirmed.
53
+ 4. Convert \`${WORKFLOW_DIR}/advisory/project-task.json\` with \`orchestra advisory convert --json\`.
46
54
 
47
55
  ## Classification
48
56
 
@@ -51,6 +59,34 @@ root instruction files.
51
59
  - Signals: ${classification.signals.map((signal) => `\`${signal}\``).join(", ")}
52
60
  `;
53
61
  }
62
+ function renderConversionGuide() {
63
+ return `# Advisory Conversion
64
+
65
+ Use this checklist after the target project repository is confirmed.
66
+
67
+ ## Convert To A Task
68
+
69
+ \`\`\`sh
70
+ orchestra advisory convert --json
71
+ \`\`\`
72
+
73
+ Optional flags:
74
+
75
+ - \`--file <file>\` converts a different project-task JSON file.
76
+ - \`--id <id>\` overrides the advisory task ID.
77
+ - \`--backlog <url>\` links the converted task to an external backlog item.
78
+ - \`--target-dir <dir>\` writes the task into a specific project workspace.
79
+
80
+ ## Verify
81
+
82
+ \`\`\`sh
83
+ orchestra status --json
84
+ orchestra health --json
85
+ \`\`\`
86
+
87
+ Attach the advisory README, decisions, role guides, and this conversion result as evidence on the project task.
88
+ `;
89
+ }
54
90
  function renderRoleGuides(roles) {
55
91
  const advisoryRoles = roles.filter((role) => [
56
92
  "product_owner",
@@ -1 +1 @@
1
- {"version":3,"file":"advisory-artifacts.js","sourceRoot":"","sources":["../src/advisory-artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAa/C,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAC3C,IAAI,EACJ,cAAc,GAIf;IACC,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG;QACZ,MAAM,aAAa,CACjB,IAAI,EACJ,kBAAkB,EAClB,WAAW,EACX,oBAAoB,CAAC,cAAc,CAAC,CACrC;QACD,MAAM,aAAa,CACjB,IAAI,EACJ,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,CAAC,YAAY,CAAC,CAC/B;QACD,MAAM,aAAa,CACjB,IAAI,EACJ,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EAAE,CAC1B;QACD,MAAM,aAAa,CACjB,IAAI,EACJ,kBAAkB,EAClB,mBAAmB,EACnB,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC5C;KACF,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,mBAAmB;IAC1B,OAAO;QACL,EAAE,EAAE,qBAAqB;QACzB,KAAK,EAAE,+CAA+C;QACtD,SAAS,EAAE,eAAe;QAC1B,kBAAkB,EAAE;YAClB,6BAA6B;YAC7B,qCAAqC;YACrC,oCAAoC;YACpC,4CAA4C;SAC7C;KACF,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,cAAuC;IACnE,OAAO;;;sCAG6B,YAAY;;;;;;;;;;;0BAWxB,YAAY;gDACU,YAAY;eAC7C,YAAY;;;;YAIf,cAAc,CAAC,IAAI;oBACX,cAAc,CAAC,WAAW;aACjC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;CAC9E,CAAC;AACF,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAsB;IAC9C,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAC1C;QACE,eAAe;QACf,SAAS;QACT,WAAW;QACX,WAAW;QACX,IAAI;QACJ,UAAU;QACV,iBAAiB;QACjB,kBAAkB;KACnB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CACpB,CAAC;IACF,OAAO;;EAEP,aAAa,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;CAChD,CAAC;AACF,CAAC;AAED,SAAS,eAAe,CAAC,IAAU;IACjC,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,uBAAuB,CAAC,CAAC;SACrE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;SAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,MAAM,IAAI,CAAC,IAAI;;SAEf,IAAI,CAAC,WAAW;;;EAGvB,SAAS;CACV,CAAC;AACF,CAAC;AAED,SAAS,uBAAuB;IAC9B,OAAO;;;;;;;;;;;;;;CAcR,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"advisory-artifacts.js","sourceRoot":"","sources":["../src/advisory-artifacts.ts"],"names":[],"mappings":"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"}
@@ -36,11 +36,15 @@ var endpoints = [
36
36
  ];
37
37
  var statePill = document.querySelector("#load-state");
38
38
  var lastUpdated = document.querySelector("#last-updated");
39
+ var adoptionGuide = document.querySelector("#adoption-guide");
40
+ var releaseReadiness = document.querySelector("#release-readiness");
39
41
  var metrics = document.querySelector("#metrics");
40
42
  var validation = document.querySelector("#validation");
41
43
  var workspaceView = document.querySelector("#workspace-view");
42
44
  var graph = document.querySelector("#graph");
43
45
  var actions = document.querySelector("#actions");
46
+ var taskDetailSelect = document.querySelector("#task-detail-select");
47
+ var taskDetail = document.querySelector("#task-detail");
44
48
  var taskOwner = document.querySelector("#task-owner");
45
49
  var charts = document.querySelector("#charts");
46
50
  var evidenceTask = document.querySelector("#evidence-task");
@@ -82,6 +86,8 @@ document.querySelector("#skills-render").addEventListener("click", loadSkillRend
82
86
  document.querySelector("#lesson-add").addEventListener("click", addLesson);
83
87
  document.querySelector("#lesson-promote").addEventListener("click", promoteLessons);
84
88
  document.querySelector("#task-add").addEventListener("click", addTaskFromWeb);
89
+ document.querySelector("#task-detail-refresh").addEventListener("click", loadTaskDetail);
90
+ taskDetailSelect.addEventListener("change", loadTaskDetail);
85
91
  document.querySelector("#workflow-start").addEventListener("click", startWorkflowFromWeb);
86
92
  workflowRuns.addEventListener("click", handleWorkflowAction);
87
93
  loadDashboard();
@@ -134,9 +140,12 @@ function render(data) {
134
140
  metric(data.validation.valid ? "Valid" : "Needs work", "Workspace")
135
141
  ]);
136
142
  renderValidation(data.validation);
143
+ renderAdoptionGuide(data);
144
+ renderReleaseReadiness(data);
137
145
  renderWorkspace(data.workspaceClassification, data.runtimeAdapters);
138
146
  renderGraph(data.graph);
139
147
  renderActions(data);
148
+ renderTaskDetailControls(data.tasks);
140
149
  renderTaskWriteControls(data.roles);
141
150
  renderCharts(data);
142
151
  renderEvidenceControls(data);
@@ -153,6 +162,149 @@ function render(data) {
153
162
  renderLessons(data.lessons);
154
163
  loadPlaywrightPlan();
155
164
  loadSkillPlan();
165
+ loadTaskDetail();
166
+ }
167
+ function renderTaskDetailControls(tasks) {
168
+ const currentValue = taskDetailSelect.value;
169
+ replace(
170
+ taskDetailSelect,
171
+ tasks.length > 0 ? tasks.map(function(task) {
172
+ return option(task.id, task.id + " - " + task.title);
173
+ }) : [option("", "No tasks")]
174
+ );
175
+ if (currentValue) {
176
+ taskDetailSelect.value = currentValue;
177
+ }
178
+ }
179
+ async function loadTaskDetail() {
180
+ if (!taskDetailSelect.value) {
181
+ replace(taskDetail, [
182
+ empty(
183
+ "No task selected",
184
+ "Create or select a task to inspect acceptance, evidence, and gates."
185
+ )
186
+ ]);
187
+ return;
188
+ }
189
+ try {
190
+ const response = await fetch(
191
+ "/api/task/detail?task=" + encodeURIComponent(taskDetailSelect.value)
192
+ );
193
+ if (!response.ok) {
194
+ throw new Error("task detail returned " + response.status);
195
+ }
196
+ renderTaskDetail(await response.json());
197
+ } catch (error) {
198
+ replace(taskDetail, [
199
+ empty("Task detail unavailable", String(error.message || error))
200
+ ]);
201
+ }
202
+ }
203
+ function renderTaskDetail(detail) {
204
+ const context = detail.context;
205
+ const task = context.task;
206
+ const releaseReadiness2 = detail.releaseReadiness;
207
+ const rows = document.createElement("div");
208
+ rows.className = "detail-grid";
209
+ rows.append(
210
+ detailBlock("Summary", [
211
+ task.id + " [" + task.status + "] " + task.title,
212
+ "Owner: " + task.ownerRole,
213
+ "Backlog: " + (task.backlogItem || "missing")
214
+ ]),
215
+ detailBlock("Acceptance Criteria", task.acceptanceCriteria || []),
216
+ detailBlock("Definition of Ready", readinessLines(context)),
217
+ detailBlock("Definition of Done", releaseReadinessLines(releaseReadiness2)),
218
+ detailBlock(
219
+ "AC Coverage",
220
+ releaseCoverageLines(detail.releaseReadinessReport)
221
+ ),
222
+ detailBlock("Risks", task.risks || []),
223
+ detailBlock("Handoffs", eventLines(context.handoffs)),
224
+ detailBlock("Reviews", eventLines(context.reviews)),
225
+ detailBlock("Evidence", eventLines(context.evidence)),
226
+ detailBlock("Gates", eventLines(context.gates)),
227
+ detailBlock("Next Actions", taskNextActions(context, releaseReadiness2))
228
+ );
229
+ replace(taskDetail, [rows]);
230
+ }
231
+ function releaseCoverageLines(report) {
232
+ if (!report || !Array.isArray(report.acceptanceCoverage)) {
233
+ return ["Coverage unavailable"];
234
+ }
235
+ if (report.acceptanceCoverage.length === 0) {
236
+ return ["No acceptance criteria"];
237
+ }
238
+ return report.acceptanceCoverage.map(function(coverage) {
239
+ const status = coverage.covered ? "covered" : "missing";
240
+ const suffix = coverage.missing && coverage.missing.length > 0 ? " (" + coverage.missing.join(", ") + ")" : "";
241
+ return coverage.criterion + ": " + status + suffix;
242
+ });
243
+ }
244
+ function readinessLines(context) {
245
+ const missing = [];
246
+ [
247
+ "backlogItem",
248
+ "goal",
249
+ "scope",
250
+ "acceptanceCriteria",
251
+ "assumptions",
252
+ "risks",
253
+ "testStrategy"
254
+ ].forEach(function(field) {
255
+ const value = context.task[field];
256
+ if (Array.isArray(value) ? value.length === 0 : !value) {
257
+ missing.push(field);
258
+ }
259
+ });
260
+ return missing.length === 0 ? ["Ready for implementation"] : missing.map(function(field) {
261
+ return "Missing " + field;
262
+ });
263
+ }
264
+ function releaseReadinessLines(releaseReadiness2) {
265
+ if (releaseReadiness2.passed) {
266
+ return ["Release readiness passed"];
267
+ }
268
+ return releaseReadiness2.missing.map(function(field) {
269
+ return "Missing " + field;
270
+ });
271
+ }
272
+ function taskNextActions(context, releaseReadiness2) {
273
+ const actions2 = [];
274
+ if ((context.task.acceptanceCriteria || []).length === 0) {
275
+ actions2.push("Add acceptance criteria before implementation.");
276
+ }
277
+ if (context.handoffs.length === 0) {
278
+ actions2.push("Create the next role handoff when work changes owner.");
279
+ }
280
+ if (context.evidence.length === 0) {
281
+ actions2.push(
282
+ "Attach command, report, screenshot, trace, or video evidence."
283
+ );
284
+ }
285
+ if (!releaseReadiness2.passed) {
286
+ actions2.push("Resolve release-readiness missing fields.");
287
+ }
288
+ return actions2.length > 0 ? actions2 : ["No task-specific action required."];
289
+ }
290
+ function eventLines(events) {
291
+ return events.length > 0 ? events.map(function(event) {
292
+ return event.actor + ": " + event.summary;
293
+ }) : ["none"];
294
+ }
295
+ function detailBlock(title, lines) {
296
+ const block = document.createElement("section");
297
+ block.className = "detail-block";
298
+ const heading = document.createElement("h3");
299
+ heading.textContent = title;
300
+ const list = document.createElement("ul");
301
+ (lines.length > 0 ? lines : ["none"]).forEach(function(line) {
302
+ const item = document.createElement("li");
303
+ item.textContent = line;
304
+ list.append(item);
305
+ });
306
+ block.append(heading, list);
307
+ return block;
156
308
  }
157
309
  function renderTaskWriteControls(roles) {
158
310
  replace(
@@ -194,6 +346,135 @@ async function addTaskFromWeb() {
194
346
  });
195
347
  await loadDashboard();
196
348
  }
349
+ function renderAdoptionGuide(data) {
350
+ const next = determinePrimaryNextAction(data);
351
+ const container = document.createElement("div");
352
+ const lead = document.createElement("p");
353
+ lead.textContent = next.summary;
354
+ const commands = document.createElement("div");
355
+ commands.className = "command-list";
356
+ next.commands.forEach(function(command) {
357
+ const chip = document.createElement("code");
358
+ chip.className = "command-chip";
359
+ chip.textContent = command;
360
+ commands.append(chip);
361
+ });
362
+ const steps = document.createElement("ol");
363
+ steps.className = "step-list";
364
+ next.steps.forEach(function(step, index) {
365
+ const item = document.createElement("li");
366
+ const number = document.createElement("b");
367
+ number.textContent = String(index + 1);
368
+ const text = document.createElement("span");
369
+ text.textContent = step;
370
+ item.append(number, text);
371
+ steps.append(item);
372
+ });
373
+ container.append(lead, commands, steps);
374
+ replace(adoptionGuide, [container]);
375
+ }
376
+ function determinePrimaryNextAction(data) {
377
+ if (!data.validation.valid) {
378
+ return {
379
+ summary: "Resolve workspace validation before starting or releasing work.",
380
+ commands: ["orchestra validate", "orchestra health --json"],
381
+ steps: [
382
+ "Inspect validation errors and warnings.",
383
+ "Fix missing workflow files, invalid task references, or stale locks.",
384
+ "Refresh the console after validation passes."
385
+ ]
386
+ };
387
+ }
388
+ if (data.status.tasks.total === 0) {
389
+ return {
390
+ summary: "Create the first governed task with an owner and acceptance criteria.",
391
+ commands: [
392
+ 'orchestra task add --id STORY-001 --title "First story" --owner developer --acceptance "verified outcome"',
393
+ "orchestra context --task STORY-001 --json"
394
+ ],
395
+ steps: [
396
+ "Add a task from the console or CLI.",
397
+ "Confirm the owner role and acceptance criteria.",
398
+ "Render context before implementation starts."
399
+ ]
400
+ };
401
+ }
402
+ if (data.graph.ready.length > 0) {
403
+ const task = data.graph.ready[0];
404
+ return {
405
+ summary: task.id + " is ready. Start with context, memory, and planning.",
406
+ commands: [
407
+ "orchestra context --task " + task.id + " --json",
408
+ "orchestra memory hook --point before_plan --task " + task.id + " --json",
409
+ "orchestra workflow run --task " + task.id + " --dry-run --gates phase"
410
+ ],
411
+ steps: [
412
+ "Review task context and relevant memory.",
413
+ "Confirm role plan and workflow gates.",
414
+ "Start the workflow when the plan matches the work."
415
+ ]
416
+ };
417
+ }
418
+ if (data.approvals.length > 0) {
419
+ return {
420
+ summary: "There are approval artifacts waiting for a release or workflow decision.",
421
+ commands: ["orchestra approvals list --json", "orchestra summary --json"],
422
+ steps: [
423
+ "Review each pending approval artifact.",
424
+ "Approve, reject, or capture accepted risk.",
425
+ "Resume the paused workflow after approval."
426
+ ]
427
+ };
428
+ }
429
+ return {
430
+ summary: "The workspace has no immediate blocking action.",
431
+ commands: ["orchestra summary --json", "orchestra release check --json"],
432
+ steps: [
433
+ "Review summary for stale evidence or locks.",
434
+ "Run release check before tagging.",
435
+ "Record smoke and rollback evidence when preparing a release."
436
+ ]
437
+ };
438
+ }
439
+ function renderReleaseReadiness(data) {
440
+ const evidenceCount = data.evidence.length;
441
+ const approvalCount = data.approvals.length;
442
+ const rows = [
443
+ readinessRow(
444
+ data.validation.valid,
445
+ "Workspace validation",
446
+ data.validation.valid ? "Valid" : "Needs fixes"
447
+ ),
448
+ readinessRow(
449
+ data.graph.blocked.length === 0 && data.graph.locked.length === 0,
450
+ "Task flow",
451
+ data.graph.blocked.length + " blocked, " + data.graph.locked.length + " locked"
452
+ ),
453
+ readinessRow(evidenceCount > 0, "Evidence", evidenceCount + " artifact(s)"),
454
+ readinessRow(
455
+ approvalCount === 0,
456
+ "Approvals",
457
+ approvalCount + " pending artifact(s)"
458
+ ),
459
+ readinessRow(
460
+ data.budget.passed,
461
+ "Budget",
462
+ data.budget.passed ? "Within configured limits" : data.budget.violations.length + " violation(s)"
463
+ )
464
+ ];
465
+ replace(releaseReadiness, rows);
466
+ }
467
+ function readinessRow(ok, title, detail) {
468
+ const node = listItem(title, detail);
469
+ const tag = document.createElement("span");
470
+ tag.className = ok ? "tag ok" : "tag warn";
471
+ tag.textContent = ok ? "ready" : "attention";
472
+ const row = document.createElement("div");
473
+ row.className = "tag-row";
474
+ row.append(tag);
475
+ node.append(row);
476
+ return node;
477
+ }
197
478
  function renderWorkspace(classification, adapters) {
198
479
  const adapterNames = adapters.map(function(adapter) {
199
480
  return adapter.label;
@@ -862,10 +1143,7 @@ function renderGraph(plan) {
862
1143
  ["Complete", plan.complete]
863
1144
  ].flatMap(function(group) {
864
1145
  return group[1].slice(0, 4).map(function(item) {
865
- return listItem(
866
- item.title,
867
- group[0] + " - " + item.id + " - " + item.ownerRole
868
- );
1146
+ return listItem(item.title, graphItemDetail(group[0], item));
869
1147
  });
870
1148
  });
871
1149
  replace(
@@ -878,6 +1156,20 @@ function renderGraph(plan) {
878
1156
  ]
879
1157
  );
880
1158
  }
1159
+ function graphItemDetail(group, item) {
1160
+ const base = group + " - " + item.id + " - " + item.ownerRole;
1161
+ if (group === "Blocked" && item.incomplete?.length > 0) {
1162
+ return base + " - blockers: " + item.incomplete.map(function(dependency) {
1163
+ return dependency.id + " [" + dependency.status + "]";
1164
+ }).join(", ");
1165
+ }
1166
+ if (group === "Locked" && item.locks?.length > 0) {
1167
+ return base + " - locks: " + item.locks.map(function(lock) {
1168
+ return lock.path + " (" + lock.reason + ")";
1169
+ }).join(", ");
1170
+ }
1171
+ return base;
1172
+ }
881
1173
  function renderActions(data) {
882
1174
  const next = [];
883
1175
  if (!data.validation.valid) {
@@ -965,6 +1257,7 @@ function renderEmpty(title, detail) {
965
1257
  replace(workspaceView, []);
966
1258
  replace(graph, []);
967
1259
  replace(actions, []);
1260
+ replace(taskDetail, []);
968
1261
  }
969
1262
  function setLoading(label, tone) {
970
1263
  statePill.textContent = label;