@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.
- 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 +19 -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 +387 -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 -1
- 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 +1366 -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 -9
- 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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps-audit.command.d.ts","sourceRoot":"","sources":["../../src/commands/deps-audit.command.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAmBhC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAmE9B,CAAC"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import * as nodePath from 'node:path';
|
|
3
|
+
import { GraphQueryApi, GraphStore, NodeKind } from '@shrkcrft/graph';
|
|
4
|
+
import { flagBool, resolveCwd, } from "../command-registry.js";
|
|
5
|
+
import { asJson, header } from "../output/format-output.js";
|
|
6
|
+
/**
|
|
7
|
+
* `shrk deps-audit` — for each workspace package, compare the
|
|
8
|
+
* `package.json` `dependencies` / `devDependencies` / `peerDependencies`
|
|
9
|
+
* against the *specifiers actually imported* from source under
|
|
10
|
+
* `<pkg>/src/` (per the SharkCraft graph).
|
|
11
|
+
*
|
|
12
|
+
* Reports:
|
|
13
|
+
* - missing deps: imported but not declared (likely build failure
|
|
14
|
+
* in the wild — the package depends on its host's resolution)
|
|
15
|
+
* - unused deps: declared but never imported (lint waste)
|
|
16
|
+
*
|
|
17
|
+
* Read-only. JSON output via `--json`. Optionally restricted to one
|
|
18
|
+
* package via `--package <name>`.
|
|
19
|
+
*
|
|
20
|
+
* Known limitations:
|
|
21
|
+
* - Type-only imports (`import type x from 'y'`) still count; the
|
|
22
|
+
* graph can't tell them apart in v3.
|
|
23
|
+
* - Subpath imports (`pkg/sub`) are reduced to their root specifier.
|
|
24
|
+
* - Built-in node modules (`node:fs`, `fs`, …) are ignored.
|
|
25
|
+
*/
|
|
26
|
+
export const depsAuditCommand = {
|
|
27
|
+
name: 'deps-audit',
|
|
28
|
+
description: 'Audit declared dependencies vs imports actually seen in each package source. Reports missing + unused deps. Read-only.',
|
|
29
|
+
usage: 'shrk deps-audit [--package <name>] [--json]',
|
|
30
|
+
async run(args) {
|
|
31
|
+
const cwd = resolveCwd(args);
|
|
32
|
+
const json = flagBool(args, 'json');
|
|
33
|
+
const onlyPackage = typeof args.flags.get('package') === 'string'
|
|
34
|
+
? args.flags.get('package')
|
|
35
|
+
: null;
|
|
36
|
+
const store = new GraphStore(cwd);
|
|
37
|
+
if (!store.exists()) {
|
|
38
|
+
process.stderr.write('No SharkCraft graph found. Run `shrk graph index` first so deps-audit has import data.\n');
|
|
39
|
+
return 1;
|
|
40
|
+
}
|
|
41
|
+
const api = GraphQueryApi.fromStore(cwd);
|
|
42
|
+
const packages = listWorkspacePackages(cwd, onlyPackage);
|
|
43
|
+
if (packages.length === 0) {
|
|
44
|
+
process.stderr.write('No packages found (looked under packages/*, libs/*, apps/*).\n');
|
|
45
|
+
return 1;
|
|
46
|
+
}
|
|
47
|
+
const reports = [];
|
|
48
|
+
for (const pkg of packages) {
|
|
49
|
+
reports.push(buildPackageReport(api, cwd, pkg));
|
|
50
|
+
}
|
|
51
|
+
if (json) {
|
|
52
|
+
process.stdout.write(asJson({ packages: reports }) + '\n');
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
let missingTotal = 0;
|
|
56
|
+
let unusedTotal = 0;
|
|
57
|
+
for (const r of reports) {
|
|
58
|
+
missingTotal += r.missingDeps.length;
|
|
59
|
+
unusedTotal += r.unusedDeps.length;
|
|
60
|
+
}
|
|
61
|
+
process.stdout.write(header(`deps-audit — ${reports.length} package(s), ${missingTotal} missing dep(s), ${unusedTotal} unused dep(s)`));
|
|
62
|
+
for (const r of reports) {
|
|
63
|
+
if (r.missingDeps.length === 0 && r.unusedDeps.length === 0)
|
|
64
|
+
continue;
|
|
65
|
+
process.stdout.write(`\n${r.packageName} (${r.packageDir})\n`);
|
|
66
|
+
if (r.missingDeps.length > 0) {
|
|
67
|
+
process.stdout.write(' missing (imported, not declared):\n');
|
|
68
|
+
for (const m of r.missingDeps) {
|
|
69
|
+
process.stdout.write(` - ${m.specifier} (imported ${m.importedFromCount}×)\n`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (r.unusedDeps.length > 0) {
|
|
73
|
+
process.stdout.write(' unused (declared, never imported):\n');
|
|
74
|
+
for (const u of r.unusedDeps) {
|
|
75
|
+
process.stdout.write(` - ${u.specifier} [${u.section}]\n`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (missingTotal === 0 && unusedTotal === 0) {
|
|
80
|
+
process.stdout.write('\nAll declared deps match actual imports. ✓\n');
|
|
81
|
+
}
|
|
82
|
+
return 0;
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
function listWorkspacePackages(cwd, onlyName) {
|
|
86
|
+
const roots = ['packages', 'libs', 'apps'].map((r) => nodePath.join(cwd, r)).filter((d) => existsSync(d));
|
|
87
|
+
const out = [];
|
|
88
|
+
for (const root of roots) {
|
|
89
|
+
let entries;
|
|
90
|
+
try {
|
|
91
|
+
entries = readdirSync(root);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
const dir = nodePath.join(root, entry);
|
|
98
|
+
let stat;
|
|
99
|
+
try {
|
|
100
|
+
stat = statSync(dir);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (!stat.isDirectory())
|
|
106
|
+
continue;
|
|
107
|
+
const pkgJsonPath = nodePath.join(dir, 'package.json');
|
|
108
|
+
if (!existsSync(pkgJsonPath))
|
|
109
|
+
continue;
|
|
110
|
+
let pkgJson;
|
|
111
|
+
try {
|
|
112
|
+
pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (!pkgJson.name)
|
|
118
|
+
continue;
|
|
119
|
+
if (onlyName !== null && pkgJson.name !== onlyName)
|
|
120
|
+
continue;
|
|
121
|
+
out.push({ name: pkgJson.name, dir, pkgJsonPath });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
function buildPackageReport(api, cwd, pkg) {
|
|
127
|
+
const declared = readDeclaredDeps(pkg.pkgJsonPath);
|
|
128
|
+
const importedSpecifiers = collectImportedSpecifiersForPackage(api, cwd, pkg.dir);
|
|
129
|
+
// Count how many distinct files inside the package import each specifier.
|
|
130
|
+
const importerCounts = new Map();
|
|
131
|
+
for (const spec of importedSpecifiers) {
|
|
132
|
+
importerCounts.set(spec, (importerCounts.get(spec) ?? 0) + 1);
|
|
133
|
+
}
|
|
134
|
+
const distinctImported = new Set(importedSpecifiers);
|
|
135
|
+
const declaredAll = new Map();
|
|
136
|
+
const declaredSections = [
|
|
137
|
+
['dependencies', declared.dependencies],
|
|
138
|
+
['devDependencies', declared.devDependencies],
|
|
139
|
+
['peerDependencies', declared.peerDependencies],
|
|
140
|
+
['optionalDependencies', declared.optionalDependencies],
|
|
141
|
+
];
|
|
142
|
+
for (const [section, map] of declaredSections) {
|
|
143
|
+
for (const k of Object.keys(map))
|
|
144
|
+
declaredAll.set(k, section);
|
|
145
|
+
}
|
|
146
|
+
const missingDeps = [];
|
|
147
|
+
for (const spec of distinctImported) {
|
|
148
|
+
if (declaredAll.has(spec))
|
|
149
|
+
continue;
|
|
150
|
+
if (spec === pkg.name)
|
|
151
|
+
continue; // self-import via package name
|
|
152
|
+
missingDeps.push({ specifier: spec, importedFromCount: importerCounts.get(spec) ?? 0 });
|
|
153
|
+
}
|
|
154
|
+
missingDeps.sort((a, b) => b.importedFromCount - a.importedFromCount);
|
|
155
|
+
const unusedDeps = [];
|
|
156
|
+
for (const [spec, section] of declaredAll.entries()) {
|
|
157
|
+
if (distinctImported.has(spec))
|
|
158
|
+
continue;
|
|
159
|
+
// devDependencies for build/test tools often don't show up in graph
|
|
160
|
+
// imports; we still report them so the user can prune if desired.
|
|
161
|
+
unusedDeps.push({ specifier: spec, section });
|
|
162
|
+
}
|
|
163
|
+
unusedDeps.sort((a, b) => a.specifier.localeCompare(b.specifier));
|
|
164
|
+
return {
|
|
165
|
+
packageName: pkg.name,
|
|
166
|
+
packageDir: nodePath.relative(cwd, pkg.dir) || '.',
|
|
167
|
+
declared,
|
|
168
|
+
importedSpecifiers: [...distinctImported],
|
|
169
|
+
missingDeps,
|
|
170
|
+
unusedDeps,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function readDeclaredDeps(pkgJsonPath) {
|
|
174
|
+
try {
|
|
175
|
+
const body = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
|
|
176
|
+
return {
|
|
177
|
+
dependencies: asStringMap(body['dependencies']),
|
|
178
|
+
devDependencies: asStringMap(body['devDependencies']),
|
|
179
|
+
peerDependencies: asStringMap(body['peerDependencies']),
|
|
180
|
+
optionalDependencies: asStringMap(body['optionalDependencies']),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return { dependencies: {}, devDependencies: {}, peerDependencies: {}, optionalDependencies: {} };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function asStringMap(value) {
|
|
188
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
189
|
+
return {};
|
|
190
|
+
const out = {};
|
|
191
|
+
for (const [k, v] of Object.entries(value)) {
|
|
192
|
+
if (typeof v === 'string')
|
|
193
|
+
out[k] = v;
|
|
194
|
+
}
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
function collectImportedSpecifiersForPackage(api, cwd, packageDir) {
|
|
198
|
+
const out = [];
|
|
199
|
+
const relDir = nodePath.relative(cwd, packageDir).replace(/\\/g, '/');
|
|
200
|
+
for (const file of api.allFiles()) {
|
|
201
|
+
if (file.kind !== NodeKind.File)
|
|
202
|
+
continue;
|
|
203
|
+
const p = file.path ?? '';
|
|
204
|
+
if (!p.startsWith(relDir + '/src/') && !p.startsWith(relDir + '/'))
|
|
205
|
+
continue;
|
|
206
|
+
// Each ImportsFile edge resolves to a file node; we want the *raw*
|
|
207
|
+
// import specifier, which the graph carries on the edge's data
|
|
208
|
+
// payload. We don't have direct access here, so we approximate by
|
|
209
|
+
// reading the file contents and extracting from-clauses.
|
|
210
|
+
const abs = nodePath.isAbsolute(p) ? p : nodePath.join(cwd, p);
|
|
211
|
+
if (!existsSync(abs))
|
|
212
|
+
continue;
|
|
213
|
+
let body;
|
|
214
|
+
try {
|
|
215
|
+
body = readFileSync(abs, 'utf8');
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
for (const spec of extractRootSpecifiers(body)) {
|
|
221
|
+
if (isBuiltinModule(spec))
|
|
222
|
+
continue;
|
|
223
|
+
if (spec.startsWith('.') || spec.startsWith('/'))
|
|
224
|
+
continue; // relative
|
|
225
|
+
out.push(rootOfSpecifier(spec));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return out;
|
|
229
|
+
}
|
|
230
|
+
const IMPORT_FROM_RE = /(?:^|\n)\s*(?:import|export)\s+[^;]*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
231
|
+
const REQUIRE_RE = /\brequire\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
232
|
+
const DYNAMIC_IMPORT_RE = /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
233
|
+
function extractRootSpecifiers(body) {
|
|
234
|
+
const out = [];
|
|
235
|
+
for (const m of body.matchAll(IMPORT_FROM_RE)) {
|
|
236
|
+
if (m[1])
|
|
237
|
+
out.push(m[1]);
|
|
238
|
+
}
|
|
239
|
+
for (const m of body.matchAll(REQUIRE_RE)) {
|
|
240
|
+
if (m[1])
|
|
241
|
+
out.push(m[1]);
|
|
242
|
+
}
|
|
243
|
+
for (const m of body.matchAll(DYNAMIC_IMPORT_RE)) {
|
|
244
|
+
if (m[1])
|
|
245
|
+
out.push(m[1]);
|
|
246
|
+
}
|
|
247
|
+
return out;
|
|
248
|
+
}
|
|
249
|
+
function rootOfSpecifier(spec) {
|
|
250
|
+
if (spec.startsWith('@')) {
|
|
251
|
+
const parts = spec.split('/');
|
|
252
|
+
return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : spec;
|
|
253
|
+
}
|
|
254
|
+
return spec.split('/')[0];
|
|
255
|
+
}
|
|
256
|
+
function isBuiltinModule(spec) {
|
|
257
|
+
if (spec.startsWith('node:'))
|
|
258
|
+
return true;
|
|
259
|
+
// Bun runtime builtins (`bun:test`, `bun:sqlite`, `bun:ffi`, …) are provided by
|
|
260
|
+
// the runtime, never an npm dependency — so they are not "missing".
|
|
261
|
+
if (spec.startsWith('bun:'))
|
|
262
|
+
return true;
|
|
263
|
+
// Common bare-name builtins.
|
|
264
|
+
return new Set([
|
|
265
|
+
'fs', 'path', 'os', 'crypto', 'http', 'https', 'url', 'util', 'stream',
|
|
266
|
+
'events', 'child_process', 'process', 'buffer', 'querystring', 'zlib',
|
|
267
|
+
'tls', 'net', 'dns', 'dgram', 'cluster', 'worker_threads', 'perf_hooks',
|
|
268
|
+
'readline', 'tty', 'vm',
|
|
269
|
+
]).has(spec);
|
|
270
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.command.d.ts","sourceRoot":"","sources":["../../src/commands/dev.command.ts"],"names":[],"mappings":"AA6CA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.command.d.ts","sourceRoot":"","sources":["../../src/commands/dev.command.ts"],"names":[],"mappings":"AA6CA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAi8ChC,eAAO,MAAM,UAAU,EAAE,eAkExB,CAAC"}
|
|
@@ -672,7 +672,11 @@ async function validateSession(args) {
|
|
|
672
672
|
const allVerifications = flagBool(args, 'all-verifications');
|
|
673
673
|
const allowPackCommands = flagBool(args, 'allow-pack-commands');
|
|
674
674
|
const wantStrict = flagBool(args, 'strict');
|
|
675
|
-
|
|
675
|
+
// flagBool is two-valued (absent → false), so `flagBool(...) !== false` is
|
|
676
|
+
// false when the flag is absent — the opposite of the intended default. Read
|
|
677
|
+
// the raw value: write the report by default, opt out only via --report=false.
|
|
678
|
+
const reportFlag = args.flags.get('report');
|
|
679
|
+
const wantReport = reportFlag !== false && reportFlag !== 'false';
|
|
676
680
|
const wantJson = flagBool(args, 'json');
|
|
677
681
|
const startedAt = new Date().toISOString();
|
|
678
682
|
const reportFileName = `validate-${startedAt.replace(/[:.]/g, '-')}.json`;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `shrk diff-check` — agent self-validation after edits.
|
|
3
|
+
*
|
|
4
|
+
* The story this command tells:
|
|
5
|
+
* 1. An AI agent (Claude Code, Cursor, etc.) makes some file changes.
|
|
6
|
+
* 2. Before declaring "done", the agent runs `shrk diff-check`.
|
|
7
|
+
* 3. The command scopes both the boundary check and the
|
|
8
|
+
* import-hygiene check to only the files the agent touched in the
|
|
9
|
+
* current git diff.
|
|
10
|
+
* 4. The output is a single agent-friendly JSON envelope with a
|
|
11
|
+
* verdict (ok / warnings / errors) and a one-line next action.
|
|
12
|
+
*
|
|
13
|
+
* Why a new command instead of "just run `shrk check boundaries
|
|
14
|
+
* --changed-only` and `shrk check imports --changed-only`":
|
|
15
|
+
*
|
|
16
|
+
* - One command instead of two — agents reliably run the *one* tool
|
|
17
|
+
* they're told to run; chained-command workflows get skipped.
|
|
18
|
+
* - One verdict — no need to OR two separate JSON outputs.
|
|
19
|
+
* - Stable, narrow schema — designed for agent consumption, not
|
|
20
|
+
* human terminals. Won't grow flags over time.
|
|
21
|
+
* - Concrete `nextAction` line — the agent knows exactly what to do
|
|
22
|
+
* next (declare done, fix N things, or re-run after a manual fix).
|
|
23
|
+
*
|
|
24
|
+
* This is a pure composer — all real logic stays in
|
|
25
|
+
* `@shrkcrft/inspector` and `@shrkcrft/boundaries`. We just stitch
|
|
26
|
+
* their outputs together with consistent scoping.
|
|
27
|
+
*/
|
|
28
|
+
import { type ICommandHandler } from '../command-registry.js';
|
|
29
|
+
export declare const diffCheckCommand: ICommandHandler;
|
|
30
|
+
//# sourceMappingURL=diff-check.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-check.command.d.ts","sourceRoot":"","sources":["../../src/commands/diff-check.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAcH,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA0GhC,eAAO,MAAM,gBAAgB,EAAE,eAiI9B,CAAC"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `shrk diff-check` — agent self-validation after edits.
|
|
3
|
+
*
|
|
4
|
+
* The story this command tells:
|
|
5
|
+
* 1. An AI agent (Claude Code, Cursor, etc.) makes some file changes.
|
|
6
|
+
* 2. Before declaring "done", the agent runs `shrk diff-check`.
|
|
7
|
+
* 3. The command scopes both the boundary check and the
|
|
8
|
+
* import-hygiene check to only the files the agent touched in the
|
|
9
|
+
* current git diff.
|
|
10
|
+
* 4. The output is a single agent-friendly JSON envelope with a
|
|
11
|
+
* verdict (ok / warnings / errors) and a one-line next action.
|
|
12
|
+
*
|
|
13
|
+
* Why a new command instead of "just run `shrk check boundaries
|
|
14
|
+
* --changed-only` and `shrk check imports --changed-only`":
|
|
15
|
+
*
|
|
16
|
+
* - One command instead of two — agents reliably run the *one* tool
|
|
17
|
+
* they're told to run; chained-command workflows get skipped.
|
|
18
|
+
* - One verdict — no need to OR two separate JSON outputs.
|
|
19
|
+
* - Stable, narrow schema — designed for agent consumption, not
|
|
20
|
+
* human terminals. Won't grow flags over time.
|
|
21
|
+
* - Concrete `nextAction` line — the agent knows exactly what to do
|
|
22
|
+
* next (declare done, fix N things, or re-run after a manual fix).
|
|
23
|
+
*
|
|
24
|
+
* This is a pure composer — all real logic stays in
|
|
25
|
+
* `@shrkcrft/inspector` and `@shrkcrft/boundaries`. We just stitch
|
|
26
|
+
* their outputs together with consistent scoping.
|
|
27
|
+
*/
|
|
28
|
+
import { buildImportHygieneReport, filterViolationsToChangedScope, inspectSharkcraft, resolveChangedFiles, } from '@shrkcrft/inspector';
|
|
29
|
+
import { evaluateBoundaries, loadTsconfigPaths, scanImports, } from '@shrkcrft/boundaries';
|
|
30
|
+
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
31
|
+
import { asJson, bullet, header, kv } from "../output/format-output.js";
|
|
32
|
+
const SCHEMA = 'sharkcraft.diff-check/v1';
|
|
33
|
+
function resolveScope(args, cwd) {
|
|
34
|
+
const staged = flagBool(args, 'staged');
|
|
35
|
+
const since = flagString(args, 'since');
|
|
36
|
+
const filesRaw = flagString(args, 'files');
|
|
37
|
+
const files = filesRaw
|
|
38
|
+
? filesRaw.split(',').map((s) => s.trim()).filter((s) => s.length > 0)
|
|
39
|
+
: [];
|
|
40
|
+
if (files.length > 0) {
|
|
41
|
+
return { mode: 'files', options: { projectRoot: cwd, files } };
|
|
42
|
+
}
|
|
43
|
+
if (staged) {
|
|
44
|
+
return { mode: 'staged', options: { projectRoot: cwd, staged: true } };
|
|
45
|
+
}
|
|
46
|
+
if (since) {
|
|
47
|
+
return { mode: 'since', options: { projectRoot: cwd, since } };
|
|
48
|
+
}
|
|
49
|
+
// Default: worktree (== `--changed-only` from `shrk check boundaries`).
|
|
50
|
+
return {
|
|
51
|
+
mode: 'worktree',
|
|
52
|
+
options: { projectRoot: cwd, includeWorktree: true },
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function deriveVerdict(env) {
|
|
56
|
+
const bErr = env.boundaries.counts.error;
|
|
57
|
+
const bWarn = env.boundaries.counts.warning;
|
|
58
|
+
const iErr = env.imports.verdict === 'errors' ? (env.imports.counts.error ?? env.imports.findings.length) : 0;
|
|
59
|
+
const iWarn = env.imports.verdict === 'warnings' ? (env.imports.counts.warning ?? env.imports.findings.length) : 0;
|
|
60
|
+
if (env.scope.fileCount === 0) {
|
|
61
|
+
return {
|
|
62
|
+
verdict: 'ok',
|
|
63
|
+
summary: 'No files changed in the current diff scope.',
|
|
64
|
+
nextAction: 'Nothing to check. If you expected changes, verify your `--staged` / `--since <ref>` flag or save your edits first.',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (bErr > 0 || iErr > 0) {
|
|
68
|
+
const parts = [];
|
|
69
|
+
if (bErr > 0)
|
|
70
|
+
parts.push(`${bErr} boundary violation${bErr === 1 ? '' : 's'}`);
|
|
71
|
+
if (iErr > 0)
|
|
72
|
+
parts.push(`${iErr} import-hygiene error${iErr === 1 ? '' : 's'}`);
|
|
73
|
+
return {
|
|
74
|
+
verdict: 'errors',
|
|
75
|
+
summary: `Diff fails the gate: ${parts.join(', ')}.`,
|
|
76
|
+
nextAction: 'Fix every error in `boundaries.violations` and `imports.findings` (look at each entry\'s `suggestedFix` line), then re-run `shrk diff-check`.',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (bWarn > 0 || iWarn > 0) {
|
|
80
|
+
const parts = [];
|
|
81
|
+
if (bWarn > 0)
|
|
82
|
+
parts.push(`${bWarn} boundary warning${bWarn === 1 ? '' : 's'}`);
|
|
83
|
+
if (iWarn > 0)
|
|
84
|
+
parts.push(`${iWarn} import-hygiene warning${iWarn === 1 ? '' : 's'}`);
|
|
85
|
+
return {
|
|
86
|
+
verdict: 'warnings',
|
|
87
|
+
summary: `Diff passes the gate with ${parts.join(', ')}.`,
|
|
88
|
+
nextAction: 'Safe to declare done. Review warnings if the diff touches a sensitive area; otherwise these are non-blocking.',
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
verdict: 'ok',
|
|
93
|
+
summary: `Diff passes the gate (${env.scope.fileCount} file${env.scope.fileCount === 1 ? '' : 's'}, 0 violations).`,
|
|
94
|
+
nextAction: 'Safe to declare done.',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export const diffCheckCommand = {
|
|
98
|
+
name: 'diff-check',
|
|
99
|
+
description: 'Self-check the current git diff against this project\'s boundary + import-hygiene rules. Single-call composite of `shrk check boundaries --changed-only` + `shrk check imports --changed-only`, with one verdict and one nextAction line. Designed for AI agents to run after editing — pass --json for the structured envelope.',
|
|
100
|
+
usage: 'shrk [--cwd <dir>] diff-check [--staged | --since <ref> | --files a.ts,b.ts] [--json]',
|
|
101
|
+
async run(args) {
|
|
102
|
+
const cwd = resolveCwd(args);
|
|
103
|
+
const wantJson = flagBool(args, 'json');
|
|
104
|
+
const { mode, options: scopeOptions } = resolveScope(args, cwd);
|
|
105
|
+
// 1. Resolve the changed file set once. Both engines re-use it.
|
|
106
|
+
const changed = resolveChangedFiles(scopeOptions);
|
|
107
|
+
const changedFiles = changed.files;
|
|
108
|
+
// 2. Boundary engine — only if rules exist.
|
|
109
|
+
const inspection = await inspectSharkcraft({ cwd });
|
|
110
|
+
const rules = inspection.boundaryRegistry.list();
|
|
111
|
+
let boundaryBlock = {
|
|
112
|
+
ran: false,
|
|
113
|
+
rulesEvaluated: 0,
|
|
114
|
+
counts: { error: 0, warning: 0, info: 0 },
|
|
115
|
+
violations: [],
|
|
116
|
+
};
|
|
117
|
+
if (rules.length > 0 && changedFiles.length > 0) {
|
|
118
|
+
const scan = scanImports({ projectRoot: cwd });
|
|
119
|
+
const tsconfigPaths = loadTsconfigPaths(cwd);
|
|
120
|
+
const evalResult = evaluateBoundaries(scan, rules, {
|
|
121
|
+
...(tsconfigPaths.aliases.size > 0 ? { tsconfigPaths } : {}),
|
|
122
|
+
});
|
|
123
|
+
const filtered = filterViolationsToChangedScope(evalResult.violations, scopeOptions);
|
|
124
|
+
boundaryBlock = {
|
|
125
|
+
ran: true,
|
|
126
|
+
rulesEvaluated: evalResult.rulesEvaluated,
|
|
127
|
+
counts: {
|
|
128
|
+
error: filtered.includedViolations.filter((v) => v.severity === 'error').length,
|
|
129
|
+
warning: filtered.includedViolations.filter((v) => v.severity === 'warning').length,
|
|
130
|
+
info: filtered.includedViolations.filter((v) => v.severity === 'info').length,
|
|
131
|
+
},
|
|
132
|
+
violations: filtered.includedViolations,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
else if (rules.length > 0 && changedFiles.length === 0) {
|
|
136
|
+
boundaryBlock = { ...boundaryBlock, ran: true, rulesEvaluated: rules.length };
|
|
137
|
+
}
|
|
138
|
+
// 3. Import-hygiene engine — always runs, but scoped to changed files.
|
|
139
|
+
let importsBlock = {
|
|
140
|
+
ran: false,
|
|
141
|
+
verdict: 'skipped',
|
|
142
|
+
counts: {},
|
|
143
|
+
findings: [],
|
|
144
|
+
};
|
|
145
|
+
if (changedFiles.length > 0) {
|
|
146
|
+
const report = buildImportHygieneReport(cwd, { files: changedFiles });
|
|
147
|
+
importsBlock = {
|
|
148
|
+
ran: true,
|
|
149
|
+
verdict: report.verdict,
|
|
150
|
+
counts: report.counts ?? {},
|
|
151
|
+
findings: report.findings,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// 4. Build envelope + derive verdict.
|
|
155
|
+
const partial = {
|
|
156
|
+
schema: SCHEMA,
|
|
157
|
+
generatedAt: new Date().toISOString(),
|
|
158
|
+
scope: {
|
|
159
|
+
mode,
|
|
160
|
+
files: changedFiles,
|
|
161
|
+
fileCount: changedFiles.length,
|
|
162
|
+
},
|
|
163
|
+
boundaries: boundaryBlock,
|
|
164
|
+
imports: importsBlock,
|
|
165
|
+
};
|
|
166
|
+
const { verdict, summary, nextAction } = deriveVerdict(partial);
|
|
167
|
+
const envelope = { ...partial, verdict, summary, nextAction };
|
|
168
|
+
// 5. Render.
|
|
169
|
+
if (wantJson) {
|
|
170
|
+
process.stdout.write(asJson(envelope) + '\n');
|
|
171
|
+
return verdict === 'errors' ? 1 : 0;
|
|
172
|
+
}
|
|
173
|
+
process.stdout.write(header('Diff check'));
|
|
174
|
+
process.stdout.write(kv('scope', `${envelope.scope.mode} (${envelope.scope.fileCount} file${envelope.scope.fileCount === 1 ? '' : 's'})`) + '\n');
|
|
175
|
+
process.stdout.write(kv('boundaries', envelope.boundaries.ran
|
|
176
|
+
? `${envelope.boundaries.counts.error} errors, ${envelope.boundaries.counts.warning} warnings`
|
|
177
|
+
: '(no rules configured or no scoped files)') + '\n');
|
|
178
|
+
process.stdout.write(kv('imports', envelope.imports.ran
|
|
179
|
+
? `verdict=${envelope.imports.verdict} (${envelope.imports.findings.length} finding${envelope.imports.findings.length === 1 ? '' : 's'})`
|
|
180
|
+
: '(no scoped files)') + '\n');
|
|
181
|
+
process.stdout.write(kv('verdict', envelope.verdict) + '\n');
|
|
182
|
+
process.stdout.write('\n');
|
|
183
|
+
process.stdout.write(envelope.summary + '\n');
|
|
184
|
+
if (envelope.boundaries.violations.length > 0) {
|
|
185
|
+
process.stdout.write('\nBoundary violations:\n');
|
|
186
|
+
for (const v of envelope.boundaries.violations.slice(0, 10)) {
|
|
187
|
+
const file = String(v.file ?? '');
|
|
188
|
+
const rule = String(v.ruleId ?? '');
|
|
189
|
+
const fix = v.suggestedFix ? ` — ${String(v.suggestedFix)}` : '';
|
|
190
|
+
process.stdout.write(bullet(`${rule} in ${file}${fix}`) + '\n');
|
|
191
|
+
}
|
|
192
|
+
if (envelope.boundaries.violations.length > 10) {
|
|
193
|
+
process.stdout.write(` … and ${envelope.boundaries.violations.length - 10} more (pass --json for full list).\n`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (envelope.imports.findings.length > 0) {
|
|
197
|
+
process.stdout.write('\nImport findings:\n');
|
|
198
|
+
for (const f of envelope.imports.findings.slice(0, 10)) {
|
|
199
|
+
const file = String(f.path ?? f.file ?? '');
|
|
200
|
+
const kind = String(f.kind ?? '');
|
|
201
|
+
process.stdout.write(bullet(`${kind} in ${file}`) + '\n');
|
|
202
|
+
}
|
|
203
|
+
if (envelope.imports.findings.length > 10) {
|
|
204
|
+
process.stdout.write(` … and ${envelope.imports.findings.length - 10} more (pass --json for full list).\n`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
process.stdout.write(`\nNext: ${envelope.nextAction}\n`);
|
|
208
|
+
return verdict === 'errors' ? 1 : 0;
|
|
209
|
+
},
|
|
210
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA6PhC,eAAO,MAAM,aAAa,EAAE,eAW3B,CAAC;AAwfF,eAAO,MAAM,qBAAqB,EAAE,eAmCnC,CAAC;AAuDF,eAAO,MAAM,yBAAyB,EAAE,eAavC,CAAC;AAIF,eAAO,MAAM,wBAAwB,EAAE,eA2CtC,CAAC;AAgCF,eAAO,MAAM,6BAA6B,EAAE,eAa3C,CAAC"}
|