@topogram/cli 0.3.64 → 0.3.65

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 (245) hide show
  1. package/package.json +1 -1
  2. package/src/adoption/plan/index.js +703 -0
  3. package/src/adoption/plan.js +12 -703
  4. package/src/agent-ops/query-builders/auth.js +375 -0
  5. package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
  6. package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
  7. package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
  8. package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
  9. package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
  10. package/src/agent-ops/query-builders/change-risk.js +25 -0
  11. package/src/agent-ops/query-builders/common.js +149 -0
  12. package/src/agent-ops/query-builders/maintained-risk.js +539 -0
  13. package/src/agent-ops/query-builders/maintained-shared.js +120 -0
  14. package/src/agent-ops/query-builders/multi-agent.js +547 -0
  15. package/src/agent-ops/query-builders/projection-impacts.js +514 -0
  16. package/src/agent-ops/query-builders/work-packets.js +417 -0
  17. package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
  18. package/src/agent-ops/query-builders/workflow-context.js +398 -0
  19. package/src/agent-ops/query-builders/workflow-presets-core.js +676 -0
  20. package/src/agent-ops/query-builders/workflow-presets.js +341 -0
  21. package/src/agent-ops/query-builders.d.ts +26 -26
  22. package/src/agent-ops/query-builders.js +42 -5021
  23. package/src/catalog/constants.js +10 -0
  24. package/src/catalog/copy.js +60 -0
  25. package/src/catalog/diagnostics.js +15 -0
  26. package/src/catalog/entries.js +42 -0
  27. package/src/catalog/files.js +67 -0
  28. package/src/catalog/provenance.js +122 -0
  29. package/src/catalog/source.js +150 -0
  30. package/src/catalog/validation.js +252 -0
  31. package/src/catalog.d.ts +2 -0
  32. package/src/catalog.js +18 -746
  33. package/src/cli/commands/catalog/check.js +31 -0
  34. package/src/cli/commands/catalog/copy.js +59 -0
  35. package/src/cli/commands/catalog/doctor.js +248 -0
  36. package/src/cli/commands/catalog/help.js +21 -0
  37. package/src/cli/commands/catalog/list.js +52 -0
  38. package/src/cli/commands/catalog/runner.js +92 -0
  39. package/src/cli/commands/catalog/shared.js +17 -0
  40. package/src/cli/commands/catalog/show.js +134 -0
  41. package/src/cli/commands/catalog.js +30 -615
  42. package/src/cli/commands/generator-policy/package-info.js +162 -0
  43. package/src/cli/commands/generator-policy/payloads.js +372 -0
  44. package/src/cli/commands/generator-policy/printers.js +159 -0
  45. package/src/cli/commands/generator-policy/runner.js +81 -0
  46. package/src/cli/commands/generator-policy/shared.js +39 -0
  47. package/src/cli/commands/generator-policy.js +15 -783
  48. package/src/cli/commands/import/adopt.js +170 -0
  49. package/src/cli/commands/import/check.js +91 -0
  50. package/src/cli/commands/import/diff.js +84 -0
  51. package/src/cli/commands/import/help.js +47 -0
  52. package/src/cli/commands/import/paths.js +277 -0
  53. package/src/cli/commands/import/plan.js +284 -0
  54. package/src/cli/commands/import/refresh.js +470 -0
  55. package/src/cli/commands/import/status-history.js +196 -0
  56. package/src/cli/commands/import/workspace.js +230 -0
  57. package/src/cli/commands/import.js +33 -1732
  58. package/src/cli/commands/package/constants.js +17 -0
  59. package/src/cli/commands/package/doctor.js +240 -0
  60. package/src/cli/commands/package/help.js +27 -0
  61. package/src/cli/commands/package/lockfile.js +135 -0
  62. package/src/cli/commands/package/npm.js +97 -0
  63. package/src/cli/commands/package/reporting.js +35 -0
  64. package/src/cli/commands/package/runner.js +33 -0
  65. package/src/cli/commands/package/shared.js +9 -0
  66. package/src/cli/commands/package/update-cli.js +252 -0
  67. package/src/cli/commands/package/versions.js +35 -0
  68. package/src/cli/commands/package.js +29 -813
  69. package/src/cli/commands/query/change-plan.js +68 -0
  70. package/src/cli/commands/query/definitions.js +202 -0
  71. package/src/cli/commands/query/import-adopt.js +121 -0
  72. package/src/cli/commands/query/runner/artifacts.js +102 -0
  73. package/src/cli/commands/query/runner/boundaries.js +211 -0
  74. package/src/cli/commands/query/runner/change.js +182 -0
  75. package/src/cli/commands/query/runner/import-adopt.js +111 -0
  76. package/src/cli/commands/query/runner/index.js +31 -0
  77. package/src/cli/commands/query/runner/output.js +12 -0
  78. package/src/cli/commands/query/runner/workflow.js +241 -0
  79. package/src/cli/commands/query/runner.js +3 -0
  80. package/src/cli/commands/query/workflow-context.js +5 -0
  81. package/src/cli/commands/query/workspace.js +274 -0
  82. package/src/cli/commands/query.js +9 -1300
  83. package/src/cli/commands/template/baseline.js +100 -0
  84. package/src/cli/commands/template/check.js +466 -0
  85. package/src/cli/commands/template/constants.js +8 -0
  86. package/src/cli/commands/template/diagnostics.js +26 -0
  87. package/src/cli/commands/template/help.js +28 -0
  88. package/src/cli/commands/template/lifecycle.js +404 -0
  89. package/src/cli/commands/template/list-show.js +287 -0
  90. package/src/cli/commands/template/policy.js +422 -0
  91. package/src/cli/commands/template/shared.js +127 -0
  92. package/src/cli/commands/template/updates.js +352 -0
  93. package/src/cli/commands/template.js +41 -2143
  94. package/src/generator/api/contracts.js +497 -0
  95. package/src/generator/api/metadata.js +221 -0
  96. package/src/generator/api/openapi.js +559 -0
  97. package/src/generator/api/schema.js +124 -0
  98. package/src/generator/api/types.d.ts +98 -0
  99. package/src/generator/api.js +3 -1195
  100. package/src/generator/context/shared/domain-sdlc.js +282 -0
  101. package/src/generator/context/shared/maintained-boundary.js +665 -0
  102. package/src/generator/context/shared/metrics.js +85 -0
  103. package/src/generator/context/shared/primitives.js +64 -0
  104. package/src/generator/context/shared/relationships.js +453 -0
  105. package/src/generator/context/shared/summaries.js +263 -0
  106. package/src/generator/context/shared/types.d.ts +207 -0
  107. package/src/generator/context/shared.d.ts +42 -0
  108. package/src/generator/context/shared.js +80 -1390
  109. package/src/generator/context/slice/core.js +397 -0
  110. package/src/generator/context/slice/sdlc.js +417 -0
  111. package/src/generator/context/slice/ui-packets.js +183 -0
  112. package/src/generator/context/slice.js +2 -859
  113. package/src/generator/registry/index.js +507 -0
  114. package/src/generator/registry.js +18 -504
  115. package/src/generator/runtime/environment/index.js +666 -0
  116. package/src/generator/runtime/environment.js +4 -666
  117. package/src/generator/runtime/runtime-check/index.js +554 -0
  118. package/src/generator/runtime/runtime-check.js +4 -554
  119. package/src/generator/runtime/shared/index.js +572 -0
  120. package/src/generator/runtime/shared.js +19 -570
  121. package/src/generator/shared.d.ts +2 -0
  122. package/src/generator/surfaces/shared.d.ts +3 -0
  123. package/src/generator/widget-conformance/behavior-report.js +258 -0
  124. package/src/generator/widget-conformance/checks.js +371 -0
  125. package/src/generator/widget-conformance/projection-context.js +200 -0
  126. package/src/generator/widget-conformance/report.js +166 -0
  127. package/src/generator/widget-conformance/types.d.ts +121 -0
  128. package/src/generator/widget-conformance.js +3 -824
  129. package/src/import/core/context.d.ts +3 -0
  130. package/src/import/core/contracts.d.ts +1 -0
  131. package/src/import/core/registry.d.ts +4 -0
  132. package/src/import/core/runner/candidates.js +217 -0
  133. package/src/import/core/runner/options.js +22 -0
  134. package/src/import/core/runner/reports.js +50 -0
  135. package/src/import/core/runner/run.js +79 -0
  136. package/src/import/core/runner/tracks.js +150 -0
  137. package/src/import/core/runner/ui-drafts.js +337 -0
  138. package/src/import/core/runner.js +3 -698
  139. package/src/import/core/shared/api-routes.js +221 -0
  140. package/src/import/core/shared/candidates.js +97 -0
  141. package/src/import/core/shared/files.js +177 -0
  142. package/src/import/core/shared/next-app.js +389 -0
  143. package/src/import/core/shared/types.d.ts +51 -0
  144. package/src/import/core/shared/ui-routes.js +230 -0
  145. package/src/import/core/shared.js +60 -861
  146. package/src/new-project/constants.js +128 -0
  147. package/src/new-project/create.js +83 -0
  148. package/src/new-project/json.js +28 -0
  149. package/src/new-project/metadata.js +96 -0
  150. package/src/new-project/package-spec.js +161 -0
  151. package/src/new-project/project-files.js +348 -0
  152. package/src/new-project/template-policy.js +269 -0
  153. package/src/new-project/template-resolution.js +368 -0
  154. package/src/new-project/template-snapshots.js +430 -0
  155. package/src/new-project/template-updates.js +512 -0
  156. package/src/new-project/types.d.ts +83 -0
  157. package/src/new-project.js +6 -2277
  158. package/src/parser.d.ts +87 -1
  159. package/src/parser.js +118 -0
  160. package/src/policy/review-boundaries.d.ts +15 -0
  161. package/src/project-config/index.js +564 -0
  162. package/src/project-config.js +19 -561
  163. package/src/resolver/enrich/acceptance-criterion.js +2 -0
  164. package/src/resolver/enrich/bug.js +2 -0
  165. package/src/resolver/enrich/pitch.js +2 -0
  166. package/src/resolver/enrich/requirement.js +2 -0
  167. package/src/resolver/enrich/task.js +2 -0
  168. package/src/resolver/index.js +19 -2089
  169. package/src/resolver/normalize.js +384 -1
  170. package/src/resolver/plans.js +168 -0
  171. package/src/resolver/projections-api.js +494 -0
  172. package/src/resolver/projections-db.js +133 -0
  173. package/src/resolver/projections-ui.js +317 -0
  174. package/src/resolver/shapes.js +251 -0
  175. package/src/resolver/shared.js +278 -0
  176. package/src/resolver/widgets.js +132 -0
  177. package/src/template-trust/constants.js +62 -0
  178. package/src/template-trust/content.js +258 -0
  179. package/src/template-trust/diff.js +92 -0
  180. package/src/template-trust/policy.js +61 -0
  181. package/src/template-trust/record.js +90 -0
  182. package/src/template-trust/status.js +182 -0
  183. package/src/template-trust.js +24 -687
  184. package/src/text-helpers.d.ts +1 -0
  185. package/src/topogram-types.d.ts +69 -0
  186. package/src/validator/common.js +488 -0
  187. package/src/validator/data-model.js +237 -0
  188. package/src/validator/docs.js +167 -0
  189. package/src/validator/expressions.js +146 -1
  190. package/src/validator/index.d.ts +23 -0
  191. package/src/validator/index.js +32 -3585
  192. package/src/validator/kinds.d.ts +41 -0
  193. package/src/validator/kinds.js +2 -0
  194. package/src/validator/model-helpers.js +46 -0
  195. package/src/validator/per-kind/acceptance-criterion.js +5 -0
  196. package/src/validator/per-kind/bug.js +6 -0
  197. package/src/validator/per-kind/domain.js +15 -2
  198. package/src/validator/per-kind/pitch.js +7 -0
  199. package/src/validator/per-kind/requirement.js +5 -0
  200. package/src/validator/per-kind/task.js +7 -0
  201. package/src/validator/per-kind/widget.js +14 -0
  202. package/src/validator/projections/api-http-async.js +410 -0
  203. package/src/validator/projections/api-http-authz.js +88 -0
  204. package/src/validator/projections/api-http-core.js +205 -0
  205. package/src/validator/projections/api-http-policies.js +339 -0
  206. package/src/validator/projections/api-http-responses.js +233 -0
  207. package/src/validator/projections/api-http.js +44 -0
  208. package/src/validator/projections/db.js +353 -0
  209. package/src/validator/projections/generator-defaults.js +45 -0
  210. package/src/validator/projections/helpers.js +87 -0
  211. package/src/validator/projections/ui-helpers.js +214 -0
  212. package/src/validator/projections/ui-navigation.js +344 -0
  213. package/src/validator/projections/ui-structure.js +364 -0
  214. package/src/validator/projections/ui-widgets.js +493 -0
  215. package/src/validator/projections/ui.js +46 -0
  216. package/src/validator/registry.js +48 -1
  217. package/src/validator/utils.d.ts +20 -0
  218. package/src/validator/utils.js +115 -12
  219. package/src/widget-behavior.d.ts +1 -0
  220. package/src/workflows/import-app/api/collect.js +221 -0
  221. package/src/workflows/import-app/api/openapi.js +257 -0
  222. package/src/workflows/import-app/api/routes.js +327 -0
  223. package/src/workflows/import-app/api/sources.js +22 -0
  224. package/src/workflows/import-app/api.js +2 -797
  225. package/src/workflows/reconcile/adoption-plan/build.js +208 -0
  226. package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
  227. package/src/workflows/reconcile/adoption-plan/outputs.js +143 -0
  228. package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
  229. package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
  230. package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
  231. package/src/workflows/reconcile/adoption-plan.js +30 -740
  232. package/src/workflows/reconcile/auth/closures.js +115 -0
  233. package/src/workflows/reconcile/auth/formatters.js +142 -0
  234. package/src/workflows/reconcile/auth/inference.js +330 -0
  235. package/src/workflows/reconcile/auth/roles.js +122 -0
  236. package/src/workflows/reconcile/auth.js +35 -690
  237. package/src/workflows/reconcile/bundle-core/index.js +600 -0
  238. package/src/workflows/reconcile/bundle-core.js +12 -598
  239. package/src/workflows/reconcile/canonical-surface.js +1 -1
  240. package/src/workflows/reconcile/impacts/adoption-plan.js +192 -0
  241. package/src/workflows/reconcile/impacts/indexes.js +101 -0
  242. package/src/workflows/reconcile/impacts/patches.js +252 -0
  243. package/src/workflows/reconcile/impacts/reports.js +80 -0
  244. package/src/workflows/reconcile/impacts.js +14 -623
  245. package/src/workspace-docs.d.ts +29 -0
@@ -0,0 +1,300 @@
1
+ import {
2
+ WORKFLOW_QUERY_FAMILIES_BY_MODE,
3
+ stableSortedStrings
4
+ } from "./common.js";
5
+ export function outputIdsForWorkflowContext(taskModeArtifact, maintainedBoundary = null) {
6
+ return stableSortedStrings([
7
+ ...((taskModeArtifact?.verification_targets?.output_verification_targets || []).map((entry) => entry.output_id)),
8
+ ...((maintainedBoundary?.outputs || []).map((entry) => entry.output_id))
9
+ ]);
10
+ }
11
+
12
+ export function integrationCategoriesForWorkflowContext(taskModeArtifact, importPlan = null) {
13
+ const categories = [];
14
+ if (taskModeArtifact?.mode === "import-adopt") categories.push("provider_adoption");
15
+ if (taskModeArtifact?.mode === "maintained-app-edit") categories.push("maintained_app");
16
+ if ((taskModeArtifact?.verification_targets?.maintained_app_checks || []).length > 0) categories.push("maintained_boundary");
17
+ if ((importPlan?.requires_human_review || []).length > 0) categories.push("human_review");
18
+ return stableSortedStrings(categories);
19
+ }
20
+
21
+ export function currentFocusFromTaskMode(taskModeArtifact) {
22
+ const selectedSurface = taskModeArtifact?.summary?.selected_surface || null;
23
+ if (selectedSurface) {
24
+ return selectedSurface;
25
+ }
26
+ const focus = taskModeArtifact?.summary?.focus || null;
27
+ return focus ? { kind: "mode_focus", label: focus } : null;
28
+ }
29
+
30
+ export function verificationSurfaceForTargets(verificationTargets) {
31
+ const targetCount = ((verificationTargets?.generated_checks || []).length)
32
+ + ((verificationTargets?.maintained_app_checks || []).length)
33
+ + ((verificationTargets?.verification_ids || []).length);
34
+ return targetCount > 0 ? "verification-targets" : null;
35
+ }
36
+
37
+ export function recommendedQueryFamilyForAction(nextAction, mode = null) {
38
+ switch (nextAction?.kind) {
39
+ case "review_staged":
40
+ case "review_bundle":
41
+ case "inspect_review_group":
42
+ case "inspect_proposal_surface":
43
+ case "customize_workflow_preset":
44
+ case "refresh_workflow_preset_customization":
45
+ case "import_declared_workflow_preset":
46
+ return "import-plan";
47
+ case "review_diff_impact":
48
+ case "inspect_projection":
49
+ case "inspect_diff":
50
+ case "review_diff_boundaries":
51
+ return "change-plan";
52
+ case "inspect_maintained_impact":
53
+ case "inspect_boundary_before_edit":
54
+ case "run_maintained_checks":
55
+ return "maintained-boundary";
56
+ case "inspect_verification_targets":
57
+ return "verification-targets";
58
+ case "inspect_workspace_digest":
59
+ return "single-agent-plan";
60
+ default:
61
+ break;
62
+ }
63
+
64
+ if (mode === "import-adopt") return "import-plan";
65
+ if (mode === "maintained-app-edit") return "maintained-boundary";
66
+ if (mode === "verification") return "verification-targets";
67
+ return "change-plan";
68
+ }
69
+
70
+ export function immediateArtifacts(primaryArtifacts = []) {
71
+ return (primaryArtifacts || []).slice(0, 2);
72
+ }
73
+
74
+ export function buildOperatorLoopSummary({
75
+ mode = null,
76
+ nextAction = null,
77
+ primaryArtifacts = [],
78
+ verificationTargets = null,
79
+ currentSurface = null
80
+ } = {}) {
81
+ return {
82
+ current_surface: currentSurface,
83
+ start_query_family: recommendedQueryFamilyForAction(nextAction, mode),
84
+ immediate_artifacts: immediateArtifacts(primaryArtifacts),
85
+ review_surface: "review-packet",
86
+ decision_surface: "proceed-decision",
87
+ verification_surface: verificationSurfaceForTargets(verificationTargets)
88
+ };
89
+ }
90
+
91
+ export function nextActionRequiresReview(nextAction) {
92
+ const reviewKinds = new Set([
93
+ "review_staged",
94
+ "inspect_review_group",
95
+ "inspect_proposal_surface",
96
+ "inspect_plan",
97
+ "inspect_boundary_before_edit",
98
+ "review_diff_boundaries",
99
+ "review_diff_impact",
100
+ "inspect_maintained_impact",
101
+ "inspect_generated_impact",
102
+ "inspect_diff",
103
+ "inspect_verification_targets",
104
+ "inspect_workspace_digest"
105
+ ]);
106
+ return reviewKinds.has(nextAction?.kind);
107
+ }
108
+
109
+ export function buildReviewBoundaries(taskModeArtifact, importPlan = null) {
110
+ return {
111
+ ownership_boundary: taskModeArtifact?.ownership_boundary || null,
112
+ review_emphasis: taskModeArtifact?.review_emphasis || [],
113
+ approved_review_groups: importPlan?.review_groups || [],
114
+ requires_human_review: importPlan?.requires_human_review || []
115
+ };
116
+ }
117
+
118
+ export function buildBlockingConditions(taskModeArtifact, importPlan = null) {
119
+ const blocking = [];
120
+ const nextAction = taskModeArtifact?.next_action || null;
121
+
122
+ if (nextAction?.kind === "missing_plan") {
123
+ blocking.push({
124
+ kind: "missing_artifact",
125
+ artifact: "candidates/reconcile/adoption-plan.agent.json",
126
+ reason: nextAction.reason || "No staged adoption plan exists yet.",
127
+ recommended_step: "Run reconcile first."
128
+ });
129
+ }
130
+
131
+ if ((importPlan?.requires_human_review || []).length > 0) {
132
+ blocking.push({
133
+ kind: "human_review_required",
134
+ count: importPlan.requires_human_review.length,
135
+ items: importPlan.requires_human_review,
136
+ reason: `${importPlan.requires_human_review.length} staged proposal(s) still require human review or mapping decisions before canonical adoption.`
137
+ });
138
+ }
139
+
140
+ if (nextAction && nextActionRequiresReview(nextAction)) {
141
+ blocking.push({
142
+ kind: "review_gate",
143
+ next_action_kind: nextAction.kind,
144
+ reason: nextAction.reason || "The next step is review-oriented rather than directly executable."
145
+ });
146
+ }
147
+
148
+ return blocking;
149
+ }
150
+
151
+ export function firstPrimaryArtifact(taskModeArtifact) {
152
+ return (taskModeArtifact?.preferred_context_artifacts || [])[0] || null;
153
+ }
154
+
155
+ export function buildImportAdoptSequence(taskModeArtifact, importPlan = null) {
156
+ const steps = [];
157
+ const primaryArtifact = firstPrimaryArtifact(taskModeArtifact);
158
+ if (primaryArtifact) {
159
+ steps.push({
160
+ order: steps.length + 1,
161
+ action: "read_primary_artifact",
162
+ artifact: primaryArtifact,
163
+ review_required: false,
164
+ reason: "Start from the staged adoption view before changing canonical Topogram."
165
+ });
166
+ }
167
+ if (importPlan) {
168
+ steps.push({
169
+ order: steps.length + 1,
170
+ action: "inspect_adoption_state",
171
+ review_required: (importPlan.requires_human_review || []).length > 0,
172
+ reason: `${(importPlan.staged_items || []).length} staged item(s) and ${(importPlan.requires_human_review || []).length} review-required item(s) are currently in scope.`
173
+ });
174
+ }
175
+ if (taskModeArtifact?.next_action) {
176
+ steps.push({
177
+ order: steps.length + 1,
178
+ action: "follow_next_action",
179
+ next_action_kind: taskModeArtifact.next_action.kind,
180
+ review_required: nextActionRequiresReview(taskModeArtifact.next_action),
181
+ reason: taskModeArtifact.next_action.reason || "Follow the current staged adoption step."
182
+ });
183
+ }
184
+ steps.push({
185
+ order: steps.length + 1,
186
+ action: "run_proof_targets",
187
+ review_required: false,
188
+ proof_targets: taskModeArtifact?.verification_targets || null,
189
+ reason: "Validate proposal state before any canonical write."
190
+ });
191
+ return steps;
192
+ }
193
+
194
+ export function buildMaintainedAppEditSequence(taskModeArtifact) {
195
+ const steps = [];
196
+ const primaryArtifact = firstPrimaryArtifact(taskModeArtifact);
197
+ if (primaryArtifact) {
198
+ steps.push({
199
+ order: 1,
200
+ action: "read_primary_artifact",
201
+ artifact: primaryArtifact,
202
+ review_required: false,
203
+ reason: "Start from the maintained-app bundle to see accepted, guarded, and no-go seams."
204
+ });
205
+ }
206
+ steps.push({
207
+ order: steps.length + 1,
208
+ action: "inspect_review_boundaries",
209
+ review_required: true,
210
+ reason: "Review human-owned seams and guarded boundaries before editing maintained code."
211
+ });
212
+ steps.push({
213
+ order: steps.length + 1,
214
+ action: "respect_write_scope",
215
+ review_required: false,
216
+ reason: "Keep edits inside the maintained write scope attached to the current proof bundle."
217
+ });
218
+ steps.push({
219
+ order: steps.length + 1,
220
+ action: "run_proof_targets",
221
+ review_required: false,
222
+ proof_targets: taskModeArtifact?.verification_targets || null,
223
+ reason: "Run maintained proof checks after the bounded edit."
224
+ });
225
+ return steps;
226
+ }
227
+
228
+ export function buildGenericSequence(taskModeArtifact, {
229
+ readReason,
230
+ reviewReason,
231
+ proofReason
232
+ } = {}) {
233
+ const steps = [];
234
+ const primaryArtifact = firstPrimaryArtifact(taskModeArtifact);
235
+ if (primaryArtifact) {
236
+ steps.push({
237
+ order: steps.length + 1,
238
+ action: "read_primary_artifact",
239
+ artifact: primaryArtifact,
240
+ review_required: false,
241
+ reason: readReason || "Start from the preferred context artifact for this mode."
242
+ });
243
+ }
244
+ if (taskModeArtifact?.next_action) {
245
+ steps.push({
246
+ order: steps.length + 1,
247
+ action: "follow_next_action",
248
+ next_action_kind: taskModeArtifact.next_action.kind,
249
+ review_required: nextActionRequiresReview(taskModeArtifact.next_action),
250
+ reason: taskModeArtifact.next_action.reason || "Follow the current recommended next action."
251
+ });
252
+ }
253
+ steps.push({
254
+ order: steps.length + 1,
255
+ action: "inspect_review_boundaries",
256
+ review_required: true,
257
+ reason: reviewReason || "Use the attached review emphasis and ownership boundary before mutating durable meaning."
258
+ });
259
+ steps.push({
260
+ order: steps.length + 1,
261
+ action: "run_proof_targets",
262
+ review_required: false,
263
+ proof_targets: taskModeArtifact?.verification_targets || null,
264
+ reason: proofReason || "Run the smallest proof set attached to this mode."
265
+ });
266
+ return steps;
267
+ }
268
+
269
+ export function buildRecommendedSequence(taskModeArtifact, importPlan = null) {
270
+ const mode = taskModeArtifact?.mode || null;
271
+ if (mode === "import-adopt") {
272
+ return buildImportAdoptSequence(taskModeArtifact, importPlan);
273
+ }
274
+ if (mode === "maintained-app-edit") {
275
+ return buildMaintainedAppEditSequence(taskModeArtifact);
276
+ }
277
+ if (mode === "diff-review") {
278
+ return buildGenericSequence(taskModeArtifact, {
279
+ readReason: "Start from the diff or focused slice before choosing an edit path.",
280
+ reviewReason: "Diff review should stay read-first until maintained and generated impact is clear.",
281
+ proofReason: "Keep proof selection attached to the affected semantic change."
282
+ });
283
+ }
284
+ if (mode === "verification") {
285
+ return buildGenericSequence(taskModeArtifact, {
286
+ readReason: "Start from the focused verification context before running checks.",
287
+ reviewReason: "Confirm the intended verification surface before widening the check set.",
288
+ proofReason: "Run the smallest correct proof set for the current task."
289
+ });
290
+ }
291
+ return buildGenericSequence(taskModeArtifact, {
292
+ readReason: "Start from the focused modeling context before editing canonical Topogram.",
293
+ reviewReason: "Review semantic boundaries before changing durable intent.",
294
+ proofReason: "Run the proof targets attached to the selected semantic closure."
295
+ });
296
+ }
297
+
298
+ export function coreWorkflowQueriesForMode(mode) {
299
+ return WORKFLOW_QUERY_FAMILIES_BY_MODE[mode] || ["change-plan", "risk-summary", "verification-targets"];
300
+ }
@@ -0,0 +1,398 @@
1
+ import {
2
+ CANONICAL_TASK_MODES,
3
+ artifactLoadOrderFromGeneratorTargets,
4
+ flattenVerificationTargets,
5
+ recommendedArtifactQueriesFromGeneratorTargets,
6
+ stableOrderedUnion,
7
+ stableSortedStrings
8
+ } from "./common.js";
9
+ import {
10
+ activeProviderPreset,
11
+ activeTeamPreset,
12
+ loadWorkflowPresetArtifacts,
13
+ presetAppliesToContext,
14
+ providerManifestWorkflowPresetDeclarations,
15
+ skippedPresetReason,
16
+ summarizeWorkflowPreset
17
+ } from "./workflow-presets-core.js";
18
+ import { buildWorkflowPresetInventory } from "./workflow-presets.js";
19
+ import {
20
+ buildBlockingConditions,
21
+ buildOperatorLoopSummary,
22
+ buildRecommendedSequence,
23
+ buildReviewBoundaries,
24
+ coreWorkflowQueriesForMode,
25
+ currentFocusFromTaskMode,
26
+ integrationCategoriesForWorkflowContext,
27
+ outputIdsForWorkflowContext
28
+ } from "./workflow-context-shared.js";
29
+ import { buildPresetGuidanceSummary, classifyRisk } from "./change-risk.js";
30
+ export function activeWorkflowPresetsForContext({
31
+ workspace = null,
32
+ providerPresets = null,
33
+ teamPresets = null,
34
+ providerManifests = null,
35
+ selectors = {}
36
+ } = {}) {
37
+ const loaded = (providerPresets && teamPresets)
38
+ ? { provider_presets: providerPresets, team_presets: teamPresets, provider_manifests: providerManifests || [] }
39
+ : loadWorkflowPresetArtifacts(workspace);
40
+
41
+ const activeProviderPresets = loaded.provider_presets
42
+ .filter((preset) => activeProviderPreset(preset) && presetAppliesToContext(preset, selectors))
43
+ .sort((a, b) => a.priority - b.priority || a.source_priority - b.source_priority || String(a.id).localeCompare(String(b.id)));
44
+ const activeTeamPresets = loaded.team_presets
45
+ .filter((preset) => activeTeamPreset(preset) && presetAppliesToContext(preset, selectors))
46
+ .sort((a, b) => a.priority - b.priority || a.source_priority - b.source_priority || String(a.id).localeCompare(String(b.id)));
47
+ const skippedPresets = [
48
+ ...loaded.provider_presets
49
+ .filter((preset) => !activeProviderPreset(preset) || !presetAppliesToContext(preset, selectors))
50
+ .map((preset) => ({
51
+ id: preset.id,
52
+ kind: preset.kind,
53
+ provider_id: preset.provider?.id || preset.provenance?.provider_id || null,
54
+ priority: preset.priority,
55
+ reason: skippedPresetReason(preset, selectors)
56
+ })),
57
+ ...loaded.team_presets
58
+ .filter((preset) => !activeTeamPreset(preset) || !presetAppliesToContext(preset, selectors))
59
+ .map((preset) => ({
60
+ id: preset.id,
61
+ kind: preset.kind,
62
+ provider_id: preset.provider?.id || preset.provenance?.provider_id || null,
63
+ priority: preset.priority,
64
+ reason: skippedPresetReason(preset, selectors)
65
+ }))
66
+ ].sort((a, b) => `${a.kind}:${a.id}`.localeCompare(`${b.kind}:${b.id}`));
67
+
68
+ return {
69
+ active_provider_presets: activeProviderPresets,
70
+ active_team_presets: activeTeamPresets,
71
+ skipped_presets: skippedPresets,
72
+ provider_manifest_declarations: providerManifestWorkflowPresetDeclarations(loaded.provider_manifests || [], loaded.provider_presets || [])
73
+ };
74
+ }
75
+
76
+ export function mergeFieldResolution(entries = []) {
77
+ return entries.filter(Boolean).map((entry) => ({
78
+ preset_id: entry.id,
79
+ kind: entry.kind,
80
+ priority: entry.priority,
81
+ source_priority: entry.source_priority
82
+ }));
83
+ }
84
+
85
+ export function buildWorkflowPresetActivationPayload({
86
+ workspace = null,
87
+ taskModeArtifact,
88
+ importPlan = null,
89
+ maintainedBoundary = null,
90
+ providerPresets = null,
91
+ teamPresets = null,
92
+ providerManifests = null,
93
+ selectors = {}
94
+ }) {
95
+ const resolvedSelectors = {
96
+ mode: taskModeArtifact?.mode || null,
97
+ task_class: taskModeArtifact?.mode || null,
98
+ outputs: outputIdsForWorkflowContext(taskModeArtifact, maintainedBoundary),
99
+ integration_categories: integrationCategoriesForWorkflowContext(taskModeArtifact, importPlan),
100
+ query_family: "workflow-activation",
101
+ manual_context: Boolean(importPlan?.requires_human_review?.length),
102
+ ...selectors
103
+ };
104
+ const inventory = buildWorkflowPresetInventory({
105
+ workspace,
106
+ providerPresets,
107
+ teamPresets,
108
+ providerManifests,
109
+ selectors: resolvedSelectors
110
+ });
111
+ const activation = activeWorkflowPresetsForContext({
112
+ workspace,
113
+ providerPresets,
114
+ teamPresets,
115
+ providerManifests,
116
+ selectors: resolvedSelectors
117
+ });
118
+ return {
119
+ type: "workflow_preset_activation_query",
120
+ mode: resolvedSelectors.mode,
121
+ selectors: resolvedSelectors,
122
+ active_presets: [
123
+ ...activation.active_provider_presets.map((preset) => summarizeWorkflowPreset(preset, resolvedSelectors)),
124
+ ...activation.active_team_presets.map((preset) => summarizeWorkflowPreset(preset, resolvedSelectors))
125
+ ].sort((a, b) => `${a.kind}:${a.priority}:${a.id}`.localeCompare(`${b.kind}:${b.priority}:${b.id}`)),
126
+ skipped_presets: activation.skipped_presets,
127
+ provider_manifest_declarations: inventory.provider_manifest_declarations || [],
128
+ summary: {
129
+ active_provider_count: activation.active_provider_presets.length,
130
+ active_team_count: activation.active_team_presets.length,
131
+ skipped_count: activation.skipped_presets.length,
132
+ missing_declared_workflow_preset_count: (inventory.provider_manifest_summary?.missing_declared_workflow_preset_count || 0)
133
+ }
134
+ };
135
+ }
136
+
137
+ export function composeWorkflowToolHints(providerPresets, teamPresets) {
138
+ const merged = {};
139
+ for (const preset of [...providerPresets, ...teamPresets]) {
140
+ for (const [toolName, value] of Object.entries(preset.tool_hints || {})) {
141
+ merged[toolName] = {
142
+ ...(merged[toolName] || {}),
143
+ ...(value && typeof value === "object" ? value : { value })
144
+ };
145
+ }
146
+ }
147
+ return merged;
148
+ }
149
+
150
+ export function buildResolvedWorkflowContextPayload({
151
+ workspace = null,
152
+ taskModeArtifact,
153
+ importPlan = null,
154
+ reviewBoundary = null,
155
+ maintainedBoundary = null,
156
+ generatorTargets = [],
157
+ providerPresets = null,
158
+ teamPresets = null,
159
+ providerManifests = null,
160
+ selectors = {}
161
+ }) {
162
+ const resolvedSelectors = {
163
+ mode: taskModeArtifact?.mode || null,
164
+ task_class: taskModeArtifact?.mode || null,
165
+ outputs: outputIdsForWorkflowContext(taskModeArtifact, maintainedBoundary),
166
+ integration_categories: integrationCategoriesForWorkflowContext(taskModeArtifact, importPlan),
167
+ query_family: "workflow",
168
+ manual_context: Boolean(importPlan?.requires_human_review?.length),
169
+ ...selectors
170
+ };
171
+ const presetInventory = buildWorkflowPresetInventory({
172
+ workspace,
173
+ providerPresets,
174
+ teamPresets,
175
+ providerManifests,
176
+ selectors: resolvedSelectors
177
+ });
178
+ const activePresets = activeWorkflowPresetsForContext({
179
+ workspace,
180
+ providerPresets,
181
+ teamPresets,
182
+ providerManifests,
183
+ selectors: resolvedSelectors
184
+ });
185
+ const providerPresetSummaries = activePresets.active_provider_presets.map((preset) => summarizeWorkflowPreset(preset, resolvedSelectors));
186
+ const teamPresetSummaries = activePresets.active_team_presets.map((preset) => summarizeWorkflowPreset(preset, resolvedSelectors));
187
+
188
+ const conflictNotes = [];
189
+ const policyNotes = [];
190
+ const appliedPresets = [];
191
+ let resolvedTaskMode = taskModeArtifact?.mode || null;
192
+ const fieldResolution = {
193
+ recommended_task_mode: [],
194
+ preferred_queries: [],
195
+ artifact_load_order: [],
196
+ review_policy: [],
197
+ verification_policy: [],
198
+ multi_agent_policy: [],
199
+ handoff_defaults: [],
200
+ tool_hints: []
201
+ };
202
+ for (const preset of [...activePresets.active_provider_presets, ...activePresets.active_team_presets]) {
203
+ if (preset.recommended_task_mode) {
204
+ fieldResolution.recommended_task_mode.push(...mergeFieldResolution([preset]));
205
+ if (CANONICAL_TASK_MODES.has(preset.recommended_task_mode)) {
206
+ if (resolvedTaskMode !== taskModeArtifact?.mode && resolvedTaskMode !== preset.recommended_task_mode) {
207
+ conflictNotes.push(`Preset ${preset.id} overrode an earlier task-mode recommendation; highest-precedence canonical task mode wins.`);
208
+ }
209
+ resolvedTaskMode = preset.recommended_task_mode;
210
+ } else {
211
+ conflictNotes.push(`Preset ${preset.id} requested unsupported task mode ${preset.recommended_task_mode}; ignoring override.`);
212
+ }
213
+ }
214
+ if (preset.write_scope || preset.ownership_boundary) {
215
+ conflictNotes.push(`Preset ${preset.id} attempted to override protected workflow boundaries; ignoring override.`);
216
+ }
217
+ appliedPresets.push({
218
+ id: preset.id,
219
+ kind: preset.kind,
220
+ source_priority: preset.source_priority,
221
+ provenance: preset.provenance || null
222
+ });
223
+ }
224
+
225
+ const coreQueries = coreWorkflowQueriesForMode(resolvedTaskMode);
226
+ const providerQueries = activePresets.active_provider_presets.flatMap((preset) => preset.preferred_queries || []);
227
+ const teamQueries = activePresets.active_team_presets.flatMap((preset) => preset.preferred_queries || []);
228
+ const preferredQueries = stableOrderedUnion([
229
+ ...teamQueries,
230
+ ...providerQueries,
231
+ ...coreQueries
232
+ ]);
233
+ fieldResolution.preferred_queries = mergeFieldResolution([
234
+ ...activePresets.active_team_presets.filter((preset) => (preset.preferred_queries || []).length > 0),
235
+ ...activePresets.active_provider_presets.filter((preset) => (preset.preferred_queries || []).length > 0)
236
+ ]);
237
+ const artifactLoadOrder = stableOrderedUnion([
238
+ ...activePresets.active_team_presets.flatMap((preset) => preset.artifact_load_order || []),
239
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.artifact_load_order || []),
240
+ ...(taskModeArtifact?.preferred_context_artifacts || []),
241
+ ...artifactLoadOrderFromGeneratorTargets(generatorTargets)
242
+ ]);
243
+ const recommendedArtifactQueries = recommendedArtifactQueriesFromGeneratorTargets(generatorTargets);
244
+ fieldResolution.artifact_load_order = mergeFieldResolution([
245
+ ...activePresets.active_team_presets.filter((preset) => (preset.artifact_load_order || []).length > 0),
246
+ ...activePresets.active_provider_presets.filter((preset) => (preset.artifact_load_order || []).length > 0)
247
+ ]);
248
+
249
+ const risk = classifyRisk({
250
+ reviewBoundary,
251
+ maintainedBoundary,
252
+ importPlan,
253
+ verificationTargets: taskModeArtifact?.verification_targets || null,
254
+ maintainedRisk: importPlan?.maintained_risk || null
255
+ });
256
+
257
+ const requiredVerification = stableOrderedUnion([
258
+ ...flattenVerificationTargets(taskModeArtifact?.verification_targets || null),
259
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.verification_policy?.required || []),
260
+ ...activePresets.active_team_presets.flatMap((preset) => preset.verification_policy?.required || [])
261
+ ]);
262
+ const recommendedVerification = stableOrderedUnion([
263
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.verification_policy?.recommended || []),
264
+ ...activePresets.active_team_presets.flatMap((preset) => preset.verification_policy?.recommended || [])
265
+ ]).filter((entry) => !requiredVerification.includes(entry));
266
+ fieldResolution.verification_policy = mergeFieldResolution([
267
+ ...activePresets.active_provider_presets.filter((preset) =>
268
+ (preset.verification_policy?.required || []).length > 0 ||
269
+ (preset.verification_policy?.recommended || []).length > 0
270
+ ),
271
+ ...activePresets.active_team_presets.filter((preset) =>
272
+ (preset.verification_policy?.required || []).length > 0 ||
273
+ (preset.verification_policy?.recommended || []).length > 0
274
+ )
275
+ ]);
276
+
277
+ const reviewBlockers = stableSortedStrings([
278
+ "no_go",
279
+ ...(risk.overall_risk === "manual_decision" || risk.overall_risk === "no_go" ? ["manual_decision"] : []),
280
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.review_policy?.block_on || []),
281
+ ...activePresets.active_team_presets.flatMap((preset) => preset.review_policy?.block_on || [])
282
+ ]);
283
+ const reviewEscalations = stableSortedStrings([
284
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.review_policy?.escalate_categories || []),
285
+ ...activePresets.active_team_presets.flatMap((preset) => preset.review_policy?.escalate_categories || [])
286
+ ]);
287
+ fieldResolution.review_policy = mergeFieldResolution([
288
+ ...activePresets.active_provider_presets.filter((preset) =>
289
+ (preset.review_policy?.block_on || []).length > 0 || (preset.review_policy?.escalate_categories || []).length > 0
290
+ ),
291
+ ...activePresets.active_team_presets.filter((preset) =>
292
+ (preset.review_policy?.block_on || []).length > 0 || (preset.review_policy?.escalate_categories || []).length > 0
293
+ )
294
+ ]);
295
+ if ((presetInventory.provider_manifest_summary?.missing_declared_workflow_preset_count || 0) > 0) {
296
+ policyNotes.push(`${presetInventory.provider_manifest_summary.missing_declared_workflow_preset_count} manifest-declared workflow preset(s) are not yet imported.`);
297
+ }
298
+ if (activePresets.skipped_presets.some((preset) => preset.reason === "inactive")) {
299
+ policyNotes.push("At least one workflow preset is present but inactive by local policy.");
300
+ }
301
+
302
+ const providerMultiAgentAllowed = activePresets.active_provider_presets.every((preset) => preset.multi_agent_policy?.allowed !== false);
303
+ const teamMultiAgentAllowed = activePresets.active_team_presets.every((preset) => preset.multi_agent_policy?.allowed !== false);
304
+ const teamDefaultStrategy = [...activePresets.active_team_presets].reverse().find((preset) => preset.multi_agent_policy?.default_strategy)?.multi_agent_policy?.default_strategy || null;
305
+ const providerDefaultStrategy = [...activePresets.active_provider_presets].reverse().find((preset) => preset.multi_agent_policy?.default_strategy)?.multi_agent_policy?.default_strategy || null;
306
+ fieldResolution.multi_agent_policy = mergeFieldResolution([
307
+ ...activePresets.active_provider_presets.filter((preset) =>
308
+ preset.multi_agent_policy?.allowed !== undefined || preset.multi_agent_policy?.default_strategy
309
+ ),
310
+ ...activePresets.active_team_presets.filter((preset) =>
311
+ preset.multi_agent_policy?.allowed !== undefined || preset.multi_agent_policy?.default_strategy
312
+ )
313
+ ]);
314
+ fieldResolution.handoff_defaults = mergeFieldResolution([
315
+ ...activePresets.active_provider_presets.filter((preset) => (preset.handoff_defaults?.required_fields || []).length > 0),
316
+ ...activePresets.active_team_presets.filter((preset) => (preset.handoff_defaults?.required_fields || []).length > 0)
317
+ ]);
318
+ fieldResolution.tool_hints = mergeFieldResolution([
319
+ ...activePresets.active_provider_presets.filter((preset) => Object.keys(preset.tool_hints || {}).length > 0),
320
+ ...activePresets.active_team_presets.filter((preset) => Object.keys(preset.tool_hints || {}).length > 0)
321
+ ]);
322
+
323
+ return {
324
+ type: "resolved_workflow_context_query",
325
+ resolved_task_mode: resolvedTaskMode,
326
+ preferred_queries: preferredQueries,
327
+ artifact_load_order: artifactLoadOrder,
328
+ recommended_artifact_queries: recommendedArtifactQueries,
329
+ effective_write_scope: taskModeArtifact?.write_scope || null,
330
+ effective_review_policy: {
331
+ block_on: reviewBlockers,
332
+ escalate_categories: reviewEscalations,
333
+ overall_risk: risk.overall_risk,
334
+ risk_reasons: risk.risk_reasons || []
335
+ },
336
+ effective_verification_policy: {
337
+ required: requiredVerification,
338
+ recommended: recommendedVerification,
339
+ output_verification_targets: taskModeArtifact?.verification_targets?.output_verification_targets || []
340
+ },
341
+ effective_multi_agent_policy: {
342
+ allowed: providerMultiAgentAllowed && teamMultiAgentAllowed,
343
+ default_strategy: teamDefaultStrategy || providerDefaultStrategy || null
344
+ },
345
+ effective_handoff_defaults: {
346
+ required_fields: stableOrderedUnion([
347
+ ...activePresets.active_provider_presets.flatMap((preset) => preset.handoff_defaults?.required_fields || []),
348
+ ...activePresets.active_team_presets.flatMap((preset) => preset.handoff_defaults?.required_fields || [])
349
+ ])
350
+ },
351
+ tool_hints: composeWorkflowToolHints(activePresets.active_provider_presets, activePresets.active_team_presets),
352
+ applied_presets: appliedPresets,
353
+ skipped_presets: activePresets.skipped_presets,
354
+ field_resolution: fieldResolution,
355
+ conflict_notes: conflictNotes,
356
+ policy_notes: policyNotes,
357
+ workflow_presets: presetInventory
358
+ };
359
+ }
360
+
361
+ export function buildSingleAgentPlanPayload({
362
+ workspace,
363
+ taskModeArtifact,
364
+ importPlan = null,
365
+ resolvedWorkflowContext = null
366
+ }) {
367
+ const primaryArtifacts = stableOrderedUnion([
368
+ ...(resolvedWorkflowContext?.artifact_load_order || []),
369
+ ...(taskModeArtifact?.preferred_context_artifacts || [])
370
+ ]);
371
+ const presetGuidanceSummary = buildPresetGuidanceSummary(importPlan?.workflow_presets || null, resolvedWorkflowContext);
372
+ return {
373
+ type: "single_agent_plan",
374
+ workspace: workspace || null,
375
+ mode: taskModeArtifact?.mode || null,
376
+ summary: taskModeArtifact?.summary || null,
377
+ current_focus: currentFocusFromTaskMode(taskModeArtifact),
378
+ next_action: taskModeArtifact?.next_action || null,
379
+ write_scope: taskModeArtifact?.write_scope || null,
380
+ review_boundaries: buildReviewBoundaries(taskModeArtifact, importPlan),
381
+ proof_targets: taskModeArtifact?.verification_targets || null,
382
+ operator_loop: buildOperatorLoopSummary({
383
+ mode: taskModeArtifact?.mode || null,
384
+ nextAction: taskModeArtifact?.next_action || null,
385
+ primaryArtifacts,
386
+ verificationTargets: taskModeArtifact?.verification_targets || null,
387
+ currentSurface: "single-agent-plan"
388
+ }),
389
+ recommended_sequence: buildRecommendedSequence(taskModeArtifact, importPlan),
390
+ blocking_conditions: buildBlockingConditions(taskModeArtifact, importPlan),
391
+ primary_artifacts: primaryArtifacts,
392
+ preset_guidance_summary: presetGuidanceSummary,
393
+ active_preset_ids: presetGuidanceSummary.active_preset_ids,
394
+ preset_blockers: presetGuidanceSummary.preset_blockers,
395
+ recommended_preset_action: presetGuidanceSummary.recommended_preset_action,
396
+ resolved_workflow_context: resolvedWorkflowContext || null
397
+ };
398
+ }