@shrkcrft/cli 0.1.0-alpha.2 → 0.1.0-alpha.21
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.
- package/dist/audit/knowledge-audit-llm.d.ts +19 -0
- package/dist/audit/knowledge-audit-llm.d.ts.map +1 -0
- package/dist/audit/knowledge-audit-llm.js +164 -0
- package/dist/audit/knowledge-audit.d.ts +61 -0
- package/dist/audit/knowledge-audit.d.ts.map +1 -0
- package/dist/audit/knowledge-audit.js +203 -0
- package/dist/audit/knowledge-fix-plan-llm.d.ts +11 -0
- package/dist/audit/knowledge-fix-plan-llm.d.ts.map +1 -0
- package/dist/audit/knowledge-fix-plan-llm.js +141 -0
- package/dist/audit/knowledge-fix-plan.d.ts +41 -0
- package/dist/audit/knowledge-fix-plan.d.ts.map +1 -0
- package/dist/audit/knowledge-fix-plan.js +125 -0
- package/dist/audit/pipeline-audit-llm.d.ts +11 -0
- package/dist/audit/pipeline-audit-llm.d.ts.map +1 -0
- package/dist/audit/pipeline-audit-llm.js +134 -0
- package/dist/audit/pipeline-audit.d.ts +69 -0
- package/dist/audit/pipeline-audit.d.ts.map +1 -0
- package/dist/audit/pipeline-audit.js +166 -0
- package/dist/audit/templates-audit-llm.d.ts +19 -0
- package/dist/audit/templates-audit-llm.d.ts.map +1 -0
- package/dist/audit/templates-audit-llm.js +207 -0
- package/dist/audit/templates-audit.d.ts +63 -0
- package/dist/audit/templates-audit.d.ts.map +1 -0
- package/dist/audit/templates-audit.js +171 -0
- package/dist/audit/templates-fix-plan-llm.d.ts +19 -0
- package/dist/audit/templates-fix-plan-llm.d.ts.map +1 -0
- package/dist/audit/templates-fix-plan-llm.js +162 -0
- package/dist/audit/templates-fix-plan.d.ts +37 -0
- package/dist/audit/templates-fix-plan.d.ts.map +1 -0
- package/dist/audit/templates-fix-plan.js +174 -0
- package/dist/command-registry.d.ts +28 -0
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +91 -1
- package/dist/commands/ai-status.command.d.ts +19 -0
- package/dist/commands/ai-status.command.d.ts.map +1 -0
- package/dist/commands/ai-status.command.js +94 -0
- package/dist/commands/api-diff.command.d.ts +11 -0
- package/dist/commands/api-diff.command.d.ts.map +1 -0
- package/dist/commands/api-diff.command.js +144 -0
- package/dist/commands/apply.command.d.ts.map +1 -1
- package/dist/commands/apply.command.js +10 -2
- package/dist/commands/arch.command.d.ts +9 -0
- package/dist/commands/arch.command.d.ts.map +1 -0
- package/dist/commands/arch.command.js +186 -0
- package/dist/commands/ask.command.d.ts.map +1 -1
- package/dist/commands/ask.command.js +10 -9
- package/dist/commands/cache-align.command.d.ts +12 -0
- package/dist/commands/cache-align.command.d.ts.map +1 -0
- package/dist/commands/cache-align.command.js +78 -0
- package/dist/commands/check.command.d.ts.map +1 -1
- package/dist/commands/check.command.js +26 -2
- package/dist/commands/code-intel.command.d.ts +18 -0
- package/dist/commands/code-intel.command.d.ts.map +1 -0
- package/dist/commands/code-intel.command.js +146 -0
- package/dist/commands/codemod.command.d.ts.map +1 -1
- package/dist/commands/codemod.command.js +27 -6
- package/dist/commands/command-catalog.d.ts +15 -3
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +407 -34
- package/dist/commands/commands.command.d.ts.map +1 -1
- package/dist/commands/commands.command.js +4 -4
- package/dist/commands/completion.command.d.ts +10 -0
- package/dist/commands/completion.command.d.ts.map +1 -0
- package/dist/commands/completion.command.js +121 -0
- package/dist/commands/compress.command.d.ts +8 -0
- package/dist/commands/compress.command.d.ts.map +1 -0
- package/dist/commands/compress.command.js +147 -0
- package/dist/commands/constructs.command.d.ts.map +1 -1
- package/dist/commands/constructs.command.js +89 -23
- package/dist/commands/context.command.d.ts.map +1 -1
- package/dist/commands/context.command.js +121 -1
- package/dist/commands/contract-gate.command.d.ts.map +1 -1
- package/dist/commands/contract-gate.command.js +5 -1
- package/dist/commands/delegate.command.d.ts +65 -0
- package/dist/commands/delegate.command.d.ts.map +1 -0
- package/dist/commands/delegate.command.js +657 -0
- package/dist/commands/deps-audit.command.d.ts +23 -0
- package/dist/commands/deps-audit.command.d.ts.map +1 -0
- package/dist/commands/deps-audit.command.js +270 -0
- package/dist/commands/dev.command.d.ts.map +1 -1
- package/dist/commands/dev.command.js +5 -2
- package/dist/commands/diff-check.command.d.ts +30 -0
- package/dist/commands/diff-check.command.d.ts.map +1 -0
- package/dist/commands/diff-check.command.js +210 -0
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +162 -10
- package/dist/commands/export.command.d.ts.map +1 -1
- package/dist/commands/export.command.js +76 -3
- package/dist/commands/framework.command.d.ts +12 -0
- package/dist/commands/framework.command.d.ts.map +1 -0
- package/dist/commands/framework.command.js +180 -0
- package/dist/commands/gate.command.d.ts +15 -0
- package/dist/commands/gate.command.d.ts.map +1 -0
- package/dist/commands/gate.command.js +300 -0
- package/dist/commands/gen.command.d.ts.map +1 -1
- package/dist/commands/gen.command.js +13 -1
- package/dist/commands/graph-code-subverbs.d.ts +33 -0
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -0
- package/dist/commands/graph-code-subverbs.js +1385 -0
- package/dist/commands/graph.command.d.ts.map +1 -1
- package/dist/commands/graph.command.js +31 -2
- package/dist/commands/help.command.d.ts +4 -3
- package/dist/commands/help.command.d.ts.map +1 -1
- package/dist/commands/help.command.js +86 -18
- package/dist/commands/helper.command.js +1 -1
- package/dist/commands/impact.command.d.ts.map +1 -1
- package/dist/commands/impact.command.js +171 -1
- package/dist/commands/import.command.d.ts.map +1 -1
- package/dist/commands/import.command.js +121 -5
- package/dist/commands/ingest.command.d.ts.map +1 -1
- package/dist/commands/ingest.command.js +5 -1
- package/dist/commands/init.command.d.ts.map +1 -1
- package/dist/commands/init.command.js +174 -7
- package/dist/commands/knowledge-author.command.d.ts.map +1 -1
- package/dist/commands/knowledge-author.command.js +9 -0
- package/dist/commands/knowledge-propose.command.d.ts.map +1 -1
- package/dist/commands/knowledge-propose.command.js +4 -2
- package/dist/commands/knowledge.command.d.ts.map +1 -1
- package/dist/commands/knowledge.command.js +26 -3
- package/dist/commands/migrate.command.d.ts +13 -0
- package/dist/commands/migrate.command.d.ts.map +1 -0
- package/dist/commands/migrate.command.js +152 -0
- package/dist/commands/move-plan.command.d.ts +23 -0
- package/dist/commands/move-plan.command.d.ts.map +1 -0
- package/dist/commands/move-plan.command.js +360 -0
- package/dist/commands/packs-new.d.ts +1 -1
- package/dist/commands/packs-new.d.ts.map +1 -1
- package/dist/commands/packs-new.js +5 -36
- package/dist/commands/packs.command.d.ts.map +1 -1
- package/dist/commands/packs.command.js +2 -10
- package/dist/commands/plan-context.command.d.ts +11 -0
- package/dist/commands/plan-context.command.d.ts.map +1 -0
- package/dist/commands/plan-context.command.js +85 -0
- package/dist/commands/preflight.command.d.ts.map +1 -1
- package/dist/commands/preflight.command.js +15 -0
- package/dist/commands/profiles.command.js +4 -4
- package/dist/commands/recommend.command.d.ts +6 -0
- package/dist/commands/recommend.command.d.ts.map +1 -1
- package/dist/commands/recommend.command.js +119 -5
- package/dist/commands/release.command.js +13 -13
- package/dist/commands/rule-graph-subverbs.d.ts +3 -0
- package/dist/commands/rule-graph-subverbs.d.ts.map +1 -0
- package/dist/commands/rule-graph-subverbs.js +132 -0
- package/dist/commands/rules.command.d.ts.map +1 -1
- package/dist/commands/rules.command.js +20 -3
- package/dist/commands/scaffold-validate.command.d.ts +22 -0
- package/dist/commands/scaffold-validate.command.d.ts.map +1 -0
- package/dist/commands/scaffold-validate.command.js +215 -0
- package/dist/commands/search-structural.command.d.ts +18 -0
- package/dist/commands/search-structural.command.d.ts.map +1 -0
- package/dist/commands/search-structural.command.js +376 -0
- package/dist/commands/search.command.js +1 -1
- package/dist/commands/smart-context.command.d.ts +67 -0
- package/dist/commands/smart-context.command.d.ts.map +1 -0
- package/dist/commands/smart-context.command.js +4728 -0
- package/dist/commands/spike.command.d.ts +22 -0
- package/dist/commands/spike.command.d.ts.map +1 -0
- package/dist/commands/spike.command.js +235 -0
- package/dist/commands/surface.command.d.ts +1 -0
- package/dist/commands/surface.command.d.ts.map +1 -1
- package/dist/commands/surface.command.js +10 -3
- package/dist/commands/task-context.command.d.ts.map +1 -1
- package/dist/commands/task-context.command.js +5 -17
- package/dist/commands/task.command.d.ts.map +1 -1
- package/dist/commands/task.command.js +8 -2
- package/dist/commands/template-quality.command.d.ts.map +1 -1
- package/dist/commands/template-quality.command.js +39 -3
- package/dist/commands/templates.command.d.ts.map +1 -1
- package/dist/commands/templates.command.js +37 -2
- package/dist/commands/tests.command.d.ts.map +1 -1
- package/dist/commands/tests.command.js +13 -2
- package/dist/commands/watch.command.d.ts +26 -0
- package/dist/commands/watch.command.d.ts.map +1 -0
- package/dist/commands/watch.command.js +456 -0
- package/dist/dashboard/code-intelligence-data.d.ts +33 -0
- package/dist/dashboard/code-intelligence-data.d.ts.map +1 -0
- package/dist/dashboard/code-intelligence-data.js +329 -0
- package/dist/dashboard/dashboard-api-server.d.ts.map +1 -1
- package/dist/dashboard/dashboard-api-server.js +256 -2
- package/dist/dashboard/knowledge-ask.d.ts +4 -0
- package/dist/dashboard/knowledge-ask.d.ts.map +1 -0
- package/dist/dashboard/knowledge-ask.js +112 -0
- package/dist/env/load-dotenv.d.ts +15 -0
- package/dist/env/load-dotenv.d.ts.map +1 -0
- package/dist/env/load-dotenv.js +70 -0
- package/dist/export/claude-commands-export.d.ts +60 -0
- package/dist/export/claude-commands-export.d.ts.map +1 -0
- package/dist/export/claude-commands-export.js +276 -0
- package/dist/export/export-formats.d.ts +1 -1
- package/dist/export/export-formats.d.ts.map +1 -1
- package/dist/export/export-formats.js +139 -12
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/init/init-templates.d.ts.map +1 -1
- package/dist/init/init-templates.js +133 -113
- package/dist/init/paths-advisory.d.ts +20 -0
- package/dist/init/paths-advisory.d.ts.map +1 -0
- package/dist/init/paths-advisory.js +88 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +331 -17
- package/dist/output/ccr-store-config.d.ts +18 -0
- package/dist/output/ccr-store-config.d.ts.map +1 -0
- package/dist/output/ccr-store-config.js +41 -0
- package/dist/output/format-output.d.ts.map +1 -1
- package/dist/output/format-output.js +6 -1
- package/dist/output/output-compression.d.ts +15 -0
- package/dist/output/output-compression.d.ts.map +1 -0
- package/dist/output/output-compression.js +60 -0
- package/dist/output/resolve-compress-type.d.ts +22 -0
- package/dist/output/resolve-compress-type.d.ts.map +1 -0
- package/dist/output/resolve-compress-type.js +21 -0
- package/dist/output/watch-loop.d.ts +9 -1
- package/dist/output/watch-loop.d.ts.map +1 -1
- package/dist/output/watch-loop.js +13 -3
- package/dist/schemas/json-schemas.d.ts +384 -36
- package/dist/schemas/json-schemas.d.ts.map +1 -1
- package/dist/schemas/json-schemas.js +247 -36
- package/dist/surface/profiles.d.ts.map +1 -1
- package/dist/surface/profiles.js +54 -10
- package/dist/surface/surface-config-writer.d.ts.map +1 -1
- package/dist/surface/surface-config-writer.js +23 -11
- package/dist/validation/run-validation-loop.d.ts.map +1 -1
- package/dist/validation/run-validation-loop.js +5 -1
- package/package.json +35 -21
- package/dist/commands/plugin.command.d.ts +0 -11
- package/dist/commands/plugin.command.d.ts.map +0 -1
- 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 {
|
|
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:
|
|
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
|
-
|
|
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(`
|
|
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
|
-
|
|
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
|
|
663
|
-
|
|
664
|
-
|
|
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
|
-
|
|
671
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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"}
|