@topogram/cli 0.3.64 → 0.3.66

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 (278) hide show
  1. package/package.json +1 -1
  2. package/src/adoption/plan/index.js +716 -0
  3. package/src/adoption/plan.js +12 -703
  4. package/src/adoption/reporting.js +1 -1
  5. package/src/agent-brief.js +7 -21
  6. package/src/agent-ops/query-builders/auth.js +375 -0
  7. package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
  8. package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
  9. package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
  10. package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
  11. package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
  12. package/src/agent-ops/query-builders/change-risk.js +25 -0
  13. package/src/agent-ops/query-builders/common.js +149 -0
  14. package/src/agent-ops/query-builders/maintained-risk.js +539 -0
  15. package/src/agent-ops/query-builders/maintained-shared.js +120 -0
  16. package/src/agent-ops/query-builders/multi-agent.js +547 -0
  17. package/src/agent-ops/query-builders/projection-impacts.js +514 -0
  18. package/src/agent-ops/query-builders/work-packets.js +417 -0
  19. package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
  20. package/src/agent-ops/query-builders/workflow-context.js +398 -0
  21. package/src/agent-ops/query-builders/workflow-presets-core.js +677 -0
  22. package/src/agent-ops/query-builders/workflow-presets.js +341 -0
  23. package/src/agent-ops/query-builders.d.ts +26 -26
  24. package/src/agent-ops/query-builders.js +42 -5021
  25. package/src/archive/jsonl.js +2 -2
  26. package/src/archive/resolver-bridge.js +1 -1
  27. package/src/archive/unarchive.js +2 -1
  28. package/src/catalog/constants.js +10 -0
  29. package/src/catalog/copy.js +65 -0
  30. package/src/catalog/diagnostics.js +15 -0
  31. package/src/catalog/entries.js +42 -0
  32. package/src/catalog/files.js +67 -0
  33. package/src/catalog/provenance.js +123 -0
  34. package/src/catalog/source.js +150 -0
  35. package/src/catalog/validation.js +252 -0
  36. package/src/catalog.d.ts +2 -0
  37. package/src/catalog.js +18 -746
  38. package/src/cli/command-parsers/project.js +3 -0
  39. package/src/cli/command-parsers/shared.js +1 -1
  40. package/src/cli/commands/agent.js +2 -2
  41. package/src/cli/commands/catalog/check.js +31 -0
  42. package/src/cli/commands/catalog/copy.js +59 -0
  43. package/src/cli/commands/catalog/doctor.js +248 -0
  44. package/src/cli/commands/catalog/help.js +21 -0
  45. package/src/cli/commands/catalog/list.js +52 -0
  46. package/src/cli/commands/catalog/runner.js +92 -0
  47. package/src/cli/commands/catalog/shared.js +17 -0
  48. package/src/cli/commands/catalog/show.js +134 -0
  49. package/src/cli/commands/catalog.js +30 -615
  50. package/src/cli/commands/check.js +3 -3
  51. package/src/cli/commands/doctor.js +2 -9
  52. package/src/cli/commands/generator-policy/package-info.js +162 -0
  53. package/src/cli/commands/generator-policy/payloads.js +372 -0
  54. package/src/cli/commands/generator-policy/printers.js +159 -0
  55. package/src/cli/commands/generator-policy/runner.js +81 -0
  56. package/src/cli/commands/generator-policy/shared.js +39 -0
  57. package/src/cli/commands/generator-policy.js +15 -783
  58. package/src/cli/commands/import/adopt.js +170 -0
  59. package/src/cli/commands/import/check.js +91 -0
  60. package/src/cli/commands/import/diff.js +84 -0
  61. package/src/cli/commands/import/help.js +47 -0
  62. package/src/cli/commands/import/paths.js +269 -0
  63. package/src/cli/commands/import/plan.js +292 -0
  64. package/src/cli/commands/import/refresh.js +471 -0
  65. package/src/cli/commands/import/status-history.js +196 -0
  66. package/src/cli/commands/import/workspace.js +233 -0
  67. package/src/cli/commands/import.js +33 -1732
  68. package/src/cli/commands/migrate.js +153 -0
  69. package/src/cli/commands/package/constants.js +17 -0
  70. package/src/cli/commands/package/doctor.js +240 -0
  71. package/src/cli/commands/package/help.js +27 -0
  72. package/src/cli/commands/package/lockfile.js +135 -0
  73. package/src/cli/commands/package/npm.js +97 -0
  74. package/src/cli/commands/package/reporting.js +35 -0
  75. package/src/cli/commands/package/runner.js +33 -0
  76. package/src/cli/commands/package/shared.js +9 -0
  77. package/src/cli/commands/package/update-cli.js +252 -0
  78. package/src/cli/commands/package/versions.js +35 -0
  79. package/src/cli/commands/package.js +29 -813
  80. package/src/cli/commands/query/change-plan.js +68 -0
  81. package/src/cli/commands/query/definitions.js +202 -0
  82. package/src/cli/commands/query/import-adopt.js +121 -0
  83. package/src/cli/commands/query/runner/artifacts.js +102 -0
  84. package/src/cli/commands/query/runner/boundaries.js +211 -0
  85. package/src/cli/commands/query/runner/change.js +182 -0
  86. package/src/cli/commands/query/runner/import-adopt.js +111 -0
  87. package/src/cli/commands/query/runner/index.js +31 -0
  88. package/src/cli/commands/query/runner/output.js +12 -0
  89. package/src/cli/commands/query/runner/workflow.js +241 -0
  90. package/src/cli/commands/query/runner.js +3 -0
  91. package/src/cli/commands/query/workflow-context.js +5 -0
  92. package/src/cli/commands/query/workspace.js +270 -0
  93. package/src/cli/commands/query.js +9 -1300
  94. package/src/cli/commands/source.js +3 -12
  95. package/src/cli/commands/template/baseline.js +100 -0
  96. package/src/cli/commands/template/check.js +467 -0
  97. package/src/cli/commands/template/constants.js +8 -0
  98. package/src/cli/commands/template/diagnostics.js +26 -0
  99. package/src/cli/commands/template/help.js +28 -0
  100. package/src/cli/commands/template/lifecycle.js +404 -0
  101. package/src/cli/commands/template/list-show.js +287 -0
  102. package/src/cli/commands/template/policy.js +422 -0
  103. package/src/cli/commands/template/shared.js +127 -0
  104. package/src/cli/commands/template/updates.js +352 -0
  105. package/src/cli/commands/template-runner.js +6 -6
  106. package/src/cli/commands/template.js +41 -2143
  107. package/src/cli/commands/trust.js +1 -1
  108. package/src/cli/commands/workflow.js +6 -1
  109. package/src/cli/dispatcher.js +6 -1
  110. package/src/cli/help.js +15 -14
  111. package/src/cli/migration-guidance.js +1 -1
  112. package/src/cli/output-safety.js +2 -1
  113. package/src/cli/path-normalization.js +3 -13
  114. package/src/generator/api/contracts.js +497 -0
  115. package/src/generator/api/metadata.js +221 -0
  116. package/src/generator/api/openapi.js +559 -0
  117. package/src/generator/api/schema.js +124 -0
  118. package/src/generator/api/types.d.ts +98 -0
  119. package/src/generator/api.js +3 -1195
  120. package/src/generator/context/domain-page.js +1 -1
  121. package/src/generator/context/shared/domain-sdlc.js +282 -0
  122. package/src/generator/context/shared/maintained-boundary.js +665 -0
  123. package/src/generator/context/shared/metrics.js +85 -0
  124. package/src/generator/context/shared/primitives.js +64 -0
  125. package/src/generator/context/shared/relationships.js +453 -0
  126. package/src/generator/context/shared/summaries.js +263 -0
  127. package/src/generator/context/shared/types.d.ts +207 -0
  128. package/src/generator/context/shared.d.ts +42 -0
  129. package/src/generator/context/shared.js +80 -1390
  130. package/src/generator/context/slice/core.js +397 -0
  131. package/src/generator/context/slice/sdlc.js +417 -0
  132. package/src/generator/context/slice/ui-packets.js +183 -0
  133. package/src/generator/context/slice.js +2 -859
  134. package/src/generator/context/task-mode.js +2 -2
  135. package/src/generator/registry/index.js +507 -0
  136. package/src/generator/registry.js +18 -504
  137. package/src/generator/runtime/environment/index.js +666 -0
  138. package/src/generator/runtime/environment.js +4 -666
  139. package/src/generator/runtime/runtime-check/index.js +554 -0
  140. package/src/generator/runtime/runtime-check.js +4 -554
  141. package/src/generator/runtime/shared/index.js +572 -0
  142. package/src/generator/runtime/shared.js +19 -570
  143. package/src/generator/sdlc/doc-page.js +1 -1
  144. package/src/generator/shared.d.ts +2 -0
  145. package/src/generator/surfaces/databases/lifecycle-shared.js +1 -1
  146. package/src/generator/surfaces/native/swiftui-templates/README.generated.md +1 -1
  147. package/src/generator/surfaces/shared.d.ts +3 -0
  148. package/src/generator/widget-conformance/behavior-report.js +258 -0
  149. package/src/generator/widget-conformance/checks.js +371 -0
  150. package/src/generator/widget-conformance/projection-context.js +200 -0
  151. package/src/generator/widget-conformance/report.js +166 -0
  152. package/src/generator/widget-conformance/types.d.ts +121 -0
  153. package/src/generator/widget-conformance.js +3 -824
  154. package/src/import/core/context.d.ts +3 -0
  155. package/src/import/core/context.js +5 -7
  156. package/src/import/core/contracts.d.ts +1 -0
  157. package/src/import/core/registry.d.ts +4 -0
  158. package/src/import/core/runner/candidates.js +337 -0
  159. package/src/import/core/runner/options.js +22 -0
  160. package/src/import/core/runner/reports.js +51 -0
  161. package/src/import/core/runner/run.js +79 -0
  162. package/src/import/core/runner/tracks.js +150 -0
  163. package/src/import/core/runner/ui-drafts.js +393 -0
  164. package/src/import/core/runner.js +3 -698
  165. package/src/import/core/shared/api-routes.js +221 -0
  166. package/src/import/core/shared/candidates.js +97 -0
  167. package/src/import/core/shared/files.js +177 -0
  168. package/src/import/core/shared/next-app.js +389 -0
  169. package/src/import/core/shared/types.d.ts +51 -0
  170. package/src/import/core/shared/ui-routes.js +230 -0
  171. package/src/import/core/shared.js +60 -861
  172. package/src/new-project/constants.js +128 -0
  173. package/src/new-project/create.js +90 -0
  174. package/src/new-project/json.js +28 -0
  175. package/src/new-project/metadata.js +96 -0
  176. package/src/new-project/package-spec.js +161 -0
  177. package/src/new-project/project-files.js +351 -0
  178. package/src/new-project/template-policy.js +269 -0
  179. package/src/new-project/template-resolution.js +370 -0
  180. package/src/new-project/template-snapshots.js +442 -0
  181. package/src/new-project/template-updates.js +512 -0
  182. package/src/new-project/types.d.ts +83 -0
  183. package/src/new-project.js +6 -2277
  184. package/src/parser.d.ts +87 -1
  185. package/src/parser.js +118 -0
  186. package/src/policy/review-boundaries.d.ts +15 -0
  187. package/src/project-config/index.js +591 -0
  188. package/src/project-config.js +19 -561
  189. package/src/resolver/enrich/acceptance-criterion.js +2 -0
  190. package/src/resolver/enrich/bug.js +2 -0
  191. package/src/resolver/enrich/pitch.js +2 -0
  192. package/src/resolver/enrich/requirement.js +2 -0
  193. package/src/resolver/enrich/task.js +2 -0
  194. package/src/resolver/index.js +19 -2089
  195. package/src/resolver/normalize.js +384 -1
  196. package/src/resolver/plans.js +168 -0
  197. package/src/resolver/projections-api.js +494 -0
  198. package/src/resolver/projections-db.js +133 -0
  199. package/src/resolver/projections-ui.js +317 -0
  200. package/src/resolver/shapes.js +251 -0
  201. package/src/resolver/shared.js +278 -0
  202. package/src/resolver/widgets.js +132 -0
  203. package/src/sdlc/adopt.js +6 -5
  204. package/src/sdlc/paths.js +3 -5
  205. package/src/sdlc/scaffold.js +2 -1
  206. package/src/template-trust/constants.js +62 -0
  207. package/src/template-trust/content.js +258 -0
  208. package/src/template-trust/diff.js +92 -0
  209. package/src/template-trust/policy.js +61 -0
  210. package/src/template-trust/record.js +90 -0
  211. package/src/template-trust/status.js +182 -0
  212. package/src/template-trust.js +24 -687
  213. package/src/text-helpers.d.ts +1 -0
  214. package/src/topogram-types.d.ts +69 -0
  215. package/src/validator/common.js +488 -0
  216. package/src/validator/data-model.js +237 -0
  217. package/src/validator/docs.js +167 -0
  218. package/src/validator/expressions.js +146 -1
  219. package/src/validator/index.d.ts +23 -0
  220. package/src/validator/index.js +32 -3585
  221. package/src/validator/kinds.d.ts +41 -0
  222. package/src/validator/kinds.js +2 -0
  223. package/src/validator/model-helpers.js +46 -0
  224. package/src/validator/per-kind/acceptance-criterion.js +5 -0
  225. package/src/validator/per-kind/bug.js +6 -0
  226. package/src/validator/per-kind/domain.js +15 -2
  227. package/src/validator/per-kind/pitch.js +7 -0
  228. package/src/validator/per-kind/requirement.js +5 -0
  229. package/src/validator/per-kind/task.js +7 -0
  230. package/src/validator/per-kind/widget.js +14 -0
  231. package/src/validator/projections/api-http-async.js +410 -0
  232. package/src/validator/projections/api-http-authz.js +88 -0
  233. package/src/validator/projections/api-http-core.js +205 -0
  234. package/src/validator/projections/api-http-policies.js +339 -0
  235. package/src/validator/projections/api-http-responses.js +233 -0
  236. package/src/validator/projections/api-http.js +44 -0
  237. package/src/validator/projections/db.js +353 -0
  238. package/src/validator/projections/generator-defaults.js +45 -0
  239. package/src/validator/projections/helpers.js +87 -0
  240. package/src/validator/projections/ui-helpers.js +214 -0
  241. package/src/validator/projections/ui-navigation.js +344 -0
  242. package/src/validator/projections/ui-structure.js +364 -0
  243. package/src/validator/projections/ui-widgets.js +493 -0
  244. package/src/validator/projections/ui.js +46 -0
  245. package/src/validator/registry.js +48 -1
  246. package/src/validator/utils.d.ts +20 -0
  247. package/src/validator/utils.js +115 -12
  248. package/src/widget-behavior.d.ts +1 -0
  249. package/src/workflows/import-app/api/collect.js +221 -0
  250. package/src/workflows/import-app/api/openapi.js +257 -0
  251. package/src/workflows/import-app/api/routes.js +327 -0
  252. package/src/workflows/import-app/api/sources.js +22 -0
  253. package/src/workflows/import-app/api.js +2 -797
  254. package/src/workflows/reconcile/adoption-plan/build.js +212 -0
  255. package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
  256. package/src/workflows/reconcile/adoption-plan/outputs.js +153 -0
  257. package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
  258. package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
  259. package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
  260. package/src/workflows/reconcile/adoption-plan.js +30 -740
  261. package/src/workflows/reconcile/auth/closures.js +115 -0
  262. package/src/workflows/reconcile/auth/formatters.js +142 -0
  263. package/src/workflows/reconcile/auth/inference.js +330 -0
  264. package/src/workflows/reconcile/auth/roles.js +122 -0
  265. package/src/workflows/reconcile/auth.js +35 -690
  266. package/src/workflows/reconcile/bundle-core/index.js +600 -0
  267. package/src/workflows/reconcile/bundle-core.js +12 -598
  268. package/src/workflows/reconcile/candidate-model.js +18 -2
  269. package/src/workflows/reconcile/canonical-surface.js +1 -1
  270. package/src/workflows/reconcile/impacts/adoption-plan.js +196 -0
  271. package/src/workflows/reconcile/impacts/indexes.js +105 -0
  272. package/src/workflows/reconcile/impacts/patches.js +252 -0
  273. package/src/workflows/reconcile/impacts/reports.js +80 -0
  274. package/src/workflows/reconcile/impacts.js +14 -623
  275. package/src/workflows/reconcile/renderers.js +41 -6
  276. package/src/workflows/shared.js +5 -11
  277. package/src/workspace-docs.d.ts +29 -0
  278. package/src/workspace-paths.js +328 -0
@@ -0,0 +1,241 @@
1
+ // @ts-check
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+
6
+ import { stableStringify } from "../../../../format.js";
7
+ import { parsePath } from "../../../../parser.js";
8
+ import { resolveWorkspace } from "../../../../resolver.js";
9
+ import {
10
+ buildImportPlanPayload,
11
+ buildResolvedWorkflowContextPayload,
12
+ buildSingleAgentPlanPayload,
13
+ buildWorkflowPresetActivationPayload,
14
+ buildWorkflowPresetCustomizationPayload,
15
+ buildWorkflowPresetDiffPayload,
16
+ buildWorkflowPresetState
17
+ } from "../../../../agent-ops/query-builders.js";
18
+ import {
19
+ adoptionPlanPath,
20
+ artifactOrNull,
21
+ buildMaintainedBundle,
22
+ buildSlice,
23
+ buildTaskMode,
24
+ generatorTargetsForWorkflowContext,
25
+ hasSelectors,
26
+ normalizeTopogramPath,
27
+ printValidationFailure,
28
+ readJson,
29
+ resultOk,
30
+ selectorOptions,
31
+ workflowPresetSelectors
32
+ } from "../workspace.js";
33
+ import { resolveRecommendedQueryFamily } from "../workflow-context.js";
34
+ import { printJson } from "./output.js";
35
+
36
+ /**
37
+ * @typedef {Record<string, any>} AnyRecord
38
+ */
39
+
40
+ /**
41
+ * @param {AnyRecord} context
42
+ * @returns {number|null}
43
+ */
44
+ export function runWorkflowQuery(context) {
45
+ const queryName = context.commandArgs?.queryName;
46
+ const selectors = selectorOptions(context);
47
+
48
+ if (queryName === "next-action") {
49
+ const result = buildTaskMode(parsePath(context.inputPath), selectors, context.modeId || "import-adopt", context.fromTopogramPath);
50
+ if (!resultOk(result)) return printValidationFailure(result);
51
+ return printJson({
52
+ type: "next_action_query",
53
+ mode: result.artifact.mode,
54
+ summary: result.artifact.summary || null,
55
+ next_action: result.artifact.next_action || null,
56
+ recommended_query_family: resolveRecommendedQueryFamily(result.artifact.next_action || null, result.artifact.mode),
57
+ immediate_artifacts: (result.artifact.preferred_context_artifacts || []).slice(0, 2),
58
+ preferred_context_artifacts: result.artifact.preferred_context_artifacts || [],
59
+ review_emphasis: result.artifact.review_emphasis || [],
60
+ write_scope: result.artifact.write_scope || null,
61
+ verification_targets: result.artifact.verification_targets || null
62
+ });
63
+ }
64
+
65
+ if (queryName === "single-agent-plan") {
66
+ return runSingleAgentPlan(context, selectors);
67
+ }
68
+
69
+ if (queryName === "resolved-workflow-context") {
70
+ return runResolvedWorkflowContext(context, selectors);
71
+ }
72
+
73
+ if (queryName === "workflow-preset-activation") {
74
+ if (!context.modeId) {
75
+ throw new Error("query workflow-preset-activation requires --mode <modeling|maintained-app-edit|import-adopt|diff-review|verification>.");
76
+ }
77
+ const topogramRoot = normalizeTopogramPath(context.inputPath);
78
+ const taskModeResult = buildTaskMode(parsePath(context.inputPath), selectors, context.modeId, context.fromTopogramPath);
79
+ if (!resultOk(taskModeResult)) return printValidationFailure(taskModeResult);
80
+ let importPlan = null;
81
+ if (context.modeId === "import-adopt" && fs.existsSync(adoptionPlanPath(topogramRoot))) {
82
+ const workflowPresets = buildWorkflowPresetState({
83
+ workspace: topogramRoot,
84
+ selectors: workflowPresetSelectors(taskModeResult.artifact, context.providerId, context.presetId, "workflow-preset-activation")
85
+ });
86
+ importPlan = buildImportPlanPayload(readJson(adoptionPlanPath(topogramRoot)), taskModeResult.artifact, null, workflowPresets);
87
+ }
88
+ return printJson(buildWorkflowPresetActivationPayload({
89
+ workspace: topogramRoot,
90
+ taskModeArtifact: taskModeResult.artifact,
91
+ importPlan,
92
+ selectors: workflowPresetSelectors(taskModeResult.artifact, context.providerId, context.presetId, "workflow-preset-activation")
93
+ }));
94
+ }
95
+
96
+ if (queryName === "workflow-preset-diff") {
97
+ if (!context.providerId) {
98
+ throw new Error("query workflow-preset-diff requires --provider <id>.");
99
+ }
100
+ return printJson(buildWorkflowPresetDiffPayload({
101
+ workspace: normalizeTopogramPath(context.inputPath),
102
+ providerId: context.providerId,
103
+ presetId: context.presetId
104
+ }));
105
+ }
106
+
107
+ if (queryName === "workflow-preset-customization" || context.commandArgs?.workflowPresetCommand === "customize") {
108
+ return runWorkflowPresetCustomization(context, queryName);
109
+ }
110
+
111
+ return null;
112
+ }
113
+
114
+ /**
115
+ * @param {AnyRecord} context
116
+ * @param {AnyRecord} selectors
117
+ * @returns {number}
118
+ */
119
+ function runSingleAgentPlan(context, selectors) {
120
+ if (!context.modeId) {
121
+ throw new Error("query single-agent-plan requires --mode <modeling|maintained-app-edit|import-adopt|diff-review|verification>.");
122
+ }
123
+ const ast = parsePath(context.inputPath);
124
+ const result = buildTaskMode(ast, selectors, context.modeId, context.fromTopogramPath);
125
+ if (!resultOk(result)) return printValidationFailure(result);
126
+ const sliceResult = hasSelectors(context) ? buildSlice(ast, selectors) : null;
127
+ if (sliceResult && !resultOk(sliceResult)) return printValidationFailure(sliceResult);
128
+ const resolved = resolveWorkspace(ast);
129
+ if (!resultOk(resolved)) return printValidationFailure(resolved);
130
+ const generatorTargets = generatorTargetsForWorkflowContext({
131
+ graph: resolved.graph,
132
+ taskModeArtifact: result.artifact,
133
+ sliceArtifact: artifactOrNull(sliceResult)
134
+ });
135
+ const topogramRoot = normalizeTopogramPath(context.inputPath);
136
+ let importPlan = null;
137
+ if (context.modeId === "import-adopt" && fs.existsSync(adoptionPlanPath(topogramRoot))) {
138
+ const workflowPresets = buildWorkflowPresetState({
139
+ workspace: topogramRoot,
140
+ selectors: workflowPresetSelectors(result.artifact, context.providerId, context.presetId, "single-agent-plan")
141
+ });
142
+ importPlan = buildImportPlanPayload(readJson(adoptionPlanPath(topogramRoot)), result.artifact, null, workflowPresets);
143
+ }
144
+ const resolvedWorkflowContext = buildResolvedWorkflowContextPayload({
145
+ workspace: topogramRoot,
146
+ taskModeArtifact: result.artifact,
147
+ generatorTargets,
148
+ selectors: workflowPresetSelectors(result.artifact, context.providerId, context.presetId, "single-agent-plan"),
149
+ importPlan
150
+ });
151
+ return printJson(buildSingleAgentPlanPayload({
152
+ workspace: topogramRoot,
153
+ taskModeArtifact: result.artifact,
154
+ importPlan,
155
+ resolvedWorkflowContext
156
+ }));
157
+ }
158
+
159
+ /**
160
+ * @param {AnyRecord} context
161
+ * @param {AnyRecord} selectors
162
+ * @returns {number}
163
+ */
164
+ function runResolvedWorkflowContext(context, selectors) {
165
+ if (!context.modeId) {
166
+ throw new Error("query resolved-workflow-context requires --mode <modeling|maintained-app-edit|import-adopt|diff-review|verification>.");
167
+ }
168
+ const topogramRoot = normalizeTopogramPath(context.inputPath);
169
+ const ast = parsePath(context.inputPath);
170
+ const taskModeResult = buildTaskMode(ast, selectors, context.modeId, context.fromTopogramPath);
171
+ if (!resultOk(taskModeResult)) return printValidationFailure(taskModeResult);
172
+ const resolved = resolveWorkspace(ast);
173
+ if (!resultOk(resolved)) return printValidationFailure(resolved);
174
+ const sliceResult = hasSelectors(context) ? buildSlice(ast, selectors) : null;
175
+ if (sliceResult && !resultOk(sliceResult)) return printValidationFailure(sliceResult);
176
+ const includeMaintainedBoundary =
177
+ context.modeId === "maintained-app-edit" ||
178
+ context.surfaceId === "maintained-boundary" ||
179
+ context.fromTopogramPath;
180
+ const maintainedBundleResult = includeMaintainedBoundary ? buildMaintainedBundle(ast) : null;
181
+ if (maintainedBundleResult && !resultOk(maintainedBundleResult)) return printValidationFailure(maintainedBundleResult);
182
+ const generatorTargets = generatorTargetsForWorkflowContext({
183
+ graph: resolved.graph,
184
+ taskModeArtifact: taskModeResult.artifact,
185
+ sliceArtifact: artifactOrNull(sliceResult),
186
+ maintainedBoundaryArtifact: maintainedBundleResult?.artifact?.maintained_boundary || null
187
+ });
188
+ let importPlan = null;
189
+ if (context.modeId === "import-adopt" && fs.existsSync(adoptionPlanPath(topogramRoot))) {
190
+ const workflowPresets = buildWorkflowPresetState({
191
+ workspace: topogramRoot,
192
+ selectors: workflowPresetSelectors(taskModeResult.artifact, context.providerId, context.presetId, "resolved-workflow-context")
193
+ });
194
+ importPlan = buildImportPlanPayload(
195
+ readJson(adoptionPlanPath(topogramRoot)),
196
+ taskModeResult.artifact,
197
+ maintainedBundleResult?.artifact?.maintained_boundary || null,
198
+ workflowPresets
199
+ );
200
+ }
201
+ return printJson(buildResolvedWorkflowContextPayload({
202
+ workspace: topogramRoot,
203
+ taskModeArtifact: taskModeResult.artifact,
204
+ importPlan,
205
+ reviewBoundary: sliceResult?.artifact?.review_boundary || null,
206
+ maintainedBoundary: maintainedBundleResult?.artifact?.maintained_boundary || null,
207
+ generatorTargets,
208
+ selectors: workflowPresetSelectors(taskModeResult.artifact, context.providerId, context.presetId, "resolved-workflow-context")
209
+ }));
210
+ }
211
+
212
+ /**
213
+ * @param {AnyRecord} context
214
+ * @param {string|undefined} queryName
215
+ * @returns {number}
216
+ */
217
+ function runWorkflowPresetCustomization(context, queryName) {
218
+ if (!context.providerId || !context.presetId) {
219
+ throw new Error(`${queryName ? "query workflow-preset-customization" : "workflow-preset customize"} requires --provider <id> and --preset <id>.`);
220
+ }
221
+ const topogramRoot = normalizeTopogramPath(context.inputPath);
222
+ const payload = buildWorkflowPresetCustomizationPayload({
223
+ workspace: topogramRoot,
224
+ providerId: context.providerId,
225
+ presetId: context.presetId
226
+ });
227
+ if (queryName === "workflow-preset-customization" || !context.shouldWrite) {
228
+ return printJson(payload);
229
+ }
230
+ const targetPath = path.resolve(topogramRoot, context.outPath || payload.recommended_local_path);
231
+ if (fs.existsSync(targetPath)) {
232
+ throw new Error(`Refusing to overwrite existing workflow preset customization at '${targetPath}'.`);
233
+ }
234
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
235
+ fs.writeFileSync(targetPath, `${stableStringify(payload.customization_template)}\n`);
236
+ return printJson({
237
+ ...payload,
238
+ written: true,
239
+ written_path: targetPath
240
+ });
241
+ }
@@ -0,0 +1,3 @@
1
+ // @ts-check
2
+
3
+ export { runQueryCommand } from "./runner/index.js";
@@ -0,0 +1,5 @@
1
+ // @ts-check
2
+
3
+ export { resolveRecommendedQueryFamily } from "./workspace.js";
4
+
5
+
@@ -0,0 +1,270 @@
1
+ // @ts-check
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+
6
+ import { generateWorkspace } from "../../../generator.js";
7
+ import { formatValidationErrors } from "../../../validator.js";
8
+ import { buildChangePlanPayload } from "../../../agent-ops/query-builders.js";
9
+ import { resolveTopoRoot } from "../../../workspace-paths.js";
10
+
11
+ /**
12
+ * @typedef {Record<string, any>} AnyRecord
13
+ */
14
+
15
+ /**
16
+ * @param {string} inputPath
17
+ * @returns {string}
18
+ */
19
+ export function normalizeTopogramPath(inputPath) {
20
+ return resolveTopoRoot(inputPath);
21
+ }
22
+
23
+ /**
24
+ * @param {AnyRecord} taskModeArtifact
25
+ * @param {string|null} providerId
26
+ * @param {string|null} presetId
27
+ * @param {string|null} queryFamily
28
+ * @returns {AnyRecord}
29
+ */
30
+ export function workflowPresetSelectors(taskModeArtifact, providerId = null, presetId = null, queryFamily = null) {
31
+ const categories = [];
32
+ if (taskModeArtifact?.mode === "import-adopt") categories.push("provider_adoption");
33
+ if (taskModeArtifact?.mode === "maintained-app-edit") categories.push("maintained_app");
34
+ if ((taskModeArtifact?.verification_targets?.maintained_app_checks || []).length > 0) categories.push("maintained_boundary");
35
+ return {
36
+ mode: taskModeArtifact?.mode || null,
37
+ task_class: taskModeArtifact?.mode || null,
38
+ provider_id: providerId,
39
+ preset_id: presetId,
40
+ query_family: queryFamily,
41
+ integration_categories: categories
42
+ };
43
+ }
44
+
45
+ /**
46
+ * @param {AnyRecord} options
47
+ * @returns {AnyRecord[]}
48
+ */
49
+ export function generatorTargetsForWorkflowContext(options = {}) {
50
+ const { graph, taskModeArtifact, sliceArtifact = null, diffArtifact = null, maintainedBoundaryArtifact = null } = options;
51
+ if (!graph || !taskModeArtifact) {
52
+ return [];
53
+ }
54
+ return buildChangePlanPayload({
55
+ graph,
56
+ taskModeArtifact,
57
+ sliceArtifact,
58
+ diffArtifact,
59
+ maintainedBoundaryArtifact
60
+ }).generator_targets || [];
61
+ }
62
+
63
+ /**
64
+ * @param {AnyRecord} options
65
+ * @returns {boolean}
66
+ */
67
+ export function importAdoptOnlyRequested(options = {}) {
68
+ return options.modeId === "import-adopt" && !(
69
+ options.capabilityId ||
70
+ options.workflowId ||
71
+ options.projectionId ||
72
+ options.componentId ||
73
+ options.entityId ||
74
+ options.journeyId ||
75
+ options.surfaceId ||
76
+ options.domainId ||
77
+ options.fromTopogramPath
78
+ );
79
+ }
80
+
81
+ /**
82
+ * @param {AnyRecord} result
83
+ * @returns {boolean}
84
+ */
85
+ export function resultOk(result) {
86
+ return Boolean(result?.ok);
87
+ }
88
+
89
+ /**
90
+ * @param {AnyRecord} result
91
+ * @returns {number}
92
+ */
93
+ export function printValidationFailure(result) {
94
+ console.error(formatValidationErrors(result.validation));
95
+ return 1;
96
+ }
97
+
98
+ /**
99
+ * @param {AnyRecord} ast
100
+ * @param {AnyRecord} selectors
101
+ * @param {string} modeId
102
+ * @param {string|null} fromTopogramPath
103
+ * @returns {AnyRecord}
104
+ */
105
+ export function buildTaskMode(ast, selectors, modeId, fromTopogramPath = null) {
106
+ return generateWorkspace(ast, {
107
+ target: "context-task-mode",
108
+ modeId,
109
+ ...selectors,
110
+ widgetId: selectors.componentId,
111
+ fromTopogramPath
112
+ });
113
+ }
114
+
115
+ /**
116
+ * @param {AnyRecord} ast
117
+ * @param {AnyRecord} selectors
118
+ * @returns {AnyRecord}
119
+ */
120
+ export function buildSlice(ast, selectors) {
121
+ return generateWorkspace(ast, {
122
+ target: "context-slice",
123
+ ...selectors,
124
+ widgetId: selectors.componentId
125
+ });
126
+ }
127
+
128
+ /**
129
+ * @param {AnyRecord} ast
130
+ * @returns {AnyRecord}
131
+ */
132
+ export function buildMaintainedBundle(ast) {
133
+ return generateWorkspace(ast, {
134
+ target: "context-bundle",
135
+ taskId: "maintained-app"
136
+ });
137
+ }
138
+
139
+ /**
140
+ * @param {AnyRecord} ast
141
+ * @param {string|null} fromTopogramPath
142
+ * @returns {AnyRecord|null}
143
+ */
144
+ export function buildDiff(ast, fromTopogramPath) {
145
+ return fromTopogramPath
146
+ ? generateWorkspace(ast, {
147
+ target: "context-diff",
148
+ fromTopogramPath
149
+ })
150
+ : null;
151
+ }
152
+
153
+ /**
154
+ * @param {AnyRecord|null} result
155
+ * @returns {AnyRecord|null}
156
+ */
157
+ export function artifactOrNull(result) {
158
+ return result?.artifact || null;
159
+ }
160
+
161
+ /**
162
+ * @param {string} topogramRoot
163
+ * @returns {string}
164
+ */
165
+ export function adoptionPlanPath(topogramRoot) {
166
+ return path.join(topogramRoot, "candidates", "reconcile", "adoption-plan.agent.json");
167
+ }
168
+
169
+ /**
170
+ * @param {string} topogramRoot
171
+ * @param {string} label
172
+ * @returns {{ reportPath: string, adoptionStatusPath: string, adoptionPlanPath: string }}
173
+ */
174
+ export function requireReconcileArtifacts(topogramRoot, label) {
175
+ const reportPath = path.join(topogramRoot, "candidates", "reconcile", "report.json");
176
+ const adoptionStatusPath = path.join(topogramRoot, "candidates", "reconcile", "adoption-status.json");
177
+ const planPath = adoptionPlanPath(topogramRoot);
178
+ if (!fs.existsSync(reportPath) || !fs.existsSync(adoptionStatusPath) || !fs.existsSync(planPath)) {
179
+ throw new Error(`No reconcile ${label} artifacts found under '${path.join(topogramRoot, "candidates", "reconcile")}'. Run 'node ./src/cli.js reconcile ${topogramRoot}' first.`);
180
+ }
181
+ return { reportPath, adoptionStatusPath, adoptionPlanPath: planPath };
182
+ }
183
+
184
+ /**
185
+ * @param {string} filePath
186
+ * @returns {AnyRecord}
187
+ */
188
+ export function readJson(filePath) {
189
+ return JSON.parse(fs.readFileSync(filePath, "utf8"));
190
+ }
191
+
192
+ /**
193
+ * @param {AnyRecord} options
194
+ * @returns {boolean}
195
+ */
196
+ export function hasSelectors(options) {
197
+ return Boolean(
198
+ options.capabilityId ||
199
+ options.workflowId ||
200
+ options.projectionId ||
201
+ options.componentId ||
202
+ options.entityId ||
203
+ options.journeyId ||
204
+ options.surfaceId ||
205
+ options.domainId
206
+ );
207
+ }
208
+
209
+ /**
210
+ * @param {AnyRecord} options
211
+ * @returns {boolean}
212
+ */
213
+ export function shouldUseImportAdoptPath(options) {
214
+ const selectorOrDiff = hasSelectors(options) || Boolean(options.fromTopogramPath);
215
+ return importAdoptOnlyRequested(options) || (!selectorOrDiff && !options.modeId);
216
+ }
217
+
218
+ /**
219
+ * @param {AnyRecord} options
220
+ * @returns {AnyRecord}
221
+ */
222
+ export function selectorOptions(options) {
223
+ return {
224
+ capabilityId: options.capabilityId,
225
+ workflowId: options.workflowId,
226
+ projectionId: options.projectionId,
227
+ componentId: options.componentId,
228
+ entityId: options.entityId,
229
+ journeyId: options.journeyId,
230
+ surfaceId: options.surfaceId,
231
+ domainId: options.domainId
232
+ };
233
+ }
234
+
235
+ /**
236
+ * @param {AnyRecord} nextAction
237
+ * @param {string|null} mode
238
+ * @returns {string}
239
+ */
240
+ export function resolveRecommendedQueryFamily(nextAction, mode) {
241
+ switch (nextAction?.kind) {
242
+ case "review_staged":
243
+ case "review_bundle":
244
+ case "inspect_review_group":
245
+ case "inspect_proposal_surface":
246
+ case "customize_workflow_preset":
247
+ case "refresh_workflow_preset_customization":
248
+ case "import_declared_workflow_preset":
249
+ return "import-plan";
250
+ case "review_diff_impact":
251
+ case "inspect_projection":
252
+ case "inspect_diff":
253
+ case "review_diff_boundaries":
254
+ return "change-plan";
255
+ case "inspect_maintained_impact":
256
+ case "inspect_boundary_before_edit":
257
+ case "run_maintained_checks":
258
+ return "maintained-boundary";
259
+ case "inspect_verification_targets":
260
+ return "verification-targets";
261
+ case "inspect_workspace_digest":
262
+ return "single-agent-plan";
263
+ default:
264
+ break;
265
+ }
266
+ if (mode === "import-adopt") return "import-plan";
267
+ if (mode === "maintained-app-edit") return "maintained-boundary";
268
+ if (mode === "verification") return "verification-targets";
269
+ return "change-plan";
270
+ }