@shrkcrft/cli 0.1.0-alpha.2 → 0.1.0-alpha.20

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 (228) hide show
  1. package/dist/audit/knowledge-audit-llm.d.ts +19 -0
  2. package/dist/audit/knowledge-audit-llm.d.ts.map +1 -0
  3. package/dist/audit/knowledge-audit-llm.js +164 -0
  4. package/dist/audit/knowledge-audit.d.ts +61 -0
  5. package/dist/audit/knowledge-audit.d.ts.map +1 -0
  6. package/dist/audit/knowledge-audit.js +203 -0
  7. package/dist/audit/knowledge-fix-plan-llm.d.ts +11 -0
  8. package/dist/audit/knowledge-fix-plan-llm.d.ts.map +1 -0
  9. package/dist/audit/knowledge-fix-plan-llm.js +141 -0
  10. package/dist/audit/knowledge-fix-plan.d.ts +41 -0
  11. package/dist/audit/knowledge-fix-plan.d.ts.map +1 -0
  12. package/dist/audit/knowledge-fix-plan.js +125 -0
  13. package/dist/audit/pipeline-audit-llm.d.ts +11 -0
  14. package/dist/audit/pipeline-audit-llm.d.ts.map +1 -0
  15. package/dist/audit/pipeline-audit-llm.js +134 -0
  16. package/dist/audit/pipeline-audit.d.ts +69 -0
  17. package/dist/audit/pipeline-audit.d.ts.map +1 -0
  18. package/dist/audit/pipeline-audit.js +166 -0
  19. package/dist/audit/templates-audit-llm.d.ts +19 -0
  20. package/dist/audit/templates-audit-llm.d.ts.map +1 -0
  21. package/dist/audit/templates-audit-llm.js +207 -0
  22. package/dist/audit/templates-audit.d.ts +63 -0
  23. package/dist/audit/templates-audit.d.ts.map +1 -0
  24. package/dist/audit/templates-audit.js +171 -0
  25. package/dist/audit/templates-fix-plan-llm.d.ts +19 -0
  26. package/dist/audit/templates-fix-plan-llm.d.ts.map +1 -0
  27. package/dist/audit/templates-fix-plan-llm.js +162 -0
  28. package/dist/audit/templates-fix-plan.d.ts +37 -0
  29. package/dist/audit/templates-fix-plan.d.ts.map +1 -0
  30. package/dist/audit/templates-fix-plan.js +174 -0
  31. package/dist/command-registry.d.ts +28 -0
  32. package/dist/command-registry.d.ts.map +1 -1
  33. package/dist/command-registry.js +91 -1
  34. package/dist/commands/ai-status.command.d.ts +19 -0
  35. package/dist/commands/ai-status.command.d.ts.map +1 -0
  36. package/dist/commands/ai-status.command.js +94 -0
  37. package/dist/commands/api-diff.command.d.ts +11 -0
  38. package/dist/commands/api-diff.command.d.ts.map +1 -0
  39. package/dist/commands/api-diff.command.js +144 -0
  40. package/dist/commands/apply.command.d.ts.map +1 -1
  41. package/dist/commands/apply.command.js +10 -2
  42. package/dist/commands/arch.command.d.ts +9 -0
  43. package/dist/commands/arch.command.d.ts.map +1 -0
  44. package/dist/commands/arch.command.js +186 -0
  45. package/dist/commands/ask.command.d.ts.map +1 -1
  46. package/dist/commands/ask.command.js +10 -9
  47. package/dist/commands/cache-align.command.d.ts +12 -0
  48. package/dist/commands/cache-align.command.d.ts.map +1 -0
  49. package/dist/commands/cache-align.command.js +78 -0
  50. package/dist/commands/check.command.d.ts.map +1 -1
  51. package/dist/commands/check.command.js +19 -2
  52. package/dist/commands/code-intel.command.d.ts +18 -0
  53. package/dist/commands/code-intel.command.d.ts.map +1 -0
  54. package/dist/commands/code-intel.command.js +146 -0
  55. package/dist/commands/codemod.command.d.ts.map +1 -1
  56. package/dist/commands/codemod.command.js +27 -6
  57. package/dist/commands/command-catalog.d.ts +15 -3
  58. package/dist/commands/command-catalog.d.ts.map +1 -1
  59. package/dist/commands/command-catalog.js +387 -34
  60. package/dist/commands/commands.command.d.ts.map +1 -1
  61. package/dist/commands/commands.command.js +4 -4
  62. package/dist/commands/completion.command.d.ts +10 -0
  63. package/dist/commands/completion.command.d.ts.map +1 -0
  64. package/dist/commands/completion.command.js +121 -0
  65. package/dist/commands/compress.command.d.ts +8 -0
  66. package/dist/commands/compress.command.d.ts.map +1 -0
  67. package/dist/commands/compress.command.js +147 -0
  68. package/dist/commands/constructs.command.d.ts.map +1 -1
  69. package/dist/commands/constructs.command.js +89 -23
  70. package/dist/commands/context.command.d.ts.map +1 -1
  71. package/dist/commands/context.command.js +121 -1
  72. package/dist/commands/contract-gate.command.d.ts.map +1 -1
  73. package/dist/commands/contract-gate.command.js +5 -1
  74. package/dist/commands/delegate.command.d.ts +65 -0
  75. package/dist/commands/delegate.command.d.ts.map +1 -0
  76. package/dist/commands/delegate.command.js +657 -0
  77. package/dist/commands/deps-audit.command.d.ts +23 -0
  78. package/dist/commands/deps-audit.command.d.ts.map +1 -0
  79. package/dist/commands/deps-audit.command.js +270 -0
  80. package/dist/commands/dev.command.d.ts.map +1 -1
  81. package/dist/commands/dev.command.js +5 -1
  82. package/dist/commands/diff-check.command.d.ts +30 -0
  83. package/dist/commands/diff-check.command.d.ts.map +1 -0
  84. package/dist/commands/diff-check.command.js +210 -0
  85. package/dist/commands/doctor.command.d.ts.map +1 -1
  86. package/dist/commands/doctor.command.js +162 -10
  87. package/dist/commands/export.command.d.ts.map +1 -1
  88. package/dist/commands/export.command.js +76 -3
  89. package/dist/commands/framework.command.d.ts +12 -0
  90. package/dist/commands/framework.command.d.ts.map +1 -0
  91. package/dist/commands/framework.command.js +180 -0
  92. package/dist/commands/gate.command.d.ts +15 -0
  93. package/dist/commands/gate.command.d.ts.map +1 -0
  94. package/dist/commands/gate.command.js +300 -0
  95. package/dist/commands/gen.command.d.ts.map +1 -1
  96. package/dist/commands/gen.command.js +13 -1
  97. package/dist/commands/graph-code-subverbs.d.ts +33 -0
  98. package/dist/commands/graph-code-subverbs.d.ts.map +1 -0
  99. package/dist/commands/graph-code-subverbs.js +1366 -0
  100. package/dist/commands/graph.command.d.ts.map +1 -1
  101. package/dist/commands/graph.command.js +31 -2
  102. package/dist/commands/help.command.d.ts +4 -3
  103. package/dist/commands/help.command.d.ts.map +1 -1
  104. package/dist/commands/help.command.js +86 -18
  105. package/dist/commands/helper.command.js +1 -1
  106. package/dist/commands/impact.command.d.ts.map +1 -1
  107. package/dist/commands/impact.command.js +171 -1
  108. package/dist/commands/import.command.d.ts.map +1 -1
  109. package/dist/commands/import.command.js +121 -5
  110. package/dist/commands/ingest.command.d.ts.map +1 -1
  111. package/dist/commands/ingest.command.js +5 -1
  112. package/dist/commands/init.command.d.ts.map +1 -1
  113. package/dist/commands/init.command.js +174 -7
  114. package/dist/commands/knowledge-author.command.d.ts.map +1 -1
  115. package/dist/commands/knowledge-author.command.js +9 -0
  116. package/dist/commands/knowledge-propose.command.d.ts.map +1 -1
  117. package/dist/commands/knowledge-propose.command.js +4 -2
  118. package/dist/commands/knowledge.command.d.ts.map +1 -1
  119. package/dist/commands/knowledge.command.js +26 -3
  120. package/dist/commands/migrate.command.d.ts +13 -0
  121. package/dist/commands/migrate.command.d.ts.map +1 -0
  122. package/dist/commands/migrate.command.js +152 -0
  123. package/dist/commands/move-plan.command.d.ts +23 -0
  124. package/dist/commands/move-plan.command.d.ts.map +1 -0
  125. package/dist/commands/move-plan.command.js +360 -0
  126. package/dist/commands/packs-new.d.ts +1 -1
  127. package/dist/commands/packs-new.d.ts.map +1 -1
  128. package/dist/commands/packs-new.js +5 -36
  129. package/dist/commands/packs.command.d.ts.map +1 -1
  130. package/dist/commands/packs.command.js +2 -10
  131. package/dist/commands/plan-context.command.d.ts +11 -0
  132. package/dist/commands/plan-context.command.d.ts.map +1 -0
  133. package/dist/commands/plan-context.command.js +85 -0
  134. package/dist/commands/preflight.command.d.ts.map +1 -1
  135. package/dist/commands/preflight.command.js +15 -0
  136. package/dist/commands/profiles.command.js +4 -4
  137. package/dist/commands/recommend.command.d.ts +6 -0
  138. package/dist/commands/recommend.command.d.ts.map +1 -1
  139. package/dist/commands/recommend.command.js +119 -5
  140. package/dist/commands/release.command.js +13 -13
  141. package/dist/commands/rule-graph-subverbs.d.ts +3 -0
  142. package/dist/commands/rule-graph-subverbs.d.ts.map +1 -0
  143. package/dist/commands/rule-graph-subverbs.js +132 -0
  144. package/dist/commands/rules.command.d.ts.map +1 -1
  145. package/dist/commands/rules.command.js +20 -3
  146. package/dist/commands/scaffold-validate.command.d.ts +22 -0
  147. package/dist/commands/scaffold-validate.command.d.ts.map +1 -0
  148. package/dist/commands/scaffold-validate.command.js +215 -0
  149. package/dist/commands/search-structural.command.d.ts +18 -0
  150. package/dist/commands/search-structural.command.d.ts.map +1 -0
  151. package/dist/commands/search-structural.command.js +376 -0
  152. package/dist/commands/search.command.js +1 -1
  153. package/dist/commands/smart-context.command.d.ts +67 -0
  154. package/dist/commands/smart-context.command.d.ts.map +1 -0
  155. package/dist/commands/smart-context.command.js +4728 -0
  156. package/dist/commands/spike.command.d.ts +22 -0
  157. package/dist/commands/spike.command.d.ts.map +1 -0
  158. package/dist/commands/spike.command.js +235 -0
  159. package/dist/commands/surface.command.d.ts +1 -0
  160. package/dist/commands/surface.command.d.ts.map +1 -1
  161. package/dist/commands/surface.command.js +10 -3
  162. package/dist/commands/task-context.command.d.ts.map +1 -1
  163. package/dist/commands/task-context.command.js +5 -17
  164. package/dist/commands/task.command.d.ts.map +1 -1
  165. package/dist/commands/task.command.js +8 -2
  166. package/dist/commands/template-quality.command.d.ts.map +1 -1
  167. package/dist/commands/template-quality.command.js +39 -3
  168. package/dist/commands/templates.command.d.ts.map +1 -1
  169. package/dist/commands/templates.command.js +37 -2
  170. package/dist/commands/tests.command.d.ts.map +1 -1
  171. package/dist/commands/tests.command.js +13 -2
  172. package/dist/commands/watch.command.d.ts +26 -0
  173. package/dist/commands/watch.command.d.ts.map +1 -0
  174. package/dist/commands/watch.command.js +456 -0
  175. package/dist/dashboard/code-intelligence-data.d.ts +33 -0
  176. package/dist/dashboard/code-intelligence-data.d.ts.map +1 -0
  177. package/dist/dashboard/code-intelligence-data.js +329 -0
  178. package/dist/dashboard/dashboard-api-server.d.ts.map +1 -1
  179. package/dist/dashboard/dashboard-api-server.js +256 -2
  180. package/dist/dashboard/knowledge-ask.d.ts +4 -0
  181. package/dist/dashboard/knowledge-ask.d.ts.map +1 -0
  182. package/dist/dashboard/knowledge-ask.js +112 -0
  183. package/dist/env/load-dotenv.d.ts +15 -0
  184. package/dist/env/load-dotenv.d.ts.map +1 -0
  185. package/dist/env/load-dotenv.js +70 -0
  186. package/dist/export/claude-commands-export.d.ts +60 -0
  187. package/dist/export/claude-commands-export.d.ts.map +1 -0
  188. package/dist/export/claude-commands-export.js +276 -0
  189. package/dist/export/export-formats.d.ts +1 -1
  190. package/dist/export/export-formats.d.ts.map +1 -1
  191. package/dist/export/export-formats.js +139 -12
  192. package/dist/index.d.ts +3 -0
  193. package/dist/index.d.ts.map +1 -1
  194. package/dist/index.js +3 -0
  195. package/dist/init/init-templates.d.ts.map +1 -1
  196. package/dist/init/init-templates.js +133 -113
  197. package/dist/init/paths-advisory.d.ts +20 -0
  198. package/dist/init/paths-advisory.d.ts.map +1 -0
  199. package/dist/init/paths-advisory.js +88 -0
  200. package/dist/main.d.ts.map +1 -1
  201. package/dist/main.js +331 -17
  202. package/dist/output/ccr-store-config.d.ts +18 -0
  203. package/dist/output/ccr-store-config.d.ts.map +1 -0
  204. package/dist/output/ccr-store-config.js +41 -0
  205. package/dist/output/format-output.d.ts.map +1 -1
  206. package/dist/output/format-output.js +6 -1
  207. package/dist/output/output-compression.d.ts +15 -0
  208. package/dist/output/output-compression.d.ts.map +1 -0
  209. package/dist/output/output-compression.js +60 -0
  210. package/dist/output/resolve-compress-type.d.ts +22 -0
  211. package/dist/output/resolve-compress-type.d.ts.map +1 -0
  212. package/dist/output/resolve-compress-type.js +21 -0
  213. package/dist/output/watch-loop.d.ts +9 -1
  214. package/dist/output/watch-loop.d.ts.map +1 -1
  215. package/dist/output/watch-loop.js +13 -3
  216. package/dist/schemas/json-schemas.d.ts +384 -36
  217. package/dist/schemas/json-schemas.d.ts.map +1 -1
  218. package/dist/schemas/json-schemas.js +247 -36
  219. package/dist/surface/profiles.d.ts.map +1 -1
  220. package/dist/surface/profiles.js +54 -9
  221. package/dist/surface/surface-config-writer.d.ts.map +1 -1
  222. package/dist/surface/surface-config-writer.js +23 -11
  223. package/dist/validation/run-validation-loop.d.ts.map +1 -1
  224. package/dist/validation/run-validation-loop.js +5 -1
  225. package/package.json +35 -21
  226. package/dist/commands/plugin.command.d.ts +0 -11
  227. package/dist/commands/plugin.command.d.ts.map +0 -1
  228. package/dist/commands/plugin.command.js +0 -394
package/dist/main.js CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { CommandRegistry, extractGlobalCwd, parseArgs, } from "./command-registry.js";
2
+ import { loadDotenv } from "./env/load-dotenv.js";
3
+ import { CommandRegistry, extractGlobalCompress, extractGlobalCwd, parseArgs, } from "./command-registry.js";
4
+ import { runCommandWithCompression } from "./output/output-compression.js";
3
5
  import { initCommand } from "./commands/init.command.js";
4
6
  import { inspectCommand } from "./commands/inspect.command.js";
5
7
  import { doctorAcknowledgeCommand, doctorAcknowledgementsCommand, doctorCommand, doctorSuppressCommand, doctorSuppressionsCommand, } from "./commands/doctor.command.js";
@@ -20,10 +22,21 @@ import { presetsListCommand, presetsGetCommand, presetsExplainCommand, presetsRe
20
22
  import { taskCommand } from "./commands/task.command.js";
21
23
  import { preflightCommand } from "./commands/preflight.command.js";
22
24
  import { checkCommand } from "./commands/check.command.js";
25
+ import { diffCheckCommand } from "./commands/diff-check.command.js";
23
26
  import { driftCommand } from "./commands/drift.command.js";
24
27
  import { graphCommand } from "./commands/graph.command.js";
28
+ import { ruleGraphCommand } from "./commands/rule-graph-subverbs.js";
29
+ import { searchStructuralCommand } from "./commands/search-structural.command.js";
30
+ import { planContextCommand } from "./commands/plan-context.command.js";
31
+ import { archCommand } from "./commands/arch.command.js";
32
+ import { frameworkCommand } from "./commands/framework.command.js";
33
+ import { apiDiffCommand } from "./commands/api-diff.command.js";
34
+ import { gateCommand } from "./commands/gate.command.js";
35
+ import { migrateCommand } from "./commands/migrate.command.js";
25
36
  import { coverageCommand } from "./commands/coverage.command.js";
26
37
  import { statsCommand } from "./commands/stats.command.js";
38
+ import { compressCommand, expandCommand } from "./commands/compress.command.js";
39
+ import { alignCommand, unalignCommand } from "./commands/cache-align.command.js";
27
40
  import { reviewCommand } from "./commands/review.command.js";
28
41
  import { onboardCommand } from "./commands/onboard.command.js";
29
42
  import { contradictionsCommand, generatedCommand, ingestCommand, } from "./commands/ingest.command.js";
@@ -37,6 +50,7 @@ import { contextCommand } from "./commands/context.command.js";
37
50
  import { diffParentCommand, diffRoundsCommand, roundsCaptureCommand, roundsListCommand, roundsParentCommand, roundsShowCommand, } from "./commands/rounds.command.js";
38
51
  import { genCommand } from "./commands/gen.command.js";
39
52
  import { applyCommand } from "./commands/apply.command.js";
53
+ import { delegateCommand } from "./commands/delegate.command.js";
40
54
  import { groundingCommand } from "./commands/grounding.command.js";
41
55
  import { planCheckCommand } from "./commands/plan-check.command.js";
42
56
  import { whyCommand } from "./commands/why.command.js";
@@ -46,6 +60,13 @@ import { dashboardCommand } from "./commands/dashboard.command.js";
46
60
  import { dashboardDiffCommand, dashboardExportCommand, } from "./commands/dashboard-export.command.js";
47
61
  import { importCommand } from "./commands/import.command.js";
48
62
  import { askCommand } from "./commands/ask.command.js";
63
+ import { aiStatusCommand } from "./commands/ai-status.command.js";
64
+ import { smartContextAuditKnowledgeCommand, smartContextAuditPipelinesCommand, smartContextAuditTemplatesCommand, smartContextCommand, smartContextEmbeddingsBuildCommand, smartContextEmbeddingsStatusCommand, smartContextListCommand, smartContextPlanAheadCommand, smartContextShowCommand, } from "./commands/smart-context.command.js";
65
+ import { spikeCommand } from "./commands/spike.command.js";
66
+ import { depsAuditCommand } from "./commands/deps-audit.command.js";
67
+ import { scaffoldValidateCommand } from "./commands/scaffold-validate.command.js";
68
+ import { movePlanCommand } from "./commands/move-plan.command.js";
69
+ import { watchCommand, watchListCommand, watchPruneCommand, watchStopCommand } from "./commands/watch.command.js";
49
70
  import { mcpCommand } from "./commands/mcp.command.js";
50
71
  import { versionCommand } from "./commands/version.command.js";
51
72
  import { makeHelpCommand } from "./commands/help.command.js";
@@ -56,7 +77,6 @@ import { biomeCommand } from "./commands/biome.command.js";
56
77
  import { ideCommand } from "./commands/ide.command.js";
57
78
  import { makeCommandsCommand } from "./commands/commands.command.js";
58
79
  import { safetyCommand } from "./commands/safety.command.js";
59
- import { pluginCommand } from "./commands/plugin.command.js";
60
80
  import { profilesCommand } from "./commands/profiles.command.js";
61
81
  import { auditProjectCouplingCommand } from "./commands/audit.command.js";
62
82
  import { conventionsCommand } from "./commands/conventions.command.js";
@@ -110,6 +130,8 @@ import { lintCommand } from "./commands/lint.command.js";
110
130
  import { changesCommand } from "./commands/changes.command.js";
111
131
  import { exploreCommand } from "./commands/explore.command.js";
112
132
  import { prCommand } from "./commands/pr.command.js";
133
+ import { completionCommand } from "./commands/completion.command.js";
134
+ import { codeIntelCommand } from "./commands/code-intel.command.js";
113
135
  import { suggestDidYouMean } from '@shrkcrft/inspector';
114
136
  import { COMMAND_CATALOG } from "./commands/command-catalog.js";
115
137
  import { errorFooterFor, renderErrorFooter } from "./output/failure-hints.js";
@@ -125,6 +147,7 @@ export function buildRegistry() {
125
147
  registry.register(initCommand);
126
148
  registry.register(inspectCommand);
127
149
  registry.register(doctorCommand);
150
+ registry.register(aiStatusCommand);
128
151
  registry.registerSubcommand('doctor', doctorSuppressCommand);
129
152
  registry.registerSubcommand('doctor', doctorSuppressionsCommand);
130
153
  // Acknowledgements with required reason + expiry.
@@ -133,6 +156,7 @@ export function buildRegistry() {
133
156
  registry.register(contextCommand);
134
157
  registry.register(genCommand);
135
158
  registry.register(applyCommand);
159
+ registry.register(delegateCommand);
136
160
  // `shrk grounding` thin context primer.
137
161
  registry.register(groundingCommand);
138
162
  // feedback3 — `shrk why <file>` (closes the dangling ide-suggested verb).
@@ -162,12 +186,25 @@ export function buildRegistry() {
162
186
  registry.register(taskCommand);
163
187
  registry.register(explainCommand);
164
188
  registry.register(checkCommand);
189
+ registry.register(diffCheckCommand);
165
190
  // changed-only preflight orchestrator.
166
191
  registry.register(preflightCommand);
167
192
  registry.register(driftCommand);
168
193
  registry.register(graphCommand);
194
+ registry.register(ruleGraphCommand);
195
+ registry.register(searchStructuralCommand);
196
+ registry.register(planContextCommand);
197
+ registry.register(archCommand);
198
+ registry.register(frameworkCommand);
199
+ registry.register(apiDiffCommand);
200
+ registry.register(gateCommand);
201
+ registry.register(migrateCommand);
169
202
  registry.register(coverageCommand);
170
203
  registry.register(statsCommand);
204
+ registry.register(compressCommand);
205
+ registry.register(expandCommand);
206
+ registry.register(alignCommand);
207
+ registry.register(unalignCommand);
171
208
  registry.register(reviewCommand);
172
209
  registry.register(onboardCommand);
173
210
  registry.register(ingestCommand);
@@ -185,6 +222,23 @@ export function buildRegistry() {
185
222
  registry.register(planParentCommand);
186
223
  registry.register(devCommand);
187
224
  registry.register(askCommand);
225
+ registry.register(smartContextCommand);
226
+ registry.registerSubcommand('smart-context', smartContextPlanAheadCommand);
227
+ registry.registerSubcommand('smart-context', smartContextListCommand);
228
+ registry.registerSubcommand('smart-context', smartContextShowCommand);
229
+ registry.registerSubcommand('smart-context', smartContextEmbeddingsBuildCommand);
230
+ registry.registerSubcommand('smart-context', smartContextEmbeddingsStatusCommand);
231
+ registry.registerSubcommand('smart-context', smartContextAuditTemplatesCommand);
232
+ registry.registerSubcommand('smart-context', smartContextAuditKnowledgeCommand);
233
+ registry.registerSubcommand('smart-context', smartContextAuditPipelinesCommand);
234
+ registry.register(spikeCommand);
235
+ registry.register(depsAuditCommand);
236
+ registry.register(scaffoldValidateCommand);
237
+ registry.register(movePlanCommand);
238
+ registry.register(watchCommand);
239
+ registry.registerSubcommand('watch', watchListCommand);
240
+ registry.registerSubcommand('watch', watchStopCommand);
241
+ registry.registerSubcommand('watch', watchPruneCommand);
188
242
  registry.register(mcpCommand);
189
243
  registry.register(versionCommand);
190
244
  registry.register(qualityCommand);
@@ -192,7 +246,6 @@ export function buildRegistry() {
192
246
  registry.register(eslintCommand);
193
247
  registry.register(biomeCommand);
194
248
  registry.register(ideCommand);
195
- registry.register(pluginCommand);
196
249
  registry.register(profilesCommand);
197
250
  registry.registerSubcommand('audit', auditProjectCouplingCommand);
198
251
  registry.register(conventionsCommand);
@@ -213,6 +266,8 @@ export function buildRegistry() {
213
266
  registry.register(lintCommand);
214
267
  registry.register(changesCommand);
215
268
  registry.register(prCommand);
269
+ registry.register(completionCommand);
270
+ registry.register(codeIntelCommand);
216
271
  registry.register(searchCommand);
217
272
  registry.register(briefCommand);
218
273
  registry.register(releaseCommand);
@@ -493,8 +548,23 @@ async function isUsageEnabled(cwd) {
493
548
  async function runCliInner(argv) {
494
549
  const registry = buildRegistry();
495
550
  // Pre-parse the global --cwd so it can appear anywhere (incl. before the command).
496
- const { cwd: globalCwd, rest: cleanArgv } = extractGlobalCwd(argv);
551
+ const { cwd: globalCwd, rest: cwdCleanArgv } = extractGlobalCwd(argv);
552
+ // Pre-parse the global --compress / --ccr output-compression flags.
553
+ const { directive: compressDirective, rest: cleanArgv } = extractGlobalCompress(cwdCleanArgv);
497
554
  const [first] = cleanArgv;
555
+ // `--compress` / `--ccr` on a real command: re-run it and compress its stdout.
556
+ // (Meta verbs like --help/--version and bare invocations are left untouched.)
557
+ if (compressDirective &&
558
+ first &&
559
+ first !== '--help' &&
560
+ first !== '-h' &&
561
+ first !== '--full-help' &&
562
+ first !== '--version' &&
563
+ first !== '-v' &&
564
+ first !== '--about') {
565
+ const childArgv = globalCwd ? ['--cwd', globalCwd, ...cleanArgv] : [...cleanArgv];
566
+ return runCommandWithCompression(childArgv, compressDirective, globalCwd ?? process.cwd());
567
+ }
498
568
  // bare invocation lands on the curated tiered view.
499
569
  if (!first) {
500
570
  const landing = await renderNoArgsLanding(globalCwd ?? process.cwd());
@@ -506,7 +576,14 @@ async function runCliInner(argv) {
506
576
  return registry.get('help').run(parseArgs([], { globalCwd }));
507
577
  }
508
578
  if (first === '--full-help') {
509
- return registry.get('help').run(parseArgs(['--full'], { globalCwd }));
579
+ // Pass through `--all` (catalog dump) and `--verbose` if the user
580
+ // included them after `--full-help`.
581
+ const extra = [];
582
+ if (argv.includes('--all'))
583
+ extra.push('--all');
584
+ if (argv.includes('--verbose') || argv.includes('-v'))
585
+ extra.push('--verbose');
586
+ return registry.get('help').run(parseArgs(['--full', ...extra], { globalCwd }));
510
587
  }
511
588
  if (first === '--version' || first === '-v') {
512
589
  return registry.get('version').run(parseArgs([], { globalCwd }));
@@ -536,7 +613,7 @@ async function runCliInner(argv) {
536
613
  process.stderr.write(renderSurfaceNotEnabledText(err));
537
614
  return SURFACE_NOT_ENABLED_EXIT_CODE;
538
615
  }
539
- return await handler.run(parseArgs(leftover, { globalCwd }));
616
+ return await handler.run(parseArgs(leftover, { globalCwd, booleanFlags: handler.booleanFlags }));
540
617
  }
541
618
  // No handler at the deepest match. If we landed on a group node (has
542
619
  // children), show that group's help so the user discovers the verbs.
@@ -550,7 +627,7 @@ async function runCliInner(argv) {
550
627
  return 2;
551
628
  }
552
629
  const attempted = probe.slice(0, 2).join(' ');
553
- process.stderr.write(`Unknown command: ${attempted}\n`);
630
+ process.stderr.write(`shrk doesn't have a \`${attempted}\` command.\n`);
554
631
  printDidYouMean(attempted);
555
632
  return 2;
556
633
  }
@@ -567,7 +644,15 @@ async function runCliInner(argv) {
567
644
  * Exported for tests.
568
645
  */
569
646
  export function looksLikeFreeFormTask(tokens) {
570
- const clean = tokens.filter((t) => t.length > 0 && !t.startsWith('-'));
647
+ // Flatten on internal whitespace so the canonical *quoted* form
648
+ // (`shrk "refactor the auth module"`) — which the shell delivers as ONE argv
649
+ // element — is counted by word, exactly like the unquoted multi-token form.
650
+ // Without this, the documented quoted form was a single token (length 1) and
651
+ // fell through to the did-you-mean matcher instead of routing to `recommend`.
652
+ const clean = tokens
653
+ .filter((t) => t.length > 0 && !t.startsWith('-'))
654
+ .flatMap((t) => t.trim().split(/\s+/))
655
+ .filter((w) => w.length > 0);
571
656
  if (clean.length < 2)
572
657
  return false;
573
658
  // 3+ tokens is almost always a sentence, not a command — `shrk` only has
@@ -658,25 +743,144 @@ async function checkSurfaceGate(matchedPath, cwd) {
658
743
  return null;
659
744
  }
660
745
  }
746
+ // Score thresholds for did-you-mean output. Picked from observed
747
+ // scoring: 1-char-off typos score 8+ on plain commands; 3-4-char-off
748
+ // near-misses score ~5; loose / token-overlap matches score 1-3.
749
+ // Junk matches (frobnicate → bundle diff) can score 8 too because of
750
+ // token overlap, so we sharpen by also requiring the suggestion's
751
+ // command name to be reasonably close in length to the attempt.
752
+ const SUGGEST_CONFIDENT_SCORE = 7;
753
+ const SUGGEST_VISIBLE_SCORE = 3;
754
+ function reorderCandidates(attempted, candidates) {
755
+ // Stable sort: higher score first, then shorter command (more likely
756
+ // canonical), then lexicographic. The base suggester returns ties in
757
+ // arbitrary order — this makes the top suggestion more predictable.
758
+ const ranked = [...candidates];
759
+ ranked.sort((a, b) => {
760
+ if (b.score !== a.score)
761
+ return b.score - a.score;
762
+ if (a.command.length !== b.command.length) {
763
+ return a.command.length - b.command.length;
764
+ }
765
+ return a.command < b.command ? -1 : a.command > b.command ? 1 : 0;
766
+ });
767
+ return ranked;
768
+ }
769
+ /** Edit distance (Levenshtein). Used to gate did-you-mean confidence. */
770
+ function editDistance(a, b) {
771
+ const m = a.length;
772
+ const n = b.length;
773
+ if (m === 0)
774
+ return n;
775
+ if (n === 0)
776
+ return m;
777
+ const dp = new Array(n + 1);
778
+ for (let j = 0; j <= n; j += 1)
779
+ dp[j] = j;
780
+ for (let i = 1; i <= m; i += 1) {
781
+ let prev = dp[0];
782
+ dp[0] = i;
783
+ for (let j = 1; j <= n; j += 1) {
784
+ const tmp = dp[j];
785
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
786
+ dp[j] = Math.min(dp[j] + 1, dp[j - 1] + 1, prev + cost);
787
+ prev = tmp;
788
+ }
789
+ }
790
+ return dp[n];
791
+ }
792
+ /**
793
+ * Suggestion is "confident" when the candidate's top token is close
794
+ * to the attempt in edit-distance terms — `doctorz`→`doctor` (1 edit)
795
+ * or `inspct`→`inspect` (1 edit) qualify; `frobnicate`→`bundle` (10
796
+ * edits) does not, even when the suggester scores them similarly
797
+ * because of incidental token overlap in descriptions.
798
+ *
799
+ * Threshold: edit distance ≤ max(1, attempt.length / 4) AND raw score
800
+ * meets `SUGGEST_VISIBLE_SCORE`. This catches typical fingers-on-keys
801
+ * typos while rejecting "you typed something totally different."
802
+ */
803
+ function isConfidentMatch(attempted, suggestion) {
804
+ if (suggestion.score < SUGGEST_VISIBLE_SCORE)
805
+ return false;
806
+ const lower = attempted.toLowerCase();
807
+ const head = (suggestion.command.split(/\s+/)[0] ?? suggestion.command).toLowerCase();
808
+ const dist = editDistance(lower, head);
809
+ const tolerance = Math.max(1, Math.floor(lower.length / 4));
810
+ return dist <= tolerance;
811
+ }
661
812
  function printDidYouMean(attempted) {
662
- const candidates = suggestDidYouMean(COMMAND_CATALOG, [attempted], 3);
663
- if (candidates.length === 0) {
664
- process.stderr.write("Tip: run `shrk commands suggest \"<partial>\"` or `shrk help` to discover commands.\n");
813
+ const rawCandidates = suggestDidYouMean(COMMAND_CATALOG, [attempted], 5);
814
+ const reordered = reorderCandidates(attempted, rawCandidates).filter((c) => c.score >= SUGGEST_VISIBLE_SCORE);
815
+ if (reordered.length === 0) {
816
+ process.stderr.write('Run `shrk help` to see the curated commands, or `shrk --full-help` for the full catalog.\n');
665
817
  const footer = errorFooterFor('unknown-command', { task: attempted });
666
818
  if (footer)
667
819
  process.stderr.write(renderErrorFooter(footer));
668
820
  return;
669
821
  }
670
- process.stderr.write('Did you mean:\n');
671
- for (const c of candidates) {
822
+ // Confident single-match path: surface ONE suggestion clearly.
823
+ const top = reordered[0];
824
+ if (isConfidentMatch(attempted, top)) {
825
+ process.stderr.write(`Did you mean \`shrk ${top.command}\`?\n`);
826
+ process.stderr.write(` ${top.description}\n`);
827
+ // Second-tier suggestions only if they're also strong.
828
+ const others = reordered.slice(1, 3).filter((c) => isConfidentMatch(attempted, c));
829
+ if (others.length > 0) {
830
+ process.stderr.write('Other close matches:\n');
831
+ for (const c of others) {
832
+ process.stderr.write(` shrk ${c.command} — ${c.description}\n`);
833
+ }
834
+ }
835
+ const footer = errorFooterFor('unknown-command', { task: attempted });
836
+ if (footer)
837
+ process.stderr.write(renderErrorFooter(footer));
838
+ return;
839
+ }
840
+ // Low-confidence: show up to 3 as "closest matches", honest about
841
+ // not knowing which is right.
842
+ process.stderr.write('Closest matches in the catalog:\n');
843
+ for (const c of reordered.slice(0, 3)) {
672
844
  process.stderr.write(` shrk ${c.command} — ${c.description}\n`);
673
845
  }
674
- // append the standardised next-command footer so the user
675
- // always has a deterministic exit route.
846
+ process.stderr.write("If none of those look right, run `shrk help` or `shrk \"<task>\"` to route as a free-form task.\n");
676
847
  const footer = errorFooterFor('unknown-command', { task: attempted });
677
848
  if (footer)
678
849
  process.stderr.write(renderErrorFooter(footer));
679
850
  }
851
+ /**
852
+ * Point fd 2 (stderr) at a log file so native-runtime teardown noise written
853
+ * during process exit lands in a file instead of the user's terminal. Returns
854
+ * silently on any failure (the worst case is the pre-existing noisy stderr).
855
+ *
856
+ * The log path can be overridden with `SHRK_NATIVE_TEARDOWN_LOG`; default is
857
+ * `<tmpdir>/shrk-native-teardown.log`. We append, with a timestamped header,
858
+ * so the trace is recoverable for debugging without ever touching the console.
859
+ */
860
+ async function redirectStderrToTeardownLog() {
861
+ try {
862
+ const fs = await import('node:fs');
863
+ const os = await import('node:os');
864
+ const path = await import('node:path');
865
+ const logPath = process.env.SHRK_NATIVE_TEARDOWN_LOG?.trim() ||
866
+ path.join(os.tmpdir(), 'shrk-native-teardown.log');
867
+ fs.mkdirSync(path.dirname(logPath), { recursive: true });
868
+ // Close fd 2; the next open() reclaims the lowest free descriptor (2),
869
+ // so all subsequent stderr — including native C++ writes during
870
+ // `__cxa_finalize` — flows to the log file.
871
+ fs.closeSync(2);
872
+ const fd = fs.openSync(logPath, 'a');
873
+ if (fd !== 2) {
874
+ // Couldn't reclaim fd 2 — leave things as they are rather than risk
875
+ // writing the result to the wrong descriptor.
876
+ return;
877
+ }
878
+ fs.writeSync(2, `\n--- shrk native-runtime teardown @ ${new Date().toISOString()} ---\n`);
879
+ }
880
+ catch {
881
+ // Best-effort containment; never let log redirection break the exit.
882
+ }
883
+ }
680
884
  // Entry point when invoked directly.
681
885
  //
682
886
  // Bun exposes `import.meta.main`; Node does not. When Node runs the
@@ -691,9 +895,119 @@ if (isMain ||
691
895
  entryPath.endsWith('shrk') ||
692
896
  entryPath.endsWith('shrk.js') ||
693
897
  entryPath.endsWith('shrk.cmd')) {
898
+ // Marks a real CLI invocation (vs. a command handler imported directly by a
899
+ // test). Commands that re-exec themselves in an isolated child gate on this
900
+ // so unit tests calling `run()` in-process never spawn a subprocess.
901
+ process.env.SHRK_CLI = '1';
902
+ loadDotenv(process.cwd());
694
903
  const argv = process.argv.slice(2);
695
- runCli(argv).then((code) => process.exit(code), (err) => {
904
+ const cleanShutdown = async (code) => {
905
+ // Best-effort teardown of shared native runtimes. Without this,
906
+ // commands that loaded native libs (ONNX via embeddings; Metal
907
+ // via node-llama-cpp) abort during `process.exit` AFTER the
908
+ // work completed — the user sees their result then `zsh: abort`.
909
+ // Dynamic imports keep these off the hot path for commands that
910
+ // never touched them.
911
+ // Track whether any native runtime (ONNX via embeddings, Metal/ggml via
912
+ // node-llama-cpp) was actually loaded this run. If so, its static
913
+ // destructors can still abort with a backtrace during `exit()` below —
914
+ // and there is no JS hook in this Node version to skip libc++ finalizers.
915
+ // We contain that by redirecting fd 2 to a log file just before exit.
916
+ let nativeRuntimeLoaded = false;
917
+ try {
918
+ const mod = (await import('@shrkcrft/embeddings'));
919
+ if (typeof mod.disposeSemanticIndexPipeline === 'function') {
920
+ nativeRuntimeLoaded = (await mod.disposeSemanticIndexPipeline()) || nativeRuntimeLoaded;
921
+ }
922
+ }
923
+ catch {
924
+ // Best-effort; never block the exit on teardown failure.
925
+ }
926
+ try {
927
+ const mod = (await import('@shrkcrft/ai'));
928
+ if (typeof mod.disposeLlamaCppRuntime === 'function') {
929
+ nativeRuntimeLoaded = (await mod.disposeLlamaCppRuntime()) || nativeRuntimeLoaded;
930
+ }
931
+ }
932
+ catch {
933
+ // Best-effort.
934
+ }
935
+ // Flush stdio synchronously before bypassing C++ destructors.
936
+ // `_exit` skips all libc finalizers, which is exactly what we
937
+ // need (see below), but it also doesn't wait for buffered
938
+ // writes to drain. Two synchronous write callbacks force the
939
+ // current buffers through.
940
+ try {
941
+ await new Promise((resolve) => process.stdout.write('', () => resolve()));
942
+ await new Promise((resolve) => process.stderr.write('', () => resolve()));
943
+ }
944
+ catch {
945
+ // ignore flush failures
946
+ }
947
+ // When running as an isolated worker (e.g. the smart-context child), hand
948
+ // the real exit code back to the parent via a sentinel file. The native
949
+ // teardown abort below would otherwise clobber it with SIGABRT (134).
950
+ const exitCodeFile = process.env.SHRK_WORKER_EXITCODE_FILE;
951
+ if (exitCodeFile) {
952
+ try {
953
+ const fs = await import('node:fs');
954
+ fs.writeFileSync(exitCodeFile, String(code), 'utf8');
955
+ }
956
+ catch {
957
+ // best-effort; parent falls back to the child's signal/code.
958
+ }
959
+ }
960
+ // Contain native-runtime teardown noise. The ggml/ONNX destructors write a
961
+ // backtrace + `libc++abi: terminating … mutex lock failed` straight to fd 2
962
+ // during `exit()`, AFTER our real output is already on screen. That bypasses
963
+ // any JS stream wrapper, so the only reliable way to keep it off the user's
964
+ // terminal is to point fd 2 at a log file first: close(2) frees the lowest
965
+ // fd, and the next open() reclaims it. Gated on `nativeRuntimeLoaded` so
966
+ // ordinary commands keep their stderr untouched.
967
+ if (nativeRuntimeLoaded) {
968
+ await redirectStderrToTeardownLog();
969
+ }
970
+ // Prefer a low-level exit over `process.exit` on Node. Without
971
+ // this, libc++ static destructors run during `process.exit`, and
972
+ // native bindings still resident in memory abort with libc++abi
973
+ // errors AFTER the user's result has already printed:
974
+ // - node-llama-cpp's libggml-metal hits `GGML_ASSERT([rsets->data
975
+ // count] == 0)` in `ggml_metal_device_free` → `zsh: abort`.
976
+ // - onnxruntime-node's worker pool aborts with
977
+ // `libc++abi: mutex lock failed: Invalid argument` after a
978
+ // successful `shrk smart-context embeddings-build`. NOTE:
979
+ // `pipeline.dispose()` returns cleanly, but ONNX worker threads
980
+ // are not actually joined — they continue running briefly and
981
+ // hit the pthread mutex teardown race. There is no JS-layer
982
+ // fix for this; upstream onnxruntime-node 1.21 has the bug.
983
+ // The low-level exit at least suppresses the destructor pass
984
+ // so the failure mode is "noisy stderr, exit code preserved"
985
+ // rather than "destructor cascade".
986
+ //
987
+ // Node exposes the low-level exit under two names depending on the
988
+ // version:
989
+ // - `process._exit` — public alias (older Node; removed from
990
+ // the public surface on Node 22+).
991
+ // - `process.reallyExit` — Node-internal name; still present on
992
+ // Node 22 even when `_exit` is undefined.
993
+ // Try both in order. Bun's process object doesn't expose either,
994
+ // but Bun also doesn't drive shutdown through libuv + libc++ static
995
+ // destructors the same way Node does, so the crash doesn't
996
+ // reproduce there. Fall back to `process.exit` when no low-level
997
+ // hook is available.
998
+ const proc = process;
999
+ const lowLevelExit = typeof proc._exit === 'function'
1000
+ ? proc._exit
1001
+ : typeof proc.reallyExit === 'function'
1002
+ ? proc.reallyExit
1003
+ : null;
1004
+ if (lowLevelExit !== null) {
1005
+ lowLevelExit(code);
1006
+ }
1007
+ process.exit(code);
1008
+ };
1009
+ runCli(argv).then((code) => cleanShutdown(code), (err) => {
696
1010
  process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}\n`);
697
- process.exit(1);
1011
+ return cleanShutdown(1);
698
1012
  });
699
1013
  }
@@ -0,0 +1,18 @@
1
+ import { TtlFileCcrStore } from '@shrkcrft/compress';
2
+ /**
3
+ * Upper bound on cached CCR originals under `.sharkcraft/ccr/`. The store evicts
4
+ * the oldest entries past this on every `put`, so the compress cache stays
5
+ * bounded instead of growing without limit (the old `FileCcrStore` had no cap).
6
+ * Count-based (not time-based) so a previously-cached key never silently
7
+ * expires out from under a `shrk expand` until it is genuinely the oldest and
8
+ * the cap is exceeded.
9
+ */
10
+ export declare const CCR_MAX_ENTRIES = 1000;
11
+ /** Absolute path to the per-project CCR cache directory (project-root-relative). */
12
+ export declare function ccrDir(cwd: string): string;
13
+ /**
14
+ * Open the bounded, cross-process CCR store the CLI write/read paths share.
15
+ * `ttlMs: 0` means no time expiry; `maxEntries` is the only bound.
16
+ */
17
+ export declare function openCcrStore(cwd: string): TtlFileCcrStore;
18
+ //# sourceMappingURL=ccr-store-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ccr-store-config.d.ts","sourceRoot":"","sources":["../../src/output/ccr-store-config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAmBrD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,oFAAoF;AACpF,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAEzD"}
@@ -0,0 +1,41 @@
1
+ import { existsSync } from 'node:fs';
2
+ import * as nodePath from 'node:path';
3
+ import { TtlFileCcrStore } from '@shrkcrft/compress';
4
+ /**
5
+ * Walk up from `cwd` to the nearest ancestor containing a `.sharkcraft/` dir
6
+ * (the project root), so `compress` and `expand` share ONE cache per project —
7
+ * a `<<ccr:KEY>>` cached at the repo root stays recoverable from any subdir
8
+ * instead of being unrecoverable because `expand` looked in `<subdir>/.sharkcraft/ccr`.
9
+ * Falls back to `cwd` when no project root is found (a fresh repo).
10
+ */
11
+ function ccrRoot(cwd) {
12
+ let dir = nodePath.resolve(cwd);
13
+ for (;;) {
14
+ if (existsSync(nodePath.join(dir, '.sharkcraft')))
15
+ return dir;
16
+ const parent = nodePath.dirname(dir);
17
+ if (parent === dir)
18
+ return cwd; // reached the filesystem root
19
+ dir = parent;
20
+ }
21
+ }
22
+ /**
23
+ * Upper bound on cached CCR originals under `.sharkcraft/ccr/`. The store evicts
24
+ * the oldest entries past this on every `put`, so the compress cache stays
25
+ * bounded instead of growing without limit (the old `FileCcrStore` had no cap).
26
+ * Count-based (not time-based) so a previously-cached key never silently
27
+ * expires out from under a `shrk expand` until it is genuinely the oldest and
28
+ * the cap is exceeded.
29
+ */
30
+ export const CCR_MAX_ENTRIES = 1000;
31
+ /** Absolute path to the per-project CCR cache directory (project-root-relative). */
32
+ export function ccrDir(cwd) {
33
+ return nodePath.join(ccrRoot(cwd), '.sharkcraft', 'ccr');
34
+ }
35
+ /**
36
+ * Open the bounded, cross-process CCR store the CLI write/read paths share.
37
+ * `ttlMs: 0` means no time expiry; `maxEntries` is the only bound.
38
+ */
39
+ export function openCcrStore(cwd) {
40
+ return new TtlFileCcrStore(ccrDir(cwd), { maxEntries: CCR_MAX_ENTRIES });
41
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"format-output.d.ts","sourceRoot":"","sources":["../../src/output/format-output.ts"],"names":[],"mappings":"AAAA,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAG3F;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE7C;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,GAAG,MAAM,CAWlE;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB"}
1
+ {"version":3,"file":"format-output.d.ts","sourceRoot":"","sources":["../../src/output/format-output.ts"],"names":[],"mappings":"AAAA,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAG3F;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAO7C;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,GAAG,MAAM,CAWlE;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB"}
@@ -9,7 +9,12 @@ export function kv(key, value) {
9
9
  return ` ${key.padEnd(18)} ${v}`;
10
10
  }
11
11
  export function asJson(value) {
12
- return JSON.stringify(value, null, 2);
12
+ // Minified by default: `--json` output is for machine / agent consumption, so
13
+ // we emit the smallest valid JSON (mirrors the MCP wire's default). The shape
14
+ // is unchanged — only whitespace is removed — so `JSON.parse` consumers are
15
+ // unaffected. Set SHRK_JSON_PRETTY=1 for human-readable 2-space indentation.
16
+ const pretty = process.env.SHRK_JSON_PRETTY === '1' || process.env.SHRK_JSON_PRETTY === 'true';
17
+ return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);
13
18
  }
14
19
  export function table(rows) {
15
20
  if (rows.length === 0)
@@ -0,0 +1,15 @@
1
+ import type { IGlobalCompressDirective } from '../command-registry.js';
2
+ /**
3
+ * Implements the global `--compress` / `--ccr` flag: run a `shrk` command in a
4
+ * child process, capture its stdout, and emit a deterministically-compressed
5
+ * version (with the original cached for `shrk expand`). The command's own
6
+ * stderr is forwarded verbatim and its exit code is preserved.
7
+ *
8
+ * A SUBPROCESS (not in-process `process.stdout` capture) on purpose: some
9
+ * commands call `process.exit`, which would discard a buffered in-process
10
+ * capture mid-write; re-running the command isolates that and still yields the
11
+ * full output + real exit status. `childArgv` has already had the compress
12
+ * flags stripped, so the child never recurses.
13
+ */
14
+ export declare function runCommandWithCompression(childArgv: readonly string[], directive: IGlobalCompressDirective, cwd: string): number;
15
+ //# sourceMappingURL=output-compression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-compression.d.ts","sourceRoot":"","sources":["../../src/output/output-compression.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAQvE;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,SAAS,EAAE,wBAAwB,EACnC,GAAG,EAAE,MAAM,GACV,MAAM,CAgDR"}