@canonical/pragma-cli 0.35.0 → 0.37.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 (295) hide show
  1. package/README.md +2 -2
  2. package/bundled-skills/add-standard/SKILL.md +338 -0
  3. package/bundled-skills/adoption-a1-styles/SKILL.md +269 -0
  4. package/bundled-skills/adoption-a2-components/SKILL.md +291 -0
  5. package/bundled-skills/adoption-a3-forms/SKILL.md +260 -0
  6. package/bundled-skills/anatomy-author/ANATOMY_DSL_SPEC.md +406 -0
  7. package/bundled-skills/anatomy-author/SKILL.md +1226 -0
  8. package/bundled-skills/design-auditor/SKILL.md +455 -0
  9. package/bundled-skills/implement-component/SKILL.md +333 -0
  10. package/bundled-skills/specify-component/SKILL.md +331 -0
  11. package/bundled-skills/specify-pattern/SKILL.md +292 -0
  12. package/dist/package.json +24 -20
  13. package/dist/pragma.conf.js +266 -34
  14. package/dist/pragma.conf.js.map +1 -1
  15. package/dist/src/bin.js +1 -1
  16. package/dist/src/bin.js.map +1 -1
  17. package/dist/src/capabilities/capabilities/hints.js +1 -1
  18. package/dist/src/capabilities/capabilities/hints.js.map +1 -1
  19. package/dist/src/capabilities/colophon/colophon.render.js +1 -1
  20. package/dist/src/capabilities/colophon/colophon.render.js.map +1 -1
  21. package/dist/src/capabilities/create/create.verb.js +2 -1
  22. package/dist/src/capabilities/create/create.verb.js.map +1 -1
  23. package/dist/src/capabilities/create/createSurface.generated.js +23 -1
  24. package/dist/src/capabilities/create/createSurface.generated.js.map +1 -1
  25. package/dist/src/capabilities/create/mount.js +4 -3
  26. package/dist/src/capabilities/create/mount.js.map +1 -1
  27. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +11 -6
  28. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -1
  29. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +60 -4
  30. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -1
  31. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js +8 -8
  32. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js.map +1 -1
  33. package/dist/src/capabilities/doctor/checks/harnessInventory.js +195 -0
  34. package/dist/src/capabilities/doctor/checks/harnessInventory.js.map +1 -0
  35. package/dist/src/capabilities/doctor/checks/index.js +6 -6
  36. package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js +38 -0
  37. package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js.map +1 -0
  38. package/dist/src/capabilities/doctor/checks/targetHealth.js +194 -50
  39. package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -1
  40. package/dist/src/capabilities/doctor/doctor.render.js +43 -64
  41. package/dist/src/capabilities/doctor/doctor.render.js.map +1 -1
  42. package/dist/src/capabilities/doctor/doctor.verb.js +6 -2
  43. package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -1
  44. package/dist/src/capabilities/doctor/runChecks.js +14 -11
  45. package/dist/src/capabilities/doctor/runChecks.js.map +1 -1
  46. package/dist/src/capabilities/graph/query.render.js +2 -2
  47. package/dist/src/capabilities/graph/query.render.js.map +1 -1
  48. package/dist/src/capabilities/info/collectInfo.js +8 -2
  49. package/dist/src/capabilities/info/collectInfo.js.map +1 -1
  50. package/dist/src/capabilities/info/info.render.js +6 -2
  51. package/dist/src/capabilities/info/info.render.js.map +1 -1
  52. package/dist/src/capabilities/prompt/prompt.render.js +2 -2
  53. package/dist/src/capabilities/prompt/prompt.render.js.map +1 -1
  54. package/dist/src/capabilities/setup/buildPlan.js +43 -39
  55. package/dist/src/capabilities/setup/buildPlan.js.map +1 -1
  56. package/dist/src/capabilities/setup/mode.js +2 -2
  57. package/dist/src/capabilities/setup/operations/index.js +4 -4
  58. package/dist/src/capabilities/setup/operations/index.js.map +1 -1
  59. package/dist/src/capabilities/setup/operations/setupCompletions.js +6 -2
  60. package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -1
  61. package/dist/src/capabilities/setup/operations/setupConfig.js +4 -2
  62. package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -1
  63. package/dist/src/capabilities/setup/operations/setupGenerator.js +156 -58
  64. package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -1
  65. package/dist/src/capabilities/setup/operations/setupLsp.js +136 -38
  66. package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -1
  67. package/dist/src/capabilities/setup/operations/setupMcp.js +101 -52
  68. package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -1
  69. package/dist/src/capabilities/setup/operations/setupSkills.js +329 -49
  70. package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -1
  71. package/dist/src/capabilities/setup/plan.js.map +1 -1
  72. package/dist/src/capabilities/setup/plan.render.js +144 -66
  73. package/dist/src/capabilities/setup/plan.render.js.map +1 -1
  74. package/dist/src/capabilities/setup/setup.render.js +1 -1
  75. package/dist/src/capabilities/setup/setup.verb.js +165 -63
  76. package/dist/src/capabilities/setup/setup.verb.js.map +1 -1
  77. package/dist/src/capabilities/setup/targets.js +122 -51
  78. package/dist/src/capabilities/setup/targets.js.map +1 -1
  79. package/dist/src/capabilities/shared/index.js +7 -6
  80. package/dist/src/capabilities/shared/index.js.map +1 -1
  81. package/dist/src/capabilities/shared/packageManager.js +300 -54
  82. package/dist/src/capabilities/shared/packageManager.js.map +1 -1
  83. package/dist/src/capabilities/skill/discover.js +97 -11
  84. package/dist/src/capabilities/skill/discover.js.map +1 -1
  85. package/dist/src/capabilities/skill/render.js +2 -2
  86. package/dist/src/capabilities/skill/render.js.map +1 -1
  87. package/dist/src/capabilities/sources/installSkills.js +145 -3
  88. package/dist/src/capabilities/sources/installSkills.js.map +1 -1
  89. package/dist/src/capabilities/sources/runUpdate.js +68 -2
  90. package/dist/src/capabilities/sources/runUpdate.js.map +1 -1
  91. package/dist/src/capabilities/sources/update.verb.js +3 -3
  92. package/dist/src/capabilities/sources/update.verb.js.map +1 -1
  93. package/dist/src/capabilities/upgrade/runUpgrade.js +43 -7
  94. package/dist/src/capabilities/upgrade/runUpgrade.js.map +1 -1
  95. package/dist/src/capabilities/upgrade/upgrade.render.js +10 -2
  96. package/dist/src/capabilities/upgrade/upgrade.render.js.map +1 -1
  97. package/dist/src/constants.js +13 -2
  98. package/dist/src/constants.js.map +1 -1
  99. package/dist/src/kernel/index.js +11 -2
  100. package/dist/src/kernel/index.js.map +1 -1
  101. package/dist/src/kernel/interactivity.js +68 -0
  102. package/dist/src/kernel/interactivity.js.map +1 -0
  103. package/dist/src/kernel/packs/renderPack.js +3 -3
  104. package/dist/src/kernel/packs/renderPack.js.map +1 -1
  105. package/dist/src/kernel/packs/resolveEntity.js +63 -12
  106. package/dist/src/kernel/packs/resolveEntity.js.map +1 -1
  107. package/dist/src/kernel/packs/runBodies.js +57 -4
  108. package/dist/src/kernel/packs/runBodies.js.map +1 -1
  109. package/dist/src/kernel/packs/schema.js +54 -2
  110. package/dist/src/kernel/packs/schema.js.map +1 -1
  111. package/dist/src/kernel/packs/sparql/applyFilters.js +104 -5
  112. package/dist/src/kernel/packs/sparql/applyFilters.js.map +1 -1
  113. package/dist/src/kernel/packs/sparql/buildLookupQuery.js +310 -43
  114. package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -1
  115. package/dist/src/kernel/packs/types.js.map +1 -1
  116. package/dist/src/kernel/project/cli/buildProgram.js +1 -1
  117. package/dist/src/kernel/project/cli/buildProgram.js.map +1 -1
  118. package/dist/src/kernel/project/cli/dispatch.js +46 -24
  119. package/dist/src/kernel/project/cli/dispatch.js.map +1 -1
  120. package/dist/src/kernel/project/cli/globalFlags.js +4 -1
  121. package/dist/src/kernel/project/cli/globalFlags.js.map +1 -1
  122. package/dist/src/kernel/project/cli/helpFormat.js +1 -2
  123. package/dist/src/kernel/project/cli/helpFormat.js.map +1 -1
  124. package/dist/src/kernel/project/cli/rootHelp.js +42 -9
  125. package/dist/src/kernel/project/cli/rootHelp.js.map +1 -1
  126. package/dist/src/kernel/project/mcp/registerVerb.js +16 -1
  127. package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -1
  128. package/dist/src/kernel/render/renderers.js +1 -1
  129. package/dist/src/kernel/render/style.js +29 -9
  130. package/dist/src/kernel/render/style.js.map +1 -1
  131. package/dist/src/kernel/render/vocabulary.js +174 -0
  132. package/dist/src/kernel/render/vocabulary.js.map +1 -0
  133. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +2 -3
  134. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -1
  135. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +1 -1
  136. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -1
  137. package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js +4 -0
  138. package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js.map +1 -0
  139. package/dist/src/kernel/runtime/graphpack/embedded.js +13 -6
  140. package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -1
  141. package/dist/src/kernel/runtime/graphpack/read.js +14 -9
  142. package/dist/src/kernel/runtime/graphpack/read.js.map +1 -1
  143. package/dist/src/kernel/runtime/loadSession.js +3 -1
  144. package/dist/src/kernel/runtime/loadSession.js.map +1 -1
  145. package/dist/src/kernel/runtime/probe.js +1 -1
  146. package/dist/src/kernel/runtime/probe.js.map +1 -1
  147. package/dist/src/kernel/runtime/refs/parseRef.js +17 -1
  148. package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -1
  149. package/dist/src/kernel/runtime/refs/resolve.js +9 -3
  150. package/dist/src/kernel/runtime/refs/resolve.js.map +1 -1
  151. package/dist/src/kernel/spec/emitReference.js +1 -1
  152. package/dist/src/kernel/spec/emitReference.js.map +1 -1
  153. package/package.json +24 -20
  154. package/pragma.conf.ts +272 -34
  155. package/src/bin.ts +8 -1
  156. package/src/capabilities/block.parity.test.ts +25 -11
  157. package/src/capabilities/block.shipped.exec.test.ts +282 -0
  158. package/src/capabilities/block.tierRank.exec.test.ts +300 -0
  159. package/src/capabilities/capabilities/hints.ts +1 -1
  160. package/src/capabilities/colophon/colophon.render.ts +1 -2
  161. package/src/capabilities/colophon/colophon.test.ts +2 -2
  162. package/src/capabilities/config/collectConfigShow.test.ts +1 -0
  163. package/src/capabilities/create/byteEquality.test.ts +28 -1
  164. package/src/capabilities/create/create.test.ts +1 -0
  165. package/src/capabilities/create/create.verb.ts +2 -1
  166. package/src/capabilities/create/createGrammar.test.ts +5 -2
  167. package/src/capabilities/create/createSurface.generated.ts +23 -1
  168. package/src/capabilities/create/crossCli.subprocess.test.ts +10 -3
  169. package/src/capabilities/create/mount.ts +3 -3
  170. package/src/capabilities/distribution.parity.test.ts +4 -0
  171. package/src/capabilities/doctor/checks/checkNodeVersion.test.ts +49 -0
  172. package/src/capabilities/doctor/checks/checkNodeVersion.ts +11 -7
  173. package/src/capabilities/doctor/checks/checkPackageRefs.ts +69 -4
  174. package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +6 -4
  175. package/src/capabilities/doctor/checks/checkShellCompletions.ts +8 -8
  176. package/src/capabilities/doctor/checks/harnessInventory.test.ts +219 -0
  177. package/src/capabilities/doctor/checks/harnessInventory.ts +298 -0
  178. package/src/capabilities/doctor/checks/index.ts +6 -6
  179. package/src/capabilities/doctor/checks/isSupportedNodeVersion.test.ts +111 -0
  180. package/src/capabilities/doctor/checks/isSupportedNodeVersion.ts +34 -0
  181. package/src/capabilities/doctor/checks/mcpCommand.test.ts +7 -1
  182. package/src/capabilities/doctor/checks/targetHealth.ts +229 -59
  183. package/src/capabilities/doctor/doctor.render.test.ts +108 -32
  184. package/src/capabilities/doctor/doctor.render.ts +56 -80
  185. package/src/capabilities/doctor/doctor.test.ts +247 -35
  186. package/src/capabilities/doctor/doctor.verb.ts +7 -2
  187. package/src/capabilities/doctor/runChecks.ts +14 -11
  188. package/src/capabilities/doctor/types.ts +15 -24
  189. package/src/capabilities/emptyRecovery.test.ts +10 -2
  190. package/src/capabilities/graph/query.render.ts +2 -2
  191. package/src/capabilities/info/collectInfo.ts +8 -1
  192. package/src/capabilities/info/info.render.ts +6 -2
  193. package/src/capabilities/info/info.test.ts +37 -1
  194. package/src/capabilities/info/types.ts +10 -2
  195. package/src/capabilities/lazy.test.ts +26 -2
  196. package/src/capabilities/listLookup.shipped.exec.test.ts +340 -0
  197. package/src/capabilities/prompt/prompt.render.ts +2 -2
  198. package/src/capabilities/renderVocabularySync.test.ts +82 -0
  199. package/src/capabilities/resources/resources.test.ts +38 -2
  200. package/src/capabilities/scopeTypeSync.test.ts +29 -15
  201. package/src/capabilities/setup/buildPlan.ts +45 -41
  202. package/src/capabilities/setup/index.ts +1 -1
  203. package/src/capabilities/setup/mode.ts +2 -2
  204. package/src/capabilities/setup/operations/index.ts +6 -1
  205. package/src/capabilities/setup/operations/setupCompletions.ts +9 -2
  206. package/src/capabilities/setup/operations/setupConfig.ts +7 -2
  207. package/src/capabilities/setup/operations/setupGenerator.ts +227 -84
  208. package/src/capabilities/setup/operations/setupLsp.ts +203 -38
  209. package/src/capabilities/setup/operations/setupMcp.ts +139 -62
  210. package/src/capabilities/setup/operations/setupSkills.ts +399 -60
  211. package/src/capabilities/setup/plan.render.ts +171 -76
  212. package/src/capabilities/setup/plan.ts +17 -12
  213. package/src/capabilities/setup/setup.mcp.correctness.test.ts +9 -9
  214. package/src/capabilities/setup/setup.render.test.ts +50 -36
  215. package/src/capabilities/setup/setup.render.ts +1 -1
  216. package/src/capabilities/setup/setup.test.ts +1126 -50
  217. package/src/capabilities/setup/setup.verb.ts +174 -68
  218. package/src/capabilities/setup/targets.ts +138 -60
  219. package/src/capabilities/setup/types.ts +10 -18
  220. package/src/capabilities/shared/index.ts +18 -6
  221. package/src/capabilities/shared/packageManager.test.ts +421 -6
  222. package/src/capabilities/shared/packageManager.ts +394 -59
  223. package/src/capabilities/skill/bundledSkills.test.ts +347 -0
  224. package/src/capabilities/skill/discover.ts +100 -11
  225. package/src/capabilities/skill/render.ts +2 -2
  226. package/src/capabilities/skill/skill.test.ts +17 -4
  227. package/src/capabilities/sources/installSkills.ts +181 -3
  228. package/src/capabilities/sources/runUpdate.ts +78 -2
  229. package/src/capabilities/sources/sources.test.ts +228 -0
  230. package/src/capabilities/sources/update.verb.ts +3 -3
  231. package/src/capabilities/surface.test.ts +14 -6
  232. package/src/capabilities/upgrade/runUpgrade.ts +45 -6
  233. package/src/capabilities/upgrade/types.ts +10 -2
  234. package/src/capabilities/upgrade/upgrade.render.ts +9 -2
  235. package/src/capabilities/upgrade/upgrade.test.ts +72 -0
  236. package/src/constants.ts +14 -1
  237. package/src/identity.test.ts +18 -5
  238. package/src/kernel/completion/entitySource.test.ts +15 -2
  239. package/src/kernel/completion/safety.test.ts +16 -9
  240. package/src/kernel/config/defaults.test.ts +19 -3
  241. package/src/kernel/config/readConfig.test.ts +1 -1
  242. package/src/kernel/index.ts +11 -2
  243. package/src/kernel/interactivity.test.ts +76 -0
  244. package/src/kernel/interactivity.ts +69 -0
  245. package/src/kernel/packs/compile.test.ts +92 -0
  246. package/src/kernel/packs/renderPack.ts +3 -3
  247. package/src/kernel/packs/resolveEntity.test.ts +75 -14
  248. package/src/kernel/packs/resolveEntity.ts +88 -24
  249. package/src/kernel/packs/runBodies.ts +84 -19
  250. package/src/kernel/packs/schema.ts +60 -4
  251. package/src/kernel/packs/sparql/applyFilters.ts +125 -4
  252. package/src/kernel/packs/sparql/buildLookupQuery.test.ts +290 -0
  253. package/src/kernel/packs/sparql/buildLookupQuery.ts +327 -45
  254. package/src/kernel/packs/toolDescription.test.ts +35 -1
  255. package/src/kernel/packs/types.ts +125 -2
  256. package/src/kernel/project/cli/buildProgram.test.ts +73 -2
  257. package/src/kernel/project/cli/buildProgram.ts +8 -1
  258. package/src/kernel/project/cli/dispatch.test.ts +5 -4
  259. package/src/kernel/project/cli/dispatch.ts +48 -25
  260. package/src/kernel/project/cli/globalFlags.ts +4 -1
  261. package/src/kernel/project/cli/helpFormat.ts +1 -2
  262. package/src/kernel/project/cli/rootHelp.ts +44 -8
  263. package/src/kernel/project/mcp/registerVerb.ts +20 -1
  264. package/src/kernel/render/prefixes.test.ts +2 -0
  265. package/src/kernel/render/renderers.ts +1 -1
  266. package/src/kernel/render/style.ts +32 -9
  267. package/src/kernel/render/vocabulary.ts +276 -0
  268. package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +2 -3
  269. package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
  270. package/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.ts +3 -0
  271. package/src/kernel/runtime/graphpack/embedded.ts +14 -6
  272. package/src/kernel/runtime/graphpack/graphpack.test.ts +31 -5
  273. package/src/kernel/runtime/graphpack/read.ts +14 -12
  274. package/src/kernel/runtime/loadSession.ts +3 -1
  275. package/src/kernel/runtime/probe.ts +1 -1
  276. package/src/kernel/runtime/refs/parseRef.test.ts +49 -1
  277. package/src/kernel/runtime/refs/parseRef.ts +25 -1
  278. package/src/kernel/runtime/refs/resolve.ts +9 -3
  279. package/src/kernel/runtime/types.ts +17 -0
  280. package/src/kernel/spec/emitReference.ts +1 -1
  281. package/src/kernel/spec/types.ts +35 -6
  282. package/src/testing/PARITY_GAPS.ts +9 -3
  283. package/src/testing/behavioral/docExamples.test.ts +4 -2
  284. package/src/testing/behavioral/errorMatrix.mcp.test.ts +110 -7
  285. package/src/testing/behavioral/journeys.firstInstall.test.ts +7 -2
  286. package/src/testing/behavioral/journeys.packageStories.test.ts +6 -3
  287. package/src/testing/eval/__snapshots__/eval.test.ts.snap +26 -1
  288. package/src/testing/eval/cases/readNouns.ts +245 -9
  289. package/src/testing/fixtures/blockGraph.ts +28 -13
  290. package/src/testing/fixtures/graph/canonical.ts +95 -12
  291. package/src/testing/helpers/runCli.test.ts +44 -0
  292. package/src/testing/helpers/runCli.ts +27 -3
  293. package/dist/src/capabilities/shared/bands.js +0 -16
  294. package/dist/src/capabilities/shared/bands.js.map +0 -1
  295. package/src/capabilities/shared/bands.ts +0 -16
@@ -19,16 +19,16 @@ import {
19
19
  } from "./plan.js";
20
20
  import {
21
21
  type AnyTarget,
22
- supportsBand,
22
+ supportsScope,
23
23
  TARGETS,
24
24
  type TargetDraft,
25
25
  } from "./targets.js";
26
- import type { ScopeBand, ScopeSelection } from "./types.js";
26
+ import type { Scope, ScopeSelection } from "./types.js";
27
27
 
28
28
  /** One detection, kept beside the row that produced it (and can read it back). */
29
29
  export interface DetectedRow {
30
30
  readonly target: AnyTarget;
31
- readonly band: ScopeBand;
31
+ readonly scope: Scope;
32
32
  readonly detection: never;
33
33
  /**
34
34
  * Why this row's detection did not settle, when it threw. `detection` is then
@@ -48,8 +48,8 @@ export interface DetectedPlan {
48
48
  readonly detected: readonly DetectedRow[];
49
49
  }
50
50
 
51
- /** The bands a `--scope` selection runs, global before project. */
52
- export const bandsForScope = (scope: ScopeSelection): readonly ScopeBand[] =>
51
+ /** The scopes a `--scope` selection runs, global before project. */
52
+ export const scopesForSelection = (scope: ScopeSelection): readonly Scope[] =>
53
53
  scope === "both" ? ["global", "project"] : [scope];
54
54
 
55
55
  /**
@@ -72,7 +72,7 @@ const messageOf = (reason: unknown): string =>
72
72
  reason instanceof Error ? reason.message : String(reason);
73
73
 
74
74
  /**
75
- * Detect every requested target in every band the scope runs.
75
+ * Detect every requested target in every scope the scope runs.
76
76
  *
77
77
  * Detections are started together and SETTLED INDEPENDENTLY: they are
78
78
  * independent reads, and a run-all that probed five targets serially paid for
@@ -82,13 +82,13 @@ const messageOf = (reason: unknown): string =>
82
82
  * unreadable config, a permission-denied directory — takes only its own row
83
83
  * down. Awaiting them as one `Promise.all` meant the first rejection prevented
84
84
  * a run from being built at all: none of the other targets ran, and doctor
85
- * rendered no banded rows whatsoever. The failed row carries its cause and is
85
+ * rendered no scoped rows whatsoever. The failed row carries its cause and is
86
86
  * reported as a row, which is the same shape a failed COMPOSE already has.
87
87
  *
88
88
  * @param rt - The per-invocation runtime.
89
89
  * @param ids - The targets to plan (all five for the run-all).
90
- * @param scope - The resolved band selection.
91
- * @returns One entry per (target, band) the scope actually runs.
90
+ * @param scope - The resolved scope selection.
91
+ * @returns One entry per (target, scope) the scope actually runs.
92
92
  * @note Impure — every target's `detect` reads the real filesystem.
93
93
  */
94
94
  export async function detectTargets(
@@ -97,25 +97,25 @@ export async function detectTargets(
97
97
  scope: ScopeSelection,
98
98
  ): Promise<DetectedRow[]> {
99
99
  const wanted = TARGETS.filter((target) => ids.includes(target.id));
100
- const pairs = bandsForScope(scope).flatMap((band) =>
100
+ const pairs = scopesForSelection(scope).flatMap((scope) =>
101
101
  wanted
102
- .filter((target) => supportsBand(target, band))
102
+ .filter((target) => supportsScope(target, scope))
103
103
  .map((target) => ({
104
104
  target,
105
- band,
105
+ scope,
106
106
  })),
107
107
  );
108
108
  const settled = await Promise.allSettled(
109
- pairs.map(({ target, band }) => target.detect(rt, band)),
109
+ pairs.map(({ target, scope }) => target.detect(rt, scope)),
110
110
  );
111
- return pairs.map(({ target, band }, index) => {
111
+ return pairs.map(({ target, scope }, index) => {
112
112
  const outcome = settled[index] as PromiseSettledResult<unknown>;
113
113
  if (outcome.status === "fulfilled") {
114
- return { target, band, detection: outcome.value as never };
114
+ return { target, scope, detection: outcome.value as never };
115
115
  }
116
116
  return {
117
117
  target,
118
- band,
118
+ scope,
119
119
  detection: undefined as never,
120
120
  failure: messageOf(outcome.reason),
121
121
  };
@@ -123,22 +123,26 @@ export async function detectTargets(
123
123
  }
124
124
 
125
125
  /**
126
- * The dim row a target gets when the SELECTED band cannot hold it — `setup
127
- * --local` still shows `completions`, saying why it is not in this run. A band
128
- * merely filters the run-all: the user asked for a band, not for that target, so
126
+ * The dim row a target gets when the SELECTED scope cannot hold it — `setup
127
+ * --local` still shows `completions`, saying why it is not in this run. A scope
128
+ * merely filters the run-all: the user asked for a scope, not for that target, so
129
129
  * nothing errors, but nothing is silently absent either. (Asking for the
130
- * impossible band on the SUB-VERB is a different thing entirely — a typed
130
+ * impossible scope on the SUB-VERB is a different thing entirely — a typed
131
131
  * contradiction, and a usage error.)
132
+ *
133
+ * The reason names the flag that WOULD reach the target, so the row is not a
134
+ * dead end: a reader who wanted `completions` under `--local` is told in the
135
+ * same line that `--global` is where it lives.
132
136
  */
133
- const outOfBandRow = (target: AnyTarget, band: ScopeBand): PlanRow => ({
137
+ const outOfScopeRow = (target: AnyTarget, scope: Scope): PlanRow => ({
134
138
  target: target.id,
135
- band,
139
+ scope,
136
140
  action: "skip",
137
- detail: "not in this band",
141
+ detail: "not part of this scope",
138
142
  reason:
139
- band === "project"
140
- ? "user-level only — it has no project band"
141
- : "project-level only — it has no global band",
143
+ scope === "project"
144
+ ? "this one is global only — run it with `--global`"
145
+ : "this one is per-project only — run it with `--local`",
142
146
  selected: false,
143
147
  });
144
148
 
@@ -151,11 +155,11 @@ const outOfBandRow = (target: AnyTarget, band: ScopeBand): PlanRow => ({
151
155
  */
152
156
  const failedDetectionRow = (
153
157
  target: AnyTarget,
154
- band: ScopeBand,
158
+ scope: Scope,
155
159
  failure: string,
156
160
  ): PlanRow => ({
157
161
  target: target.id,
158
- band,
162
+ scope,
159
163
  action: "skip",
160
164
  detail: "detection did not complete",
161
165
  reason: failure,
@@ -179,51 +183,51 @@ export function draftFor(
179
183
  removal: boolean,
180
184
  ): TargetDraft {
181
185
  return removal
182
- ? hit.target.removalPlan(hit.detection, hit.band, roots)
183
- : hit.target.plan(hit.detection, hit.band, roots);
186
+ ? hit.target.removalPlan(hit.detection, hit.scope, roots)
187
+ : hit.target.plan(hit.detection, hit.scope, roots);
184
188
  }
185
189
 
186
190
  /**
187
191
  * Project detections into plan rows.
188
192
  *
189
- * @param scope - The resolved band selection (named in the header).
193
+ * @param selection - The resolved scope selection (named in the header).
190
194
  * @param roots - The two named roots every path renders relative to.
191
- * @param detected - The detections, in table order per band.
192
- * @param ids - The targets that were REQUESTED, so an out-of-band one still
195
+ * @param detected - The detections, in table order per scope.
196
+ * @param ids - The targets that were REQUESTED, so an out-of-scope one still
193
197
  * gets a visible row.
194
198
  * @param removal - Build the removal plan (`--undo`) instead of the forward one.
195
199
  * @returns The plan.
196
200
  */
197
201
  export function buildPlan(
198
- scope: ScopeSelection,
202
+ selection: ScopeSelection,
199
203
  roots: SetupPlan["roots"],
200
204
  detected: readonly DetectedRow[],
201
205
  ids: readonly TargetId[],
202
206
  removal = false,
203
207
  ): SetupPlan {
204
208
  const rows: PlanRow[] = [];
205
- for (const band of bandsForScope(scope)) {
209
+ for (const scope of scopesForSelection(selection)) {
206
210
  for (const target of TARGETS) {
207
211
  if (!ids.includes(target.id)) continue;
208
212
  const hit = detected.find(
209
- (d) => d.target.id === target.id && d.band === band,
213
+ (d) => d.target.id === target.id && d.scope === scope,
210
214
  );
211
215
  if (hit === undefined) {
212
- // Only worth a line when the target has no row in ANY selected band —
216
+ // Only worth a line when the target has no row in ANY selected scope —
213
217
  // under `--scope both` a global-only target already appears above.
214
218
  const elsewhere = detected.some((d) => d.target.id === target.id);
215
- if (!elsewhere) rows.push(outOfBandRow(target, band));
219
+ if (!elsewhere) rows.push(outOfScopeRow(target, scope));
216
220
  continue;
217
221
  }
218
222
  const failure = detectionFailure(hit);
219
223
  if (failure !== undefined) {
220
- rows.push(failedDetectionRow(target, band, failure));
224
+ rows.push(failedDetectionRow(target, scope, failure));
221
225
  continue;
222
226
  }
223
227
  const draft = draftFor(hit, roots, removal);
224
228
  rows.push({
225
229
  target: target.id,
226
- band,
230
+ scope,
227
231
  action: draft.action,
228
232
  detail: draft.detail,
229
233
  ...(draft.reason === undefined ? {} : { reason: draft.reason }),
@@ -232,5 +236,5 @@ export function buildPlan(
232
236
  });
233
237
  }
234
238
  }
235
- return { scope, roots, rows };
239
+ return { scope: selection, roots, rows };
236
240
  }
@@ -9,4 +9,4 @@ export type {
9
9
  TargetId,
10
10
  } from "./plan.js";
11
11
  export { setupModule } from "./setup.verb.js";
12
- export type { ScopeBand, ScopeSelection } from "./types.js";
12
+ export type { Scope, ScopeSelection } from "./types.js";
@@ -20,8 +20,8 @@
20
20
  * who forgot `--yes` reads the hint on the very output they are capturing.
21
21
  *
22
22
  * An MCP tool call is programmatic consent: `transport === "mcp"` resolves as if
23
- * `--yes` were passed. The band default applies there too — the tool writes the
24
- * global band unless told otherwise.
23
+ * `--yes` were passed. The scope default applies there too — the tool writes the
24
+ * global scope unless told otherwise.
25
25
  */
26
26
 
27
27
  import type { InteractionMode } from "@canonical/summon-core/projection";
@@ -13,7 +13,7 @@
13
13
  *
14
14
  * The detection types are part of the surface, not an implementation leak: a
15
15
  * detection is the value passed from the read half to the compose half and on
16
- * to the plan rows, so `doctor`'s banded checks name the same records `setup`
16
+ * to the plan rows, so `doctor`'s scoped checks name the same records `setup`
17
17
  * acts on. The presentation helpers travel with them for the same reason — a
18
18
  * skip reason or an uninstall remedy is derived from one detection, and
19
19
  * deriving it twice is how the two surfaces start disagreeing about the same
@@ -54,6 +54,7 @@ export {
54
54
  lspEditorNames,
55
55
  lspSkipReason,
56
56
  lspUninstallRemedy,
57
+ ownedLspEditors,
57
58
  } from "./setupLsp.js";
58
59
  export type { McpDetection } from "./setupMcp.js";
59
60
  export {
@@ -61,6 +62,7 @@ export {
61
62
  composeMcpRemoval,
62
63
  detectMcp,
63
64
  mcpGroupState,
65
+ mcpWriteState,
64
66
  ownedMcpGroups,
65
67
  selectedGroups,
66
68
  } from "./setupMcp.js";
@@ -71,4 +73,7 @@ export {
71
73
  detectSkills,
72
74
  ownedSkillLinks,
73
75
  skillsSkipReason,
76
+ skillsSkipRemedy,
77
+ staleSkillLinks,
78
+ withinRoot,
74
79
  } from "./setupSkills.js";
@@ -204,11 +204,18 @@ export function composeCompletions(d: CompletionsDetection): Task<void> {
204
204
  * machine that never installed one reverses zero steps and says so.
205
205
  *
206
206
  * @param d - The detection gathered up front.
207
+ * @param undoKey - Correlation key stamped on the reversal(s), echoed on
208
+ * their undo outcomes so the caller can read results back per row.
207
209
  * @returns A Task whose undo deletes the installed script.
208
210
  */
209
- export function composeCompletionsRemoval(d: CompletionsDetection): Task<void> {
211
+ export function composeCompletionsRemoval(
212
+ d: CompletionsDetection,
213
+ undoKey?: string,
214
+ ): Task<void> {
210
215
  if (d.path === null || d.script === null || d.state === "absent") {
211
216
  return sequence_([]);
212
217
  }
213
- return sequence_([writeFile(d.path, d.script, { undo: deleteFile(d.path) })]);
218
+ return sequence_([
219
+ writeFile(d.path, d.script, { undo: deleteFile(d.path), undoKey }),
220
+ ]);
214
221
  }
@@ -110,12 +110,17 @@ export function composeConfigFile(d: ConfigDetection): Task<void> {
110
110
  * delete as its `undo`, which is what the undo interpreter executes.
111
111
  *
112
112
  * @param d - The detection gathered up front.
113
+ * @param undoKey - Correlation key stamped on the reversal(s), echoed on
114
+ * their undo outcomes so the caller can read results back per row.
113
115
  * @returns A Task whose undo removes a seed-only config, or an empty Task.
114
116
  */
115
- export function composeConfigRemoval(d: ConfigDetection): Task<void> {
117
+ export function composeConfigRemoval(
118
+ d: ConfigDetection,
119
+ undoKey?: string,
120
+ ): Task<void> {
116
121
  if (!d.exists || !d.isSeed) return sequence_([]);
117
122
  return sequence_([
118
- writeFile(d.path, SEED_CONFIG, { undo: deleteFile(d.path) }),
123
+ writeFile(d.path, SEED_CONFIG, { undo: deleteFile(d.path), undoKey }),
119
124
  ]);
120
125
  }
121
126