@shrkcrft/cli 0.1.0-alpha.30 → 0.1.0-alpha.31

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 (510) hide show
  1. package/dist/asset-preview/apply-asset-preview.js +1 -1
  2. package/dist/authoring/authoring-kit.d.ts +9 -1
  3. package/dist/authoring/authoring-kit.d.ts.map +1 -1
  4. package/dist/authoring/authoring-kit.js +26 -13
  5. package/dist/bootstrap/unlinked-workspace-dependency.d.ts +11 -0
  6. package/dist/bootstrap/unlinked-workspace-dependency.d.ts.map +1 -0
  7. package/dist/bootstrap/unlinked-workspace-dependency.js +99 -0
  8. package/dist/command-registry.d.ts +100 -1
  9. package/dist/command-registry.d.ts.map +1 -1
  10. package/dist/command-registry.js +130 -3
  11. package/dist/commands/api-diff.command.d.ts.map +1 -1
  12. package/dist/commands/api-diff.command.js +12 -0
  13. package/dist/commands/apply.command.d.ts.map +1 -1
  14. package/dist/commands/apply.command.js +3 -0
  15. package/dist/commands/arch.command.d.ts.map +1 -1
  16. package/dist/commands/arch.command.js +26 -7
  17. package/dist/commands/architecture.command.d.ts.map +1 -1
  18. package/dist/commands/architecture.command.js +8 -2
  19. package/dist/commands/baseline.command.d.ts +54 -3
  20. package/dist/commands/baseline.command.d.ts.map +1 -1
  21. package/dist/commands/baseline.command.js +582 -74
  22. package/dist/commands/biome.command.d.ts.map +1 -1
  23. package/dist/commands/biome.command.js +20 -0
  24. package/dist/commands/boundaries.command.d.ts +9 -1
  25. package/dist/commands/boundaries.command.d.ts.map +1 -1
  26. package/dist/commands/boundaries.command.js +88 -20
  27. package/dist/commands/bundle.command.d.ts.map +1 -1
  28. package/dist/commands/bundle.command.js +57 -11
  29. package/dist/commands/cache-align.command.d.ts.map +1 -1
  30. package/dist/commands/cache-align.command.js +3 -1
  31. package/dist/commands/changelog-data.d.ts.map +1 -1
  32. package/dist/commands/changelog-data.js +138 -0
  33. package/dist/commands/changes.command.d.ts.map +1 -1
  34. package/dist/commands/changes.command.js +15 -0
  35. package/dist/commands/check.command.d.ts.map +1 -1
  36. package/dist/commands/check.command.js +1241 -322
  37. package/dist/commands/checks.command.d.ts.map +1 -1
  38. package/dist/commands/checks.command.js +188 -40
  39. package/dist/commands/ci.command.d.ts.map +1 -1
  40. package/dist/commands/ci.command.js +35 -2
  41. package/dist/commands/code-intel.command.d.ts.map +1 -1
  42. package/dist/commands/code-intel.command.js +3 -0
  43. package/dist/commands/command-catalog.d.ts +23 -1
  44. package/dist/commands/command-catalog.d.ts.map +1 -1
  45. package/dist/commands/command-catalog.js +152 -35
  46. package/dist/commands/commands.command.d.ts +21 -3
  47. package/dist/commands/commands.command.d.ts.map +1 -1
  48. package/dist/commands/commands.command.js +172 -27
  49. package/dist/commands/compress.command.d.ts.map +1 -1
  50. package/dist/commands/compress.command.js +4 -0
  51. package/dist/commands/constructs.command.d.ts.map +1 -1
  52. package/dist/commands/constructs.command.js +50 -12
  53. package/dist/commands/context.command.d.ts.map +1 -1
  54. package/dist/commands/context.command.js +40 -5
  55. package/dist/commands/contract-templates.command.d.ts.map +1 -1
  56. package/dist/commands/contract-templates.command.js +9 -1
  57. package/dist/commands/contract.command.d.ts.map +1 -1
  58. package/dist/commands/contract.command.js +35 -0
  59. package/dist/commands/conventions.command.d.ts.map +1 -1
  60. package/dist/commands/conventions.command.js +189 -29
  61. package/dist/commands/coverage.command.d.ts.map +1 -1
  62. package/dist/commands/coverage.command.js +9 -0
  63. package/dist/commands/daily.commands.d.ts +0 -1
  64. package/dist/commands/daily.commands.d.ts.map +1 -1
  65. package/dist/commands/daily.commands.js +12 -76
  66. package/dist/commands/dashboard.command.d.ts.map +1 -1
  67. package/dist/commands/dashboard.command.js +10 -0
  68. package/dist/commands/dev.command.d.ts.map +1 -1
  69. package/dist/commands/dev.command.js +45 -2
  70. package/dist/commands/diagnostics.command.d.ts +0 -2
  71. package/dist/commands/diagnostics.command.d.ts.map +1 -1
  72. package/dist/commands/diagnostics.command.js +5 -78
  73. package/dist/commands/diff-check.command.d.ts +6 -4
  74. package/dist/commands/diff-check.command.d.ts.map +1 -1
  75. package/dist/commands/diff-check.command.js +190 -103
  76. package/dist/commands/docs-references.command.d.ts +13 -0
  77. package/dist/commands/docs-references.command.d.ts.map +1 -1
  78. package/dist/commands/docs-references.command.js +269 -72
  79. package/dist/commands/doctor.command.d.ts.map +1 -1
  80. package/dist/commands/doctor.command.js +58 -4
  81. package/dist/commands/drift.command.d.ts.map +1 -1
  82. package/dist/commands/drift.command.js +17 -4
  83. package/dist/commands/eslint.command.d.ts.map +1 -1
  84. package/dist/commands/eslint.command.js +20 -0
  85. package/dist/commands/export.command.d.ts.map +1 -1
  86. package/dist/commands/export.command.js +23 -1
  87. package/dist/commands/feedback-dispatch.command.d.ts.map +1 -1
  88. package/dist/commands/feedback-dispatch.command.js +29 -0
  89. package/dist/commands/feedback.command.d.ts.map +1 -1
  90. package/dist/commands/feedback.command.js +6 -1
  91. package/dist/commands/finish.command.d.ts.map +1 -1
  92. package/dist/commands/finish.command.js +32 -8
  93. package/dist/commands/fix.command.d.ts.map +1 -1
  94. package/dist/commands/fix.command.js +19 -0
  95. package/dist/commands/gate.command.d.ts +6 -1
  96. package/dist/commands/gate.command.d.ts.map +1 -1
  97. package/dist/commands/gate.command.js +50 -124
  98. package/dist/commands/gates.command.d.ts +52 -0
  99. package/dist/commands/gates.command.d.ts.map +1 -1
  100. package/dist/commands/gates.command.js +811 -185
  101. package/dist/commands/gen.command.d.ts.map +1 -1
  102. package/dist/commands/gen.command.js +4 -0
  103. package/dist/commands/generated.command.d.ts +33 -3
  104. package/dist/commands/generated.command.d.ts.map +1 -1
  105. package/dist/commands/generated.command.js +499 -147
  106. package/dist/commands/graph-code-subverbs.d.ts +15 -0
  107. package/dist/commands/graph-code-subverbs.d.ts.map +1 -1
  108. package/dist/commands/graph-code-subverbs.js +198 -24
  109. package/dist/commands/graph.command.d.ts.map +1 -1
  110. package/dist/commands/graph.command.js +79 -37
  111. package/dist/commands/help.command.d.ts +30 -6
  112. package/dist/commands/help.command.d.ts.map +1 -1
  113. package/dist/commands/help.command.js +323 -199
  114. package/dist/commands/helper.command.d.ts +1 -0
  115. package/dist/commands/helper.command.d.ts.map +1 -1
  116. package/dist/commands/helper.command.js +195 -56
  117. package/dist/commands/impact.command.d.ts.map +1 -1
  118. package/dist/commands/impact.command.js +115 -12
  119. package/dist/commands/infer.command.d.ts.map +1 -1
  120. package/dist/commands/infer.command.js +20 -45
  121. package/dist/commands/ingest.command.d.ts +0 -1
  122. package/dist/commands/ingest.command.d.ts.map +1 -1
  123. package/dist/commands/ingest.command.js +25 -41
  124. package/dist/commands/knowledge-author.command.d.ts +0 -3
  125. package/dist/commands/knowledge-author.command.d.ts.map +1 -1
  126. package/dist/commands/knowledge-author.command.js +10 -23
  127. package/dist/commands/knowledge.command.d.ts.map +1 -1
  128. package/dist/commands/knowledge.command.js +469 -129
  129. package/dist/commands/languages.command.d.ts.map +1 -1
  130. package/dist/commands/languages.command.js +27 -0
  131. package/dist/commands/lint.command.d.ts.map +1 -1
  132. package/dist/commands/lint.command.js +3 -0
  133. package/dist/commands/mcp.command.d.ts +18 -0
  134. package/dist/commands/mcp.command.d.ts.map +1 -1
  135. package/dist/commands/mcp.command.js +33 -8
  136. package/dist/commands/onboard.command.d.ts.map +1 -1
  137. package/dist/commands/onboard.command.js +20 -0
  138. package/dist/commands/owners.command.d.ts.map +1 -1
  139. package/dist/commands/owners.command.js +14 -2
  140. package/dist/commands/packs-new.d.ts +13 -1
  141. package/dist/commands/packs-new.d.ts.map +1 -1
  142. package/dist/commands/packs-new.js +500 -335
  143. package/dist/commands/packs.command.d.ts.map +1 -1
  144. package/dist/commands/packs.command.js +378 -36
  145. package/dist/commands/paths.command.d.ts.map +1 -1
  146. package/dist/commands/paths.command.js +9 -1
  147. package/dist/commands/pipelines.command.d.ts.map +1 -1
  148. package/dist/commands/pipelines.command.js +7 -1
  149. package/dist/commands/plan-check.command.d.ts.map +1 -1
  150. package/dist/commands/plan-check.command.js +3 -0
  151. package/dist/commands/plan.command.d.ts.map +1 -1
  152. package/dist/commands/plan.command.js +3 -0
  153. package/dist/commands/playbooks.command.d.ts.map +1 -1
  154. package/dist/commands/playbooks.command.js +7 -2
  155. package/dist/commands/policy-lint.command.d.ts +19 -2
  156. package/dist/commands/policy-lint.command.d.ts.map +1 -1
  157. package/dist/commands/policy-lint.command.js +224 -65
  158. package/dist/commands/policy.command.d.ts.map +1 -1
  159. package/dist/commands/policy.command.js +6 -1
  160. package/dist/commands/pr.command.d.ts.map +1 -1
  161. package/dist/commands/pr.command.js +14 -0
  162. package/dist/commands/presets.command.d.ts.map +1 -1
  163. package/dist/commands/presets.command.js +12 -27
  164. package/dist/commands/profiles.command.d.ts.map +1 -1
  165. package/dist/commands/profiles.command.js +94 -26
  166. package/dist/commands/provenance.command.js +1 -1
  167. package/dist/commands/quality.command.d.ts.map +1 -1
  168. package/dist/commands/quality.command.js +129 -33
  169. package/dist/commands/recommend.command.d.ts +20 -4
  170. package/dist/commands/recommend.command.d.ts.map +1 -1
  171. package/dist/commands/recommend.command.js +172 -278
  172. package/dist/commands/registrations.command.d.ts.map +1 -1
  173. package/dist/commands/registrations.command.js +138 -13
  174. package/dist/commands/registry-lifecycle-run.d.ts +14 -0
  175. package/dist/commands/registry-lifecycle-run.d.ts.map +1 -0
  176. package/dist/commands/registry-lifecycle-run.js +336 -0
  177. package/dist/commands/registry.command.d.ts.map +1 -1
  178. package/dist/commands/registry.command.js +235 -62
  179. package/dist/commands/release.command.d.ts.map +1 -1
  180. package/dist/commands/release.command.js +99 -20
  181. package/dist/commands/report.command.d.ts.map +1 -1
  182. package/dist/commands/report.command.js +38 -2
  183. package/dist/commands/reuse-coverage.command.d.ts +23 -0
  184. package/dist/commands/reuse-coverage.command.d.ts.map +1 -0
  185. package/dist/commands/reuse-coverage.command.js +536 -0
  186. package/dist/commands/reuse.command.d.ts +3 -18
  187. package/dist/commands/reuse.command.d.ts.map +1 -1
  188. package/dist/commands/reuse.command.js +395 -244
  189. package/dist/commands/review.command.d.ts.map +1 -1
  190. package/dist/commands/review.command.js +33 -1
  191. package/dist/commands/rounds.command.d.ts.map +1 -1
  192. package/dist/commands/rounds.command.js +5 -0
  193. package/dist/commands/safety.command.d.ts.map +1 -1
  194. package/dist/commands/safety.command.js +9 -0
  195. package/dist/commands/scaffolds.command.d.ts.map +1 -1
  196. package/dist/commands/scaffolds.command.js +97 -25
  197. package/dist/commands/search.command.d.ts +0 -8
  198. package/dist/commands/search.command.d.ts.map +1 -1
  199. package/dist/commands/search.command.js +136 -28
  200. package/dist/commands/self-config-xrefs.command.d.ts +24 -0
  201. package/dist/commands/self-config-xrefs.command.d.ts.map +1 -0
  202. package/dist/commands/self-config-xrefs.command.js +170 -0
  203. package/dist/commands/self-config.command.d.ts.map +1 -1
  204. package/dist/commands/self-config.command.js +261 -65
  205. package/dist/commands/smart-context.command.d.ts.map +1 -1
  206. package/dist/commands/smart-context.command.js +39 -3
  207. package/dist/commands/spec.command.d.ts.map +1 -1
  208. package/dist/commands/spec.command.js +3 -0
  209. package/dist/commands/stats.command.d.ts.map +1 -1
  210. package/dist/commands/stats.command.js +3 -0
  211. package/dist/commands/surface.command.d.ts +6 -1
  212. package/dist/commands/surface.command.d.ts.map +1 -1
  213. package/dist/commands/surface.command.js +256 -54
  214. package/dist/commands/task-context.command.js +1 -1
  215. package/dist/commands/task.command.d.ts.map +1 -1
  216. package/dist/commands/task.command.js +22 -1
  217. package/dist/commands/templates.command.d.ts +4 -0
  218. package/dist/commands/templates.command.d.ts.map +1 -1
  219. package/dist/commands/templates.command.js +109 -22
  220. package/dist/commands/test.command.d.ts.map +1 -1
  221. package/dist/commands/test.command.js +161 -33
  222. package/dist/commands/tests.command.d.ts.map +1 -1
  223. package/dist/commands/tests.command.js +29 -3
  224. package/dist/commands/trace.command.d.ts.map +1 -1
  225. package/dist/commands/trace.command.js +29 -4
  226. package/dist/commands/watch.command.d.ts.map +1 -1
  227. package/dist/commands/watch.command.js +3 -0
  228. package/dist/commands/why.command.d.ts.map +1 -1
  229. package/dist/commands/why.command.js +3 -0
  230. package/dist/commands/wiring.command.d.ts +18 -4
  231. package/dist/commands/wiring.command.d.ts.map +1 -1
  232. package/dist/commands/wiring.command.js +360 -73
  233. package/dist/dashboard/code-intelligence-data.js +4 -4
  234. package/dist/diff/deleted-orphan-coverage.d.ts +32 -0
  235. package/dist/diff/deleted-orphan-coverage.d.ts.map +1 -0
  236. package/dist/diff/deleted-orphan-coverage.js +107 -0
  237. package/dist/diff/deleted-orphan-scope-notes.d.ts +23 -0
  238. package/dist/diff/deleted-orphan-scope-notes.d.ts.map +1 -0
  239. package/dist/diff/deleted-orphan-scope-notes.js +49 -0
  240. package/dist/diff/deleted-orphans.d.ts +32 -0
  241. package/dist/diff/deleted-orphans.d.ts.map +1 -1
  242. package/dist/diff/deleted-orphans.js +42 -2
  243. package/dist/dispatch/closest-match.d.ts +15 -0
  244. package/dist/dispatch/closest-match.d.ts.map +1 -0
  245. package/dist/dispatch/closest-match.js +47 -0
  246. package/dist/dispatch/global-flags.d.ts +94 -0
  247. package/dist/dispatch/global-flags.d.ts.map +1 -0
  248. package/dist/dispatch/global-flags.js +123 -0
  249. package/dist/dispatch/guard-invocation-input.d.ts +24 -0
  250. package/dist/dispatch/guard-invocation-input.d.ts.map +1 -0
  251. package/dist/dispatch/guard-invocation-input.js +1 -0
  252. package/dist/dispatch/guard-invocation.d.ts +33 -0
  253. package/dist/dispatch/guard-invocation.d.ts.map +1 -0
  254. package/dist/dispatch/guard-invocation.js +183 -0
  255. package/dist/dispatch/help-intercept.d.ts +22 -0
  256. package/dist/dispatch/help-intercept.d.ts.map +1 -0
  257. package/dist/dispatch/help-intercept.js +42 -0
  258. package/dist/dispatch/i-declared-invocation.d.ts +17 -0
  259. package/dist/dispatch/i-declared-invocation.d.ts.map +1 -0
  260. package/dist/dispatch/i-declared-invocation.js +1 -0
  261. package/dist/dispatch/i-unknown-flag-refusal-input.d.ts +28 -0
  262. package/dist/dispatch/i-unknown-flag-refusal-input.d.ts.map +1 -0
  263. package/dist/dispatch/i-unknown-flag-refusal-input.js +1 -0
  264. package/dist/dispatch/invocation-rejection-kind.d.ts +15 -0
  265. package/dist/dispatch/invocation-rejection-kind.d.ts.map +1 -0
  266. package/dist/dispatch/invocation-rejection-kind.js +15 -0
  267. package/dist/dispatch/invocation-rejection.d.ts +18 -0
  268. package/dist/dispatch/invocation-rejection.d.ts.map +1 -0
  269. package/dist/dispatch/invocation-rejection.js +1 -0
  270. package/dist/dispatch/judge-invocation.d.ts +24 -0
  271. package/dist/dispatch/judge-invocation.d.ts.map +1 -0
  272. package/dist/dispatch/judge-invocation.js +50 -0
  273. package/dist/dispatch/positional-mode.d.ts +18 -0
  274. package/dist/dispatch/positional-mode.d.ts.map +1 -0
  275. package/dist/dispatch/positional-mode.js +18 -0
  276. package/dist/dispatch/read-tracking-map.d.ts +28 -0
  277. package/dist/dispatch/read-tracking-map.d.ts.map +1 -0
  278. package/dist/dispatch/read-tracking-map.js +58 -0
  279. package/dist/dispatch/refuse-sibling-valve-flags.d.ts +30 -0
  280. package/dist/dispatch/refuse-sibling-valve-flags.d.ts.map +1 -0
  281. package/dist/dispatch/refuse-sibling-valve-flags.js +65 -0
  282. package/dist/dispatch/subverb-spec.d.ts +26 -0
  283. package/dist/dispatch/subverb-spec.d.ts.map +1 -0
  284. package/dist/dispatch/subverb-spec.js +1 -0
  285. package/dist/dispatch/undocumented-flag-reads.d.ts +22 -0
  286. package/dist/dispatch/undocumented-flag-reads.d.ts.map +1 -0
  287. package/dist/dispatch/undocumented-flag-reads.js +283 -0
  288. package/dist/dispatch/unknown-flag-refusal-mode.d.ts +13 -0
  289. package/dist/dispatch/unknown-flag-refusal-mode.d.ts.map +1 -0
  290. package/dist/dispatch/unknown-flag-refusal-mode.js +13 -0
  291. package/dist/dispatch/unknown-flag-refusal.d.ts +22 -0
  292. package/dist/dispatch/unknown-flag-refusal.d.ts.map +1 -0
  293. package/dist/dispatch/unknown-flag-refusal.js +57 -0
  294. package/dist/dispatch/unread-flags.d.ts +152 -0
  295. package/dist/dispatch/unread-flags.d.ts.map +1 -0
  296. package/dist/dispatch/unread-flags.js +295 -0
  297. package/dist/dispatch/verdict-valve-flag.d.ts +21 -0
  298. package/dist/dispatch/verdict-valve-flag.d.ts.map +1 -0
  299. package/dist/dispatch/verdict-valve-flag.js +21 -0
  300. package/dist/dispatch/walk-declared-subverbs.d.ts +14 -0
  301. package/dist/dispatch/walk-declared-subverbs.d.ts.map +1 -0
  302. package/dist/dispatch/walk-declared-subverbs.js +28 -0
  303. package/dist/exit-codes.d.ts +41 -3
  304. package/dist/exit-codes.d.ts.map +1 -1
  305. package/dist/exit-codes.js +153 -14
  306. package/dist/finish/run-finish.d.ts +72 -5
  307. package/dist/finish/run-finish.d.ts.map +1 -1
  308. package/dist/finish/run-finish.js +453 -104
  309. package/dist/gates/accepted-empty-note.d.ts +10 -0
  310. package/dist/gates/accepted-empty-note.d.ts.map +1 -0
  311. package/dist/gates/accepted-empty-note.js +11 -0
  312. package/dist/gates/allow-empty.d.ts +25 -0
  313. package/dist/gates/allow-empty.d.ts.map +1 -0
  314. package/dist/gates/allow-empty.js +27 -0
  315. package/dist/gates/asset-doctor-failing-units.d.ts +16 -0
  316. package/dist/gates/asset-doctor-failing-units.d.ts.map +1 -0
  317. package/dist/gates/asset-doctor-failing-units.js +14 -0
  318. package/dist/gates/asset-doctor-failure-line.d.ts +16 -0
  319. package/dist/gates/asset-doctor-failure-line.d.ts.map +1 -0
  320. package/dist/gates/asset-doctor-failure-line.js +28 -0
  321. package/dist/gates/empty-rule-advice-lines.d.ts +15 -0
  322. package/dist/gates/empty-rule-advice-lines.d.ts.map +1 -0
  323. package/dist/gates/empty-rule-advice-lines.js +20 -0
  324. package/dist/gates/gate-envelope.d.ts +85 -8
  325. package/dist/gates/gate-envelope.d.ts.map +1 -1
  326. package/dist/gates/gate-envelope.js +56 -7
  327. package/dist/gates/gate-rule-globs.d.ts +37 -3
  328. package/dist/gates/gate-rule-globs.d.ts.map +1 -1
  329. package/dist/gates/gate-rule-globs.js +78 -40
  330. package/dist/gates/gate-rule-view.d.ts +17 -4
  331. package/dist/gates/gate-rule-view.d.ts.map +1 -1
  332. package/dist/gates/gate-rule-view.js +105 -90
  333. package/dist/gates/i-coverage-dead-glob.d.ts +19 -0
  334. package/dist/gates/i-coverage-dead-glob.d.ts.map +1 -0
  335. package/dist/gates/i-coverage-dead-glob.js +1 -0
  336. package/dist/gates/i-coverage-negation.d.ts +13 -0
  337. package/dist/gates/i-coverage-negation.d.ts.map +1 -0
  338. package/dist/gates/i-coverage-negation.js +1 -0
  339. package/dist/gates/i-registration-query-settle-input.d.ts +18 -0
  340. package/dist/gates/i-registration-query-settle-input.d.ts.map +1 -0
  341. package/dist/gates/i-registration-query-settle-input.js +1 -0
  342. package/dist/gates/i-unit-state-note-row.d.ts +16 -0
  343. package/dist/gates/i-unit-state-note-row.d.ts.map +1 -0
  344. package/dist/gates/i-unit-state-note-row.js +1 -0
  345. package/dist/gates/i-unit-state-notes.d.ts +32 -0
  346. package/dist/gates/i-unit-state-notes.d.ts.map +1 -0
  347. package/dist/gates/i-unit-state-notes.js +1 -0
  348. package/dist/gates/incomplete-registry-inventory.d.ts +19 -0
  349. package/dist/gates/incomplete-registry-inventory.d.ts.map +1 -0
  350. package/dist/gates/incomplete-registry-inventory.js +63 -0
  351. package/dist/gates/measure-registration-roles.d.ts +10 -0
  352. package/dist/gates/measure-registration-roles.d.ts.map +1 -0
  353. package/dist/gates/measure-registration-roles.js +9 -0
  354. package/dist/gates/plane-verdict.d.ts +14 -0
  355. package/dist/gates/plane-verdict.d.ts.map +1 -0
  356. package/dist/gates/plane-verdict.js +22 -0
  357. package/dist/gates/qualify-clean-for-units.d.ts +12 -0
  358. package/dist/gates/qualify-clean-for-units.d.ts.map +1 -0
  359. package/dist/gates/qualify-clean-for-units.js +18 -0
  360. package/dist/gates/registration-graph-verdict.d.ts +34 -0
  361. package/dist/gates/registration-graph-verdict.d.ts.map +1 -0
  362. package/dist/gates/registration-graph-verdict.js +70 -0
  363. package/dist/gates/registration-roles.d.ts +9 -0
  364. package/dist/gates/registration-roles.d.ts.map +1 -0
  365. package/dist/gates/registration-roles.js +1 -0
  366. package/dist/gates/registry-liveness.d.ts +11 -0
  367. package/dist/gates/registry-liveness.d.ts.map +1 -0
  368. package/dist/gates/registry-liveness.js +13 -0
  369. package/dist/gates/rule-coverage.d.ts +187 -4
  370. package/dist/gates/rule-coverage.d.ts.map +1 -1
  371. package/dist/gates/rule-coverage.js +501 -49
  372. package/dist/gates/run-gate-planes.d.ts +14 -0
  373. package/dist/gates/run-gate-planes.d.ts.map +1 -1
  374. package/dist/gates/run-gate-planes.js +172 -30
  375. package/dist/gates/scaffold-selftest.d.ts +56 -0
  376. package/dist/gates/scaffold-selftest.d.ts.map +1 -0
  377. package/dist/gates/scaffold-selftest.js +119 -0
  378. package/dist/gates/seam-rejected-rules.d.ts +28 -0
  379. package/dist/gates/seam-rejected-rules.d.ts.map +1 -0
  380. package/dist/gates/seam-rejected-rules.js +95 -0
  381. package/dist/gates/self-test-check.d.ts +29 -0
  382. package/dist/gates/self-test-check.d.ts.map +1 -0
  383. package/dist/gates/self-test-check.js +1 -0
  384. package/dist/gates/self-test-subject.d.ts +28 -0
  385. package/dist/gates/self-test-subject.d.ts.map +1 -0
  386. package/dist/gates/self-test-subject.js +1 -0
  387. package/dist/gates/self-test.d.ts +20 -0
  388. package/dist/gates/self-test.d.ts.map +1 -0
  389. package/dist/gates/self-test.js +82 -0
  390. package/dist/gates/settle-verdict.d.ts +14 -0
  391. package/dist/gates/settle-verdict.d.ts.map +1 -0
  392. package/dist/gates/settle-verdict.js +13 -0
  393. package/dist/gates/settled-verdict.d.ts +8 -0
  394. package/dist/gates/settled-verdict.d.ts.map +1 -0
  395. package/dist/gates/settled-verdict.js +1 -0
  396. package/dist/gates/template-registry-coverage.d.ts +18 -0
  397. package/dist/gates/template-registry-coverage.d.ts.map +1 -0
  398. package/dist/gates/template-registry-coverage.js +24 -0
  399. package/dist/gates/unit-state-notes.d.ts +40 -0
  400. package/dist/gates/unit-state-notes.d.ts.map +1 -0
  401. package/dist/gates/unit-state-notes.js +71 -0
  402. package/dist/gates/verdict-line.d.ts +18 -0
  403. package/dist/gates/verdict-line.d.ts.map +1 -0
  404. package/dist/gates/verdict-line.js +40 -0
  405. package/dist/graph/graph-reuse-lookup.d.ts +10 -0
  406. package/dist/graph/graph-reuse-lookup.d.ts.map +1 -0
  407. package/dist/graph/graph-reuse-lookup.js +41 -0
  408. package/dist/graph/index-behind-hint.d.ts +11 -0
  409. package/dist/graph/index-behind-hint.d.ts.map +1 -0
  410. package/dist/graph/index-behind-hint.js +27 -0
  411. package/dist/knowledge/knowledge-stale-gate-flags.d.ts +3 -0
  412. package/dist/knowledge/knowledge-stale-gate-flags.d.ts.map +1 -0
  413. package/dist/knowledge/knowledge-stale-gate-flags.js +1 -0
  414. package/dist/knowledge/knowledge-stale-gate-input.d.ts +3 -0
  415. package/dist/knowledge/knowledge-stale-gate-input.d.ts.map +1 -0
  416. package/dist/knowledge/knowledge-stale-gate-input.js +1 -0
  417. package/dist/knowledge/knowledge-stale-gate-result.d.ts +3 -0
  418. package/dist/knowledge/knowledge-stale-gate-result.d.ts.map +1 -0
  419. package/dist/knowledge/knowledge-stale-gate-result.js +1 -0
  420. package/dist/knowledge/knowledge-stale-gate.d.ts +10 -0
  421. package/dist/knowledge/knowledge-stale-gate.d.ts.map +1 -0
  422. package/dist/knowledge/knowledge-stale-gate.js +9 -0
  423. package/dist/main.d.ts.map +1 -1
  424. package/dist/main.js +200 -83
  425. package/dist/output/failure-hints.d.ts.map +1 -1
  426. package/dist/output/failure-hints.js +11 -9
  427. package/dist/output/rejected-entries-note.d.ts +57 -0
  428. package/dist/output/rejected-entries-note.d.ts.map +1 -0
  429. package/dist/output/rejected-entries-note.js +103 -0
  430. package/dist/output/stdout-is-pipe.d.ts +13 -0
  431. package/dist/output/stdout-is-pipe.d.ts.map +1 -0
  432. package/dist/output/stdout-is-pipe.js +21 -0
  433. package/dist/packs/stale-build-warning.d.ts +11 -0
  434. package/dist/packs/stale-build-warning.d.ts.map +1 -0
  435. package/dist/packs/stale-build-warning.js +23 -0
  436. package/dist/quality/run-quality.d.ts +123 -0
  437. package/dist/quality/run-quality.d.ts.map +1 -0
  438. package/dist/quality/run-quality.js +442 -0
  439. package/dist/schemas/json-schemas.d.ts +184 -3
  440. package/dist/schemas/json-schemas.d.ts.map +1 -1
  441. package/dist/schemas/json-schemas.js +113 -2
  442. package/dist/shrk.d.ts +3 -0
  443. package/dist/shrk.d.ts.map +1 -0
  444. package/dist/shrk.js +30 -0
  445. package/dist/surface/audience-applicability.d.ts +26 -0
  446. package/dist/surface/audience-applicability.d.ts.map +1 -0
  447. package/dist/surface/audience-applicability.js +60 -0
  448. package/dist/surface/catalog-command-safety.d.ts +18 -0
  449. package/dist/surface/catalog-command-safety.d.ts.map +1 -0
  450. package/dist/surface/catalog-command-safety.js +62 -0
  451. package/dist/surface/cli-command-resolver.d.ts +21 -0
  452. package/dist/surface/cli-command-resolver.d.ts.map +1 -0
  453. package/dist/surface/cli-command-resolver.js +87 -0
  454. package/dist/surface/command-dispatch-kind.d.ts +20 -0
  455. package/dist/surface/command-dispatch-kind.d.ts.map +1 -0
  456. package/dist/surface/command-dispatch-kind.js +20 -0
  457. package/dist/surface/command-index-entry.d.ts +40 -0
  458. package/dist/surface/command-index-entry.d.ts.map +1 -0
  459. package/dist/surface/command-index-entry.js +1 -0
  460. package/dist/surface/command-index.d.ts +77 -0
  461. package/dist/surface/command-index.d.ts.map +1 -0
  462. package/dist/surface/command-index.js +323 -0
  463. package/dist/surface/i-command-index.d.ts +22 -0
  464. package/dist/surface/i-command-index.d.ts.map +1 -0
  465. package/dist/surface/i-command-index.js +1 -0
  466. package/dist/surface/i-command-string-context.d.ts +20 -0
  467. package/dist/surface/i-command-string-context.d.ts.map +1 -0
  468. package/dist/surface/i-command-string-context.js +1 -0
  469. package/dist/surface/i-surface-denial.d.ts +13 -0
  470. package/dist/surface/i-surface-denial.d.ts.map +1 -0
  471. package/dist/surface/i-surface-denial.js +1 -0
  472. package/dist/surface/load-surface-context.d.ts +17 -1
  473. package/dist/surface/load-surface-context.d.ts.map +1 -1
  474. package/dist/surface/load-surface-context.js +48 -10
  475. package/dist/surface/not-enabled-error.d.ts +38 -4
  476. package/dist/surface/not-enabled-error.d.ts.map +1 -1
  477. package/dist/surface/not-enabled-error.js +96 -6
  478. package/dist/surface/profiles.d.ts +7 -0
  479. package/dist/surface/profiles.d.ts.map +1 -1
  480. package/dist/surface/resolve-command-string.d.ts +10 -0
  481. package/dist/surface/resolve-command-string.d.ts.map +1 -0
  482. package/dist/surface/resolve-command-string.js +572 -0
  483. package/dist/surface/surface-config-writer.d.ts +7 -2
  484. package/dist/surface/surface-config-writer.d.ts.map +1 -1
  485. package/dist/surface/surface-config-writer.js +25 -6
  486. package/dist/surface/surface-layer.d.ts +11 -0
  487. package/dist/surface/surface-layer.d.ts.map +1 -0
  488. package/dist/surface/surface-layer.js +11 -0
  489. package/dist/surface/surface-refusal-reason.d.ts +16 -0
  490. package/dist/surface/surface-refusal-reason.d.ts.map +1 -0
  491. package/dist/surface/surface-refusal-reason.js +16 -0
  492. package/dist/surface/surface-selector.d.ts +26 -0
  493. package/dist/surface/surface-selector.d.ts.map +1 -0
  494. package/dist/surface/surface-selector.js +42 -0
  495. package/dist/surface/surface-summary.d.ts +61 -18
  496. package/dist/surface/surface-summary.d.ts.map +1 -1
  497. package/dist/surface/surface-summary.js +147 -60
  498. package/dist/surface/tier.d.ts +85 -22
  499. package/dist/surface/tier.d.ts.map +1 -1
  500. package/dist/surface/tier.js +132 -30
  501. package/dist/usage/usage-log.d.ts +6 -1
  502. package/dist/usage/usage-log.d.ts.map +1 -1
  503. package/dist/usage/usage-log.js +7 -2
  504. package/dist/validation/run-validation-loop.d.ts +9 -0
  505. package/dist/validation/run-validation-loop.d.ts.map +1 -1
  506. package/dist/validation/run-validation-loop.js +14 -11
  507. package/dist/validation/typecheck-emitted.d.ts +8 -9
  508. package/dist/validation/typecheck-emitted.d.ts.map +1 -1
  509. package/dist/validation/typecheck-emitted.js +17 -97
  510. package/package.json +34 -34
@@ -1,97 +1,59 @@
1
1
  import { GraphStore, GraphQueryApi } from '@shrkcrft/graph';
2
- import { resolveProjectConfig } from '@shrkcrft/inspector';
2
+ import { curatedDeclarationMap, rankReuseCandidates, resolveCuratedReuse, resolveProjectConfig, reuseImportLine, } from '@shrkcrft/inspector';
3
+ import { MatchConfidenceVerdict, ReuseCandidateSource, ReuseImportStyle, ReuseMatchSource, ReuseNameMatch, UnfollowedReExportKind, } from '@shrkcrft/core';
3
4
  import { flagBool, flagNumber, resolveCwd, } from "../command-registry.js";
5
+ import { PositionalMode } from "../dispatch/positional-mode.js";
6
+ import { ExitCode } from "../exit-codes.js";
7
+ import { graphReuseLookup } from "../graph/graph-reuse-lookup.js";
8
+ import { indexBehindHint } from "../graph/index-behind-hint.js";
4
9
  import { asJson, header } from "../output/format-output.js";
5
- const STOP = new Set([
6
- 'the', 'a', 'an', 'to', 'for', 'of', 'and', 'or', 'with', 'in', 'on', 'into', 'my',
7
- 'add', 'use', 'using', 'create', 'make', 'new', 'build', 'want', 'need', 'how', 'do',
8
- ]);
9
- function tokenize(s) {
10
- // Min length 3: 2-char tokens (`ui`, `id`) substring-match unrelated text
11
- // (`guidance`, `valid`) and produce false-positive primitive matches.
12
- return [
13
- ...new Set(s
14
- .toLowerCase()
15
- .replace(/[^a-z0-9]+/g, ' ')
16
- .split(' ')
17
- .filter((t) => t.length >= 3 && !STOP.has(t))),
18
- ];
19
- }
20
- function scorePrimitive(p, tokens) {
21
- // Substring match (so intent "debounce" matches symbol `useDebounce`); the
22
- // 3-char minimum above keeps it from over-matching on tiny fragments.
23
- const symbolLower = p.symbol.toLowerCase();
24
- const hay = [p.symbol, ...(p.roles ?? []), ...(p.keywords ?? []), p.description ?? '']
25
- .join(' ')
26
- .toLowerCase();
27
- let s = 0;
28
- const matched = [];
29
- let symbolHit = false;
30
- for (const t of tokens) {
31
- if (hay.includes(t)) {
32
- s += 1;
33
- matched.push(t);
34
- if (symbolLower.includes(t))
35
- symbolHit = true;
36
- }
37
- }
38
- // A role the intent mentions is a strong signal; re-weight role hits.
39
- for (const role of p.roles ?? []) {
40
- const rl = role.toLowerCase();
41
- if (rl.length >= 3 && tokens.some((t) => rl.includes(t)))
42
- s += 0.5;
43
- }
44
- return { score: s, matched, symbolHit };
45
- }
46
10
  /**
47
- * Confidence floor: a keyword collision is not a match. A hit is only "confident"
48
- * when it matched the symbol name itself, OR matched ≥2 distinct query tokens, OR
49
- * the query was a single token and that token hit. A single generic keyword hit on
50
- * a multi-token intent (the "nearest collision on an unrelated entry" failure mode)
51
- * is a weak match — surfaced as a did-you-mean, never as a confident answer.
11
+ * The did-you-mean ranker. The engine lives in `@shrkcrft/inspector` (pure, so
12
+ * a read-only MCP tool can call it); re-exported here for existing importers.
52
13
  */
53
- function isConfidentMatch(detail, queryTokenCount) {
54
- if (detail.matched.length === 0)
55
- return false;
56
- if (detail.symbolHit)
57
- return true;
58
- if (detail.matched.length >= 2)
59
- return true;
60
- return queryTokenCount <= 1;
61
- }
14
+ export { rankReuseSuggestions } from '@shrkcrft/inspector';
62
15
  const INDEX_RE = /(^|\/)index\.[cm]?[jt]sx?$/;
63
- /**
64
- * Rank ALL primitives by the matcher's own score (descending; ties broken by
65
- * symbol name so the order is deterministic), then return the top-`k` as scored
66
- * did-you-mean suggestions. Pure no graph, no IO — so it is directly
67
- * unit-testable. When every candidate scores 0 (a nonsense intent that shares no
68
- * term) the result is the alphabetically-first `k` primitives, each with
69
- * `score: 0`; the caller states "no candidate shares any term" in that case
70
- * rather than dumping the whole catalog.
71
- */
72
- export function rankReuseSuggestions(primitives, tokens, k) {
73
- const cap = Math.max(1, Math.floor(k));
74
- return primitives
75
- .map((p) => ({ p, detail: scorePrimitive(p, tokens) }))
76
- .sort((a, b) => b.detail.score - a.detail.score || a.p.symbol.localeCompare(b.p.symbol))
77
- .slice(0, cap)
78
- .map(({ p, detail }) => ({
79
- symbol: p.symbol,
80
- score: detail.score,
81
- confidence: tokens.length === 0 ? 0 : detail.matched.length / tokens.length,
82
- matched: detail.matched,
83
- roles: p.roles,
84
- }));
85
- }
16
+ /** Whether the uncurated public export surface was consulted, and how much of it. */
17
+ var ExportSurfaceStatus;
18
+ (function (ExportSurfaceStatus) {
19
+ /** Every workspace package root was walked in full. */
20
+ ExportSurfaceStatus["Searched"] = "searched";
21
+ /**
22
+ * Searched, but part of the surface could not be walked a package with no
23
+ * resolved entry, or a local re-export the index could not follow. `reason`
24
+ * says which; the unwalked part is listed.
25
+ */
26
+ ExportSurfaceStatus["Partial"] = "partial";
27
+ /** Nothing was searched: no graph index, or no package entry to start from. */
28
+ ExportSurfaceStatus["NotSearched"] = "not-searched";
29
+ /** `--curated-only`. */
30
+ ExportSurfaceStatus["Disabled"] = "disabled";
31
+ })(ExportSurfaceStatus || (ExportSurfaceStatus = {}));
32
+ const SOURCE_WORD = {
33
+ [ReuseMatchSource.Symbol]: 'name',
34
+ [ReuseMatchSource.Role]: 'roles',
35
+ [ReuseMatchSource.Keyword]: 'keywords',
36
+ [ReuseMatchSource.Description]: 'description',
37
+ };
38
+ const NAME_MATCH_WORDS = {
39
+ [ReuseNameMatch.Exact]: 'exact name match',
40
+ [ReuseNameMatch.Covers]: 'name covers the intent',
41
+ [ReuseNameMatch.Partial]: 'partial name match',
42
+ [ReuseNameMatch.None]: 'no name match',
43
+ };
86
44
  export const reuseCommand = {
87
45
  name: 'reuse',
88
- description: 'Intent the canonical primitive to reuse. Matches your intent against configured reusePrimitives[], then resolves the symbol in the code graph to its declaration, public import path, sibling exports, and real consumer files to copy. Deterministic; no AI.',
89
- usage: 'shrk reuse "<what I want to build>" [--limit N] [--all] [--json]',
90
- booleanFlags: new Set(['json', 'all']),
46
+ // The positionals are the free-form intent (`coverage` is a trie child).
47
+ positionals: PositionalMode.Free,
48
+ description: 'Intent → the canonical primitive to reuse. Ranks configured reusePrimitives[] AND (with a code graph) the uncurated public export surface of every workspace package — an exactly-named exported construct outranks a curated entry that names only part of the intent or matched only through its metadata, and is labelled uncurated. Resolves each answer to its declaration, public import path (a default import for a default export), sibling exports and real consumer files. `shrk reuse coverage` measures curation drift. Deterministic; no AI.',
49
+ usage: 'shrk reuse "<what I want to build>" [--limit N] [--all] [--curated-only] [--include-types] [--json] · shrk reuse coverage',
50
+ booleanFlags: new Set(['json', 'all', 'curated-only', 'include-types']),
91
51
  async run(args) {
92
52
  const cwd = resolveCwd(args);
93
53
  const wantJson = flagBool(args, 'json');
94
54
  const wantAll = flagBool(args, 'all');
55
+ const curatedOnly = flagBool(args, 'curated-only');
56
+ const includeTypes = flagBool(args, 'include-types');
95
57
  // `--limit N` caps both the confident results (historic default 3) and the
96
58
  // did-you-mean suggestion list. When omitted, suggestions default to 5 (a
97
59
  // couple more than results — the point of a did-you-mean is a short menu).
@@ -100,8 +62,8 @@ export const reuseCommand = {
100
62
  const suggestK = limitFlag ?? 5;
101
63
  const intent = args.positional.join(' ').trim();
102
64
  if (!intent) {
103
- process.stderr.write('Usage: shrk reuse "<what I want to build>" [--limit N] [--all] [--json]\n');
104
- return 2;
65
+ process.stderr.write('Usage: shrk reuse "<what I want to build>" [--limit N] [--all] [--curated-only] [--include-types] [--json]\n');
66
+ return ExitCode.UsageError;
105
67
  }
106
68
  const loaded = await resolveProjectConfig(cwd);
107
69
  if (!loaded.ok) {
@@ -124,193 +86,180 @@ export const reuseCommand = {
124
86
  for (const d of planeDiagnostics)
125
87
  process.stdout.write(` ! ${d}\n`);
126
88
  };
127
- if (primitives.length === 0) {
128
- if (wantJson) {
129
- process.stdout.write(asJson({ schema: 'sharkcraft.reuse/v1', intent, results: [], ...planeJson }) + '\n');
130
- return 0;
131
- }
132
- process.stdout.write(header(`Reuse: "${intent}"`));
133
- process.stdout.write(' No reuse primitives configured. Declare `reusePrimitives[]` in sharkcraft.config.ts\n' +
134
- ' to map roles/intents to canonical symbols (see docs/reuse.md).\n');
135
- writePlaneNotes();
136
- return 0;
137
- }
138
- const tokens = tokenize(intent);
139
- const confidenceOf = (matched) => tokens.length === 0 ? 0 : matched / tokens.length;
140
- const scored = primitives
141
- .map((p) => ({ p, detail: scorePrimitive(p, tokens) }))
142
- .filter((x) => x.detail.score > 0)
143
- .sort((a, b) => b.detail.score - a.detail.score || a.p.symbol.localeCompare(b.p.symbol));
144
- const confident = scored.filter((x) => isConfidentMatch(x.detail, tokens.length));
145
- const ranked = confident.slice(0, Math.max(1, limit));
146
89
  const store = new GraphStore(cwd);
147
90
  const api = store.exists() ? GraphQueryApi.fromStore(cwd) : null;
148
- // Zero keyword overlap: nothing matched at all. Rather than dump the entire
149
- // declared catalog (dozens of lines an agent must re-read), rank ALL
150
- // candidates and surface the nearest top-K by name every score is 0 here,
151
- // so this is an alphabetized short menu, stated as such. The full catalog is
152
- // available only behind an explicit `--all`.
153
- if (scored.length === 0) {
154
- const suggestions = rankReuseSuggestions(primitives, tokens, suggestK);
155
- const roles = [...new Set(primitives.flatMap((p) => p.roles))].sort();
156
- if (wantJson) {
157
- process.stdout.write(asJson({
158
- schema: 'sharkcraft.reuse/v1',
159
- intent,
160
- confident: false,
161
- results: [],
162
- suggestions,
163
- ...(wantAll ? { availableRoles: roles } : {}),
164
- ...planeJson,
165
- }) + '\n');
166
- return 0;
91
+ // The public surface, whenever a graph exists: the uncurated candidates
92
+ // (unless --curated-only), AND always how a curated `importPath`
93
+ // exports its symbol, so the printed import line compiles. Lazy + memoized.
94
+ const fullSurface = api ? api.publicExportSurface() : undefined;
95
+ const lookup = api ? graphReuseLookup(api) : undefined;
96
+ // ONE resolution per curated entry — the record `shrk reuse coverage` judges
97
+ // the entry by: its construct, its import line, whether that compiles.
98
+ const resolutionList = primitives.map((p) => resolveCuratedReuse(p, fullSurface, lookup));
99
+ const resolutions = new Map(primitives.map((p, i) => [p, resolutionList[i]]));
100
+ // The uncurated export surface — searched whenever a graph exists and has a
101
+ // package root, unless the caller asked for the curated index alone. A
102
+ // skipped (or partial) search is said out loud: "no uncurated match" and
103
+ // "never looked" must not read alike.
104
+ let surface;
105
+ let exportSurface;
106
+ if (curatedOnly) {
107
+ exportSurface = { status: ExportSurfaceStatus.Disabled, reason: '--curated-only', roots: 0, packagesWithoutEntry: [], size: 0 };
108
+ }
109
+ else if (!fullSurface) {
110
+ exportSurface = {
111
+ status: ExportSurfaceStatus.NotSearched,
112
+ reason: 'no graph index — run `shrk graph index`',
113
+ roots: 0,
114
+ packagesWithoutEntry: [],
115
+ size: 0,
116
+ };
117
+ }
118
+ else if (fullSurface.roots.length === 0) {
119
+ // Zero roots walked is "never looked", never "looked, found nothing".
120
+ exportSurface = {
121
+ status: ExportSurfaceStatus.NotSearched,
122
+ reason: fullSurface.packagesWithoutEntry.length > 0
123
+ ? 'no package entry resolves to an indexed file'
124
+ : 'no workspace packages (package.json `workspaces`)',
125
+ roots: 0,
126
+ packagesWithoutEntry: fullSurface.packagesWithoutEntry.map((p) => ({ package: p.package, reason: p.reason })),
127
+ size: 0,
128
+ };
129
+ }
130
+ else {
131
+ surface = fullSurface;
132
+ const local = fullSurface.unfollowedReExports.filter((u) => u.kind === UnfollowedReExportKind.Unresolved);
133
+ const gaps = [];
134
+ if (fullSurface.packagesWithoutEntry.length > 0) {
135
+ const total = fullSurface.roots.length + fullSurface.packagesWithoutEntry.length;
136
+ gaps.push(`${fullSurface.packagesWithoutEntry.length} of ${total} package(s) have no resolved entry`);
167
137
  }
168
- process.stdout.write(header(`Reuse: "${intent}"`));
169
- if (wantAll) {
170
- process.stdout.write(' No primitive matched — no candidate shares any term — showing full catalog:\n');
171
- for (const r of roles.slice(0, 40))
172
- process.stdout.write(` • ${r}\n`);
138
+ if (local.length > 0)
139
+ gaps.push(`${local.length} re-export(s) the index could not follow`);
140
+ exportSurface = {
141
+ status: gaps.length > 0 ? ExportSurfaceStatus.Partial : ExportSurfaceStatus.Searched,
142
+ ...(gaps.length > 0 ? { reason: gaps.join('; ') } : {}),
143
+ roots: fullSurface.roots.length,
144
+ packagesWithoutEntry: fullSurface.packagesWithoutEntry.map((p) => ({ package: p.package, reason: p.reason })),
145
+ size: fullSurface.exports.length,
146
+ ...(fullSurface.unfollowedReExports.length > 0
147
+ ? {
148
+ unresolvedReExports: fullSurface.unfollowedReExports.length,
149
+ unfollowedReExports: [...fullSurface.unfollowedReExports],
150
+ }
151
+ : {}),
152
+ };
153
+ }
154
+ // The curated constructs, by resolved declaration — exactly the exclusion
155
+ // `shrk reuse coverage` applies (a same-named export of a DIFFERENT
156
+ // construct stays a candidate).
157
+ const curatedDeclaredIn = api ? curatedDeclarationMap(primitives, resolutionList) : undefined;
158
+ const ranking = rankReuseCandidates(primitives, surface, intent, {
159
+ limit,
160
+ suggestLimit: suggestK,
161
+ includeTypes,
162
+ curatedOnly,
163
+ ...(curatedDeclaredIn ? { curatedDeclaredIn } : {}),
164
+ });
165
+ const confidenceJson = {
166
+ confident: ranking.confident,
167
+ verdict: ranking.verdict,
168
+ floor: ranking.floor,
169
+ bestScore: ranking.bestScore,
170
+ };
171
+ // The miss path only (nothing matched by NAME): is the index behind? The
172
+ // freshness walk is not free, so it never runs on a hit.
173
+ const behind = api && !ranking.nameAnswered ? indexBehindHint(cwd) : null;
174
+ const surfaceJson = {
175
+ exportSurface,
176
+ curationGap: ranking.curationGap,
177
+ superseded: ranking.superseded,
178
+ ...(behind ? { indexBehind: behind } : {}),
179
+ };
180
+ const writeSurfaceNotes = () => {
181
+ if (exportSurface.status === ExportSurfaceStatus.NotSearched) {
182
+ process.stdout.write(api
183
+ ? ` ⚠ uncurated export surface NOT searched (${exportSurface.reason ?? 'no package root'})\n`
184
+ : ' ⚠ uncurated export surface NOT searched (no graph index) — run `shrk graph index`\n');
173
185
  }
174
- else {
175
- process.stdout.write(' No strong match no candidate shares any term with the intent.\n' +
176
- ' Nearest primitives (pass --all for the full catalog):\n');
177
- for (const s of suggestions) {
178
- process.stdout.write(` • ${s.symbol} (score ${s.score}; roles: ${s.roles.join(', ') || '—'})\n`);
179
- }
186
+ const byReason = new Map();
187
+ for (const p of exportSurface.packagesWithoutEntry) {
188
+ const list = byReason.get(p.reason);
189
+ if (list)
190
+ list.push(p.package);
191
+ else
192
+ byReason.set(p.reason, [p.package]);
180
193
  }
181
- writePlaneNotes();
182
- return 0;
183
- }
184
- // Weak overlap only (a single generic keyword collision on an unrelated
185
- // entry): below the confidence floor. A miss must look like a miss — never
186
- // return the nearest collision as a confident answer. Offer did-you-mean.
187
- if (ranked.length === 0) {
188
- // Rank the weakly-overlapping candidates (score > 0) and cap at K — never
189
- // the whole catalog. `suggestions` and the legacy `didYouMean` alias carry
190
- // the same scored rows; `--all` additionally dumps every declared role.
191
- const suggestions = scored.slice(0, Math.max(1, suggestK)).map((x) => ({
192
- symbol: x.p.symbol,
193
- score: x.detail.score,
194
- confidence: confidenceOf(x.detail.matched.length),
195
- matched: x.detail.matched,
196
- roles: x.p.roles,
197
- }));
198
- const roles = [...new Set(primitives.flatMap((p) => p.roles))].sort();
199
- if (wantJson) {
200
- process.stdout.write(asJson({
201
- schema: 'sharkcraft.reuse/v1',
202
- intent,
203
- confident: false,
204
- results: [],
205
- suggestions,
206
- didYouMean: suggestions,
207
- ...(wantAll ? { availableRoles: roles } : {}),
208
- ...planeJson,
209
- }) + '\n');
210
- return 0;
194
+ for (const [reason, pkgs] of byReason) {
195
+ const shown = pkgs.slice(0, 4).join(', ') + (pkgs.length > 4 ? `, +${pkgs.length - 4} more` : '');
196
+ process.stdout.write(` ⚠ ${pkgs.length} package(s) not searched — ${reason} (${shown})\n`);
211
197
  }
212
- process.stdout.write(header(`Reuse: "${intent}"`));
213
- process.stdout.write(' No confident match the intent only weakly overlaps existing primitives.\n' +
214
- ' Did you mean (weak, verify before reusing):\n');
215
- for (const s of suggestions) {
216
- process.stdout.write(` • ${s.symbol} (score ${s.score}, ${Math.round(s.confidence * 100)}% of intent; matched: ${s.matched.join(', ') || '—'})\n`);
198
+ const unfollowed = exportSurface.unfollowedReExports ?? [];
199
+ const local = unfollowed.filter((u) => u.kind === UnfollowedReExportKind.Unresolved);
200
+ if (local.length > 0) {
201
+ const shown = local.slice(0, 3).map(formatUnfollowed).join(', ') + (local.length > 3 ? `, +${local.length - 3} more` : '');
202
+ process.stdout.write(` ${local.length} re-export(s) not followed — part of the surface NOT searched (${shown})\n`);
217
203
  }
218
- if (wantAll) {
219
- process.stdout.write(' Full catalog (all declared roles):\n');
220
- for (const r of roles.slice(0, 40))
221
- process.stdout.write(` • ${r}\n`);
204
+ const external = unfollowed.length - local.length;
205
+ if (external > 0) {
206
+ process.stdout.write(` (${external} re-export(s) of modules outside the workspace not followed)\n`);
222
207
  }
223
- writePlaneNotes();
224
- return 0;
225
- }
226
- const results = ranked.map(({ p, detail }) => {
227
- const score = detail.score;
228
- const r = {
229
- symbol: p.symbol,
230
- score,
231
- confidence: confidenceOf(detail.matched.length),
232
- matched: detail.matched,
233
- roles: p.roles,
234
- siblings: [],
235
- consumers: [],
236
- };
237
- if (p.description)
238
- r.description = p.description;
239
- if (p.importPath)
240
- r.importPath = p.importPath;
241
- if (api) {
242
- // Disambiguate same-named declarations deterministically: prefer
243
- // exported symbols, then shallowest path; disclose the alternates.
244
- const candidates = api
245
- .findSymbol(p.symbol, { exact: true })
246
- .slice()
247
- .sort((a, b) => (a.path ?? '').localeCompare(b.path ?? ''));
248
- const exported = candidates.filter((c) => c.data?.['isExported'] === true);
249
- const pool = exported.length > 0 ? exported : candidates;
250
- const sym = pool[0];
251
- if (sym) {
252
- if (sym.path)
253
- r.declaredIn = sym.path;
254
- if (sym.line)
255
- r.declaredLine = sym.line;
256
- if (sym.path) {
257
- const fileNode = api.findFile(sym.path);
258
- if (fileNode) {
259
- r.siblings = api
260
- .symbolsIn(fileNode.id)
261
- .filter((s) => s.data?.['isExported'] === true && s.label && s.label !== p.symbol)
262
- .map((s) => s.label)
263
- .slice(0, 8);
264
- // When no public importPath is configured, surface a re-exporting
265
- // barrel as a hint (we never fabricate a module specifier from a
266
- // deep file path — that would be a broken/unusable import).
267
- if (!r.importPath) {
268
- const barrel = api.importersOf(fileNode.id).find((n) => n.path && INDEX_RE.test(n.path));
269
- if (barrel?.path)
270
- r.reExportedVia = barrel.path;
271
- }
272
- }
273
- }
274
- const sites = api.referenceSitesOf(sym.id);
275
- r.consumerTotal = sites.length;
276
- r.consumers = sites
277
- .slice(0, 5)
278
- .map((s) => ({ path: s.node.path ?? s.node.id, ...(s.line ? { line: s.line } : {}) }));
279
- const alts = pool.slice(1).map((c) => c.path).filter((x) => !!x);
280
- if (alts.length > 0)
281
- r.alternates = alts;
282
- }
283
- else {
284
- r.notFound = true;
285
- }
208
+ for (const s of ranking.superseded) {
209
+ process.stdout.write(` (superseded: ${s.symbol} from ${s.package} → use ${s.supersededBy.join(' / ')} — per reusePrimitives[].supersedes)\n`);
286
210
  }
287
- // The import line is emitted ONLY from a configured importPath (a clean,
288
- // copy-pasteable specifier). Without it we show declaration + barrel hint.
289
- if (r.importPath)
290
- r.importLine = `import { ${p.symbol} } from '${r.importPath}';`;
291
- return r;
292
- });
211
+ if (behind)
212
+ process.stdout.write(` ⚠ ${behind}\n`);
213
+ };
214
+ if (ranking.results.length === 0) {
215
+ return writeNoAnswer({
216
+ intent,
217
+ ranking,
218
+ primitivesCount: primitives.length,
219
+ roles: [...new Set(primitives.flatMap((p) => p.roles))].sort(),
220
+ wantJson,
221
+ wantAll,
222
+ extraJson: { ...confidenceJson, ...surfaceJson, ...planeJson },
223
+ writeNotes: () => {
224
+ writePlaneNotes();
225
+ writeSurfaceNotes();
226
+ },
227
+ });
228
+ }
229
+ const results = ranking.results.map((c) => enrichResult(c, api, c.primitive ? resolutions.get(c.primitive) : undefined));
293
230
  if (wantJson) {
294
- process.stdout.write(asJson({ schema: 'sharkcraft.reuse/v1', intent, graphIndexed: !!api, results, ...planeJson }) + '\n');
231
+ process.stdout.write(asJson({
232
+ schema: 'sharkcraft.reuse/v1',
233
+ intent,
234
+ graphIndexed: !!api,
235
+ ...confidenceJson,
236
+ results,
237
+ ...surfaceJson,
238
+ ...planeJson,
239
+ }) + '\n');
295
240
  return 0;
296
241
  }
297
242
  process.stdout.write(header(`Reuse: "${intent}"`));
298
243
  writePlaneNotes();
244
+ writeSurfaceNotes();
299
245
  if (!api) {
300
246
  process.stdout.write(' (code graph missing — import path/siblings/consumers limited; run `shrk graph index`)\n');
301
247
  }
302
248
  let i = 0;
303
249
  for (const r of results) {
304
250
  i += 1;
305
- process.stdout.write(`\n${i}. ${r.symbol}\n`);
251
+ process.stdout.write(`\n${i}. ${r.symbol} [${resultLabel(r)}]\n`);
306
252
  if (r.description)
307
253
  process.stdout.write(` ${r.description}\n`);
308
- process.stdout.write(` match: score ${r.score} (${Math.round(r.confidence * 100)}% of intent; matched: ${r.matched.join(', ') || '—'})\n`);
254
+ process.stdout.write(` match: ${matchLine(r)}\n`);
309
255
  if (r.notFound) {
310
256
  process.stdout.write(' ⚠ symbol not found in the code graph — verify reusePrimitives[].symbol (typo/rename?) or run `shrk graph index`\n');
311
257
  }
312
258
  if (r.importLine) {
313
259
  process.stdout.write(` import: ${r.importLine}\n`);
260
+ if (r.importPathAgrees === false) {
261
+ process.stdout.write(` ⚠ '${r.importPath}' does not export ${r.symbol} (per the index) — this import would not compile; see \`shrk reuse coverage\`\n`);
262
+ }
314
263
  }
315
264
  else if (r.reExportedVia) {
316
265
  process.stdout.write(` re-exported via: ${r.reExportedVia} (set reusePrimitives[].importPath for a copy-paste import)\n`);
@@ -318,6 +267,8 @@ export const reuseCommand = {
318
267
  if (r.declaredIn) {
319
268
  process.stdout.write(` declared in: ${r.declaredIn}${r.declaredLine ? ':' + r.declaredLine : ''}\n`);
320
269
  }
270
+ if (r.via && r.via.length > 0)
271
+ process.stdout.write(` reached via: ${r.via.join(' → ')}\n`);
321
272
  if (r.alternates && r.alternates.length > 0) {
322
273
  process.stdout.write(` ⚠ name also declared in: ${r.alternates.join(', ')}\n`);
323
274
  }
@@ -333,6 +284,206 @@ export const reuseCommand = {
333
284
  process.stdout.write(` - ${c.path}${c.line ? ':' + c.line : ''}\n`);
334
285
  }
335
286
  }
287
+ if (ranking.curationGap) {
288
+ process.stdout.write('\n ⚠ Curation gap: an uncurated export matches this intent by NAME, while the best curated\n' +
289
+ ' candidate names only part of it, or matched only through its roles/keywords/description.\n' +
290
+ ' Add the export to reusePrimitives[] — or list it in the curated entry\'s `supersedes` — and\n' +
291
+ ' run `shrk reuse coverage` to see every such gap.\n');
292
+ }
336
293
  return 0;
337
294
  },
338
295
  };
296
+ /** No confident answer: a weak did-you-mean, or a plain "nothing shares a term". */
297
+ function writeNoAnswer(o) {
298
+ const { ranking, wantAll } = o;
299
+ const suggestions = ranking.suggestions;
300
+ const weak = ranking.verdict === MatchConfidenceVerdict.NoConfidentMatch;
301
+ if (o.wantJson) {
302
+ process.stdout.write(asJson({
303
+ schema: 'sharkcraft.reuse/v1',
304
+ intent: o.intent,
305
+ results: [],
306
+ suggestions,
307
+ // The legacy alias, kept on the weak branch where it always lived.
308
+ ...(weak ? { didYouMean: suggestions } : {}),
309
+ ...(wantAll ? { availableRoles: o.roles } : {}),
310
+ ...o.extraJson,
311
+ }) + '\n');
312
+ return 0;
313
+ }
314
+ process.stdout.write(header(`Reuse: "${o.intent}"`));
315
+ if (o.primitivesCount === 0) {
316
+ process.stdout.write(' No reuse primitives configured. Declare `reusePrimitives[]` in sharkcraft.config.ts\n' +
317
+ ' to map roles/intents to canonical symbols (see docs/reuse.md).\n');
318
+ }
319
+ if (weak) {
320
+ // Weak overlap only (a single generic keyword collision on an unrelated
321
+ // entry, or an export sharing only part of the name): below the confidence
322
+ // floor. A miss must look like a miss — never the nearest collision as an answer.
323
+ process.stdout.write(' No confident match — the intent only weakly overlaps existing candidates.\n' +
324
+ ' Did you mean (weak, verify before reusing):\n');
325
+ for (const s of suggestions)
326
+ process.stdout.write(` • ${suggestionLine(s)}\n`);
327
+ if (wantAll) {
328
+ process.stdout.write(' Full catalog (all declared roles):\n');
329
+ for (const r of o.roles.slice(0, 40))
330
+ process.stdout.write(` • ${r}\n`);
331
+ }
332
+ }
333
+ else if (o.primitivesCount > 0) {
334
+ // Zero overlap: rather than dump the whole catalog, the alphabetized
335
+ // nearest top-K (every score is 0 here), stated as such. The full catalog
336
+ // is available only behind an explicit `--all`.
337
+ if (wantAll) {
338
+ process.stdout.write(' No primitive matched — no candidate shares any term — showing full catalog:\n');
339
+ for (const r of o.roles.slice(0, 40))
340
+ process.stdout.write(` • ${r}\n`);
341
+ }
342
+ else {
343
+ process.stdout.write(' No strong match — no candidate shares any term with the intent.\n' +
344
+ ' Nearest primitives (pass --all for the full catalog):\n');
345
+ for (const s of suggestions) {
346
+ process.stdout.write(` • ${s.symbol} (score ${s.score}; roles: ${s.roles.join(', ') || '—'})\n`);
347
+ }
348
+ }
349
+ }
350
+ o.writeNotes();
351
+ return 0;
352
+ }
353
+ /**
354
+ * Resolve one ranked candidate through the code graph (declaration, import,
355
+ * siblings, consumers). A curated row is printed from its
356
+ * `IReuseCuratedResolution` — the SAME record `shrk reuse coverage` judges the
357
+ * entry by — so the declaration shown and the import line printed are the ones
358
+ * the coverage verdict checked.
359
+ */
360
+ function enrichResult(c, api, res) {
361
+ const r = {
362
+ symbol: c.symbol,
363
+ source: c.source,
364
+ score: c.score,
365
+ confidence: c.confidence,
366
+ matched: c.matched,
367
+ matchedVia: c.matchedVia,
368
+ nameMatch: c.nameMatch,
369
+ roles: c.primitive?.roles ?? [],
370
+ siblings: [],
371
+ consumers: [],
372
+ };
373
+ const p = c.primitive;
374
+ if (p) {
375
+ if (p.description)
376
+ r.description = p.description;
377
+ if (p.importPath) {
378
+ r.importPath = p.importPath;
379
+ // The import line is emitted ONLY from a real specifier (the configured
380
+ // importPath), bound the way its module exports the symbol.
381
+ const style = res?.importStyle ?? ReuseImportStyle.Named;
382
+ r.importLine = res?.importLine ?? reuseImportLine(p.symbol, p.importPath, style);
383
+ r.importStyle = style;
384
+ if (style === ReuseImportStyle.Default)
385
+ r.isDefault = true;
386
+ }
387
+ if (res?.importPathAgrees !== undefined)
388
+ r.importPathAgrees = res.importPathAgrees;
389
+ if (api) {
390
+ const d = res?.declaration;
391
+ if (d) {
392
+ r.declaredIn = d.path;
393
+ if (d.line)
394
+ r.declaredLine = d.line;
395
+ const fileNode = api.findFile(d.path);
396
+ if (fileNode) {
397
+ r.siblings = exportedSiblings(api, fileNode.id, d.symbolId);
398
+ // When no public importPath is configured, surface a re-exporting
399
+ // barrel as a hint (we never fabricate a module specifier from a
400
+ // deep file path — that would be a broken/unusable import).
401
+ if (!r.importPath) {
402
+ const barrel = api.importersOf(fileNode.id).find((n) => n.path && INDEX_RE.test(n.path));
403
+ if (barrel?.path)
404
+ r.reExportedVia = barrel.path;
405
+ }
406
+ }
407
+ setConsumers(r, api, d.symbolId);
408
+ if (res && res.alternates.length > 0)
409
+ r.alternates = [...res.alternates];
410
+ }
411
+ else {
412
+ r.notFound = true;
413
+ }
414
+ }
415
+ }
416
+ else if (c.export) {
417
+ // Uncurated: the package name IS a real, copy-pasteable specifier — the
418
+ // construct is reachable from that package's root entry, which is exactly
419
+ // the file `import … from '<pkg>'` resolves to. Nothing is fabricated.
420
+ const e = c.export;
421
+ r.package = e.package;
422
+ r.importPath = e.package;
423
+ r.declaredIn = e.declaredIn;
424
+ if (e.line)
425
+ r.declaredLine = e.line;
426
+ r.via = e.via;
427
+ const style = e.isDefault === true ? ReuseImportStyle.Default : ReuseImportStyle.Named;
428
+ if (e.isDefault)
429
+ r.isDefault = true;
430
+ r.importStyle = style;
431
+ r.importLine = reuseImportLine(c.symbol, e.package, style);
432
+ if (api) {
433
+ const fileNode = api.findFile(e.declaredIn);
434
+ if (fileNode)
435
+ r.siblings = exportedSiblings(api, fileNode.id, e.symbolId);
436
+ setConsumers(r, api, e.symbolId);
437
+ }
438
+ }
439
+ return r;
440
+ }
441
+ function exportedSiblings(api, fileNodeId, selfId) {
442
+ return api
443
+ .symbolsIn(fileNodeId)
444
+ .filter((s) => s.data?.['isExported'] === true && s.label && s.id !== selfId)
445
+ .map((s) => s.label)
446
+ .slice(0, 8);
447
+ }
448
+ function setConsumers(r, api, symbolId) {
449
+ const sites = api.referenceSitesOf(symbolId);
450
+ r.consumerTotal = sites.length;
451
+ r.consumers = sites
452
+ .slice(0, 5)
453
+ .map((s) => ({ path: s.node.path ?? s.node.id, ...(s.line ? { line: s.line } : {}) }));
454
+ }
455
+ function formatUnfollowed(u) {
456
+ return `${u.file} → '${u.specifier}'${u.name === '*' ? '' : ` { ${u.name} }`}`;
457
+ }
458
+ /** `[uncurated · exported by @demo/ui · exact name match]` / `[curated · via keywords — not its name]`. */
459
+ function resultLabel(r) {
460
+ if (r.source === ReuseCandidateSource.ExportSurface) {
461
+ return `uncurated · exported by ${r.package ?? '?'} · ${NAME_MATCH_WORDS[r.nameMatch]}`;
462
+ }
463
+ if (r.nameMatch === ReuseNameMatch.None)
464
+ return `curated · via ${metadataVia(r)} — not its name`;
465
+ return `curated · ${NAME_MATCH_WORDS[r.nameMatch]}`;
466
+ }
467
+ function matchLine(r) {
468
+ const pct = Math.round(r.confidence * 100);
469
+ const matched = r.matched.join(', ') || '—';
470
+ if (r.source === ReuseCandidateSource.Curated && r.nameMatch === ReuseNameMatch.None) {
471
+ // The honesty qualifier: a high percentage earned only through metadata
472
+ // must not read like a name match.
473
+ return `score ${r.score} (${pct}% of intent — via ${metadataVia(r)}; not its name; matched: ${matched})`;
474
+ }
475
+ return `score ${r.score} (${pct}% of intent; matched: ${matched})`;
476
+ }
477
+ function metadataVia(r) {
478
+ const words = r.matchedVia.filter((v) => v !== ReuseMatchSource.Symbol).map((v) => SOURCE_WORD[v]);
479
+ return words.length > 0 ? words.join(', ') : 'metadata';
480
+ }
481
+ function suggestionLine(s) {
482
+ const pct = Math.round(s.confidence * 100);
483
+ const matched = s.matched.join(', ') || '—';
484
+ if (s.source === ReuseCandidateSource.ExportSurface) {
485
+ return `${s.symbol} (uncurated · exported by ${s.package ?? '?'} · ${NAME_MATCH_WORDS[s.nameMatch]}; score ${s.score}, ${pct}% of intent; matched: ${matched})`;
486
+ }
487
+ const via = s.nameMatch === ReuseNameMatch.None ? ` — via ${metadataVia(s)}, not its name` : '';
488
+ return `${s.symbol} (score ${s.score}, ${pct}% of intent; matched: ${matched}${via})`;
489
+ }