@ankhorage/doctor 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +61 -0
  4. package/dist/analysis.d.ts +17 -0
  5. package/dist/analysis.d.ts.map +1 -0
  6. package/dist/analysis.js +181 -0
  7. package/dist/analysis.js.map +1 -0
  8. package/dist/ankh.provider.d.ts +10 -0
  9. package/dist/ankh.provider.d.ts.map +1 -0
  10. package/dist/ankh.provider.js +27 -0
  11. package/dist/ankh.provider.js.map +1 -0
  12. package/dist/cli.d.ts +10 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +39 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/commandContext.d.ts +12 -0
  17. package/dist/commandContext.d.ts.map +1 -0
  18. package/dist/commandContext.js +15 -0
  19. package/dist/commandContext.js.map +1 -0
  20. package/dist/commands.d.ts +71 -0
  21. package/dist/commands.d.ts.map +1 -0
  22. package/dist/commands.js +207 -0
  23. package/dist/commands.js.map +1 -0
  24. package/dist/diagnostics.d.ts +11 -0
  25. package/dist/diagnostics.d.ts.map +1 -0
  26. package/dist/diagnostics.js +9 -0
  27. package/dist/diagnostics.js.map +1 -0
  28. package/dist/index.d.ts +9 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +6 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/packageMetadata.d.ts +10 -0
  33. package/dist/packageMetadata.d.ts.map +1 -0
  34. package/dist/packageMetadata.js +16 -0
  35. package/dist/packageMetadata.js.map +1 -0
  36. package/dist/readme-usage.d.ts +2 -0
  37. package/dist/readme-usage.d.ts.map +1 -0
  38. package/dist/readme-usage.js +32 -0
  39. package/dist/readme-usage.js.map +1 -0
  40. package/package.json +85 -0
  41. package/src/analysis.ts +354 -0
  42. package/src/ankh.provider.ts +53 -0
  43. package/src/cli.ts +67 -0
  44. package/src/commandContext.ts +27 -0
  45. package/src/commands.ts +312 -0
  46. package/src/diagnostics.ts +33 -0
  47. package/src/index.ts +26 -0
  48. package/src/packageMetadata.ts +23 -0
  49. package/src/readme-usage.ts +32 -0
@@ -0,0 +1,207 @@
1
+ import { analyzeDoctorTarget } from "./analysis.js";
2
+ import { countErrorDiagnostics, countWarningDiagnostics, } from "./diagnostics.js";
3
+ import { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY } from "./packageMetadata.js";
4
+ const COMMAND_CAPABILITIES = {
5
+ validate: DOCTOR_CAPABILITIES[0],
6
+ fix: DOCTOR_CAPABILITIES[1],
7
+ repo: DOCTOR_CAPABILITIES[2],
8
+ package: DOCTOR_CAPABILITIES[3],
9
+ };
10
+ export const DOCTOR_COMMANDS = [
11
+ {
12
+ standaloneName: "validate",
13
+ path: ["validate"],
14
+ capability: COMMAND_CAPABILITIES.validate,
15
+ mode: "validate",
16
+ summary: "Auto-detect lightweight repo and package diagnostics for a local path.",
17
+ run: runValidateCommand,
18
+ },
19
+ {
20
+ standaloneName: "fix",
21
+ path: ["fix"],
22
+ capability: COMMAND_CAPABILITIES.fix,
23
+ mode: "fix",
24
+ summary: "Run the same lightweight checks and report that no automatic fixes exist yet.",
25
+ run: runFixCommand,
26
+ },
27
+ {
28
+ standaloneName: "repo",
29
+ path: ["repo"],
30
+ capability: COMMAND_CAPABILITIES.repo,
31
+ mode: "repo",
32
+ summary: "Force repo-light diagnostics for a repo/workspace-root candidate path.",
33
+ run: runRepoCommand,
34
+ },
35
+ {
36
+ standaloneName: "package",
37
+ path: ["package"],
38
+ capability: COMMAND_CAPABILITIES.package,
39
+ mode: "package",
40
+ summary: "Force package-light diagnostics for a directory containing package.json.",
41
+ run: runPackageCommand,
42
+ },
43
+ ];
44
+ export async function runDoctorCommand(request, options = {}) {
45
+ const services = createDoctorCommandServices(options.services);
46
+ try {
47
+ const parsedArgs = parseCommandArguments(request.command, request.argv);
48
+ if (parsedArgs.kind === "help") {
49
+ request.context.writeStdout(renderCommandHelp(request.command));
50
+ return { exitCode: 0 };
51
+ }
52
+ return await request.command.run({
53
+ context: request.context,
54
+ inputPath: parsedArgs.inputPath,
55
+ }, services);
56
+ }
57
+ catch (error) {
58
+ request.context.writeStderr(renderCommandFailure(request.command.standaloneName, error));
59
+ return { exitCode: 1 };
60
+ }
61
+ }
62
+ export function createProviderCommandDescriptors() {
63
+ return DOCTOR_COMMANDS.map((command) => ({
64
+ capability: command.capability,
65
+ path: command.path,
66
+ summary: command.summary,
67
+ }));
68
+ }
69
+ export function findDoctorCommandByStandaloneName(value) {
70
+ return DOCTOR_COMMANDS.find((command) => command.standaloneName === value) ?? null;
71
+ }
72
+ export function renderRootHelp(version) {
73
+ const commandLines = DOCTOR_COMMANDS.map((command) => ` ${command.standaloneName.padEnd(8, " ")} ${command.summary}`).join("\n");
74
+ return [
75
+ `@ankhorage/doctor v${version}`,
76
+ "",
77
+ "Usage:",
78
+ " ankhorage-doctor <command> [path]",
79
+ ` ankh ${DOCTOR_COMMAND_CATEGORY} <command> [path]`,
80
+ "",
81
+ "Commands:",
82
+ commandLines,
83
+ "",
84
+ "Path resolution:",
85
+ " Pass [path], or omit it to validate the current working directory.",
86
+ "",
87
+ ].join("\n");
88
+ }
89
+ export function renderUnknownCommand(value) {
90
+ return [
91
+ `Unknown doctor command: ${value}`,
92
+ "",
93
+ "Run ankhorage-doctor --help",
94
+ "",
95
+ ].join("\n");
96
+ }
97
+ function renderCommandHelp(command) {
98
+ return [
99
+ command.summary,
100
+ "",
101
+ "Usage:",
102
+ ` ankhorage-doctor ${command.standaloneName} [path]`,
103
+ ` ankh ${DOCTOR_COMMAND_CATEGORY} ${command.path.join(" ")} [path]`,
104
+ "",
105
+ "Path resolution:",
106
+ " Pass [path], or omit it to validate the current working directory.",
107
+ "",
108
+ ].join("\n");
109
+ }
110
+ function createDoctorCommandServices(overrides = {}) {
111
+ return {
112
+ analyzeTarget: overrides.analyzeTarget ?? analyzeDoctorTarget,
113
+ };
114
+ }
115
+ function parseCommandArguments(command, argv) {
116
+ const firstArg = argv[0];
117
+ if (argv.length === 1 && firstArg !== undefined && isHelpToken(firstArg)) {
118
+ return { kind: "help" };
119
+ }
120
+ if (argv.length > 1) {
121
+ throw new Error(`Doctor ${command.standaloneName} accepts at most one path argument.`);
122
+ }
123
+ return {
124
+ kind: "run",
125
+ inputPath: firstArg,
126
+ };
127
+ }
128
+ async function runValidateCommand(request, services) {
129
+ const result = await services.analyzeTarget({
130
+ cwd: request.context.cwd,
131
+ inputPath: request.inputPath,
132
+ mode: "validate",
133
+ });
134
+ request.context.writeStdout(renderAnalysisReport("validate", result));
135
+ return {
136
+ exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,
137
+ };
138
+ }
139
+ async function runFixCommand(request, services) {
140
+ const result = await services.analyzeTarget({
141
+ cwd: request.context.cwd,
142
+ inputPath: request.inputPath,
143
+ mode: "fix",
144
+ });
145
+ request.context.writeStdout(renderAnalysisReport("fix", result));
146
+ request.context.writeStdout("No automatic fixes available.\n");
147
+ return {
148
+ exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,
149
+ };
150
+ }
151
+ async function runRepoCommand(request, services) {
152
+ const result = await services.analyzeTarget({
153
+ cwd: request.context.cwd,
154
+ inputPath: request.inputPath,
155
+ mode: "repo",
156
+ });
157
+ request.context.writeStdout(renderAnalysisReport("repo", result));
158
+ return {
159
+ exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,
160
+ };
161
+ }
162
+ async function runPackageCommand(request, services) {
163
+ const result = await services.analyzeTarget({
164
+ cwd: request.context.cwd,
165
+ inputPath: request.inputPath,
166
+ mode: "package",
167
+ });
168
+ request.context.writeStdout(renderAnalysisReport("package", result));
169
+ return {
170
+ exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,
171
+ };
172
+ }
173
+ function renderAnalysisReport(commandName, result) {
174
+ const lines = [
175
+ `doctor ${commandName}`,
176
+ `target: ${result.targetPath}`,
177
+ `checks: ${result.appliedChecks.length > 0 ? result.appliedChecks.join(", ") : "none"}`,
178
+ `repoMarkers: ${result.repoMarkers.length > 0 ? result.repoMarkers.join(", ") : "none"}`,
179
+ "",
180
+ "Diagnostics:",
181
+ ];
182
+ if (result.diagnostics.length === 0) {
183
+ lines.push(" none");
184
+ }
185
+ else {
186
+ for (const diagnostic of result.diagnostics) {
187
+ lines.push(renderDiagnosticLine(diagnostic));
188
+ }
189
+ }
190
+ const errorCount = countErrorDiagnostics(result.diagnostics);
191
+ const warningCount = countWarningDiagnostics(result.diagnostics);
192
+ lines.push("");
193
+ lines.push(`Summary: ${errorCount} error(s), ${warningCount} warning(s)`);
194
+ lines.push("");
195
+ return lines.join("\n");
196
+ }
197
+ function renderDiagnosticLine(diagnostic) {
198
+ return ` - ${diagnostic.severity.toUpperCase()} ${diagnostic.code}: ${diagnostic.message}`;
199
+ }
200
+ function renderCommandFailure(commandName, error) {
201
+ const message = error instanceof Error ? error.message : String(error);
202
+ return [`Failed to run doctor ${commandName}: ${message}`, ""].join("\n");
203
+ }
204
+ function isHelpToken(value) {
205
+ return value === "--help" || value === "-h" || value === "help";
206
+ }
207
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AnkhCapabilityId,\n AnkhCommandDescriptor,\n} from \"@ankhorage/contracts/cli\";\n\nimport type { DoctorAnalysisResult, DoctorTargetMode } from \"./analysis.js\";\nimport { analyzeDoctorTarget } from \"./analysis.js\";\nimport {\n countErrorDiagnostics,\n countWarningDiagnostics,\n type DoctorDiagnostic,\n} from \"./diagnostics.js\";\nimport { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY } from \"./packageMetadata.js\";\nimport type { DoctorCommandContext, DoctorCommandRunResult } from \"./commandContext.js\";\n\ntype DoctorCommandName = \"fix\" | \"package\" | \"repo\" | \"validate\";\n\ninterface DoctorCommandRunRequest {\n readonly context: DoctorCommandContext;\n readonly inputPath?: string;\n}\n\ntype DoctorCommandImplementation = (\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n) => Promise<DoctorCommandRunResult>;\n\nexport interface DoctorCommandDefinition {\n readonly capability: AnkhCapabilityId;\n readonly mode: DoctorTargetMode;\n readonly path: readonly [DoctorCommandName];\n readonly standaloneName: DoctorCommandName;\n readonly summary: string;\n readonly run: DoctorCommandImplementation;\n}\n\nexport interface DoctorCommandInvocation {\n readonly argv: readonly string[];\n readonly command: DoctorCommandDefinition;\n readonly context: DoctorCommandContext;\n}\n\nexport interface DoctorCommandServices {\n readonly analyzeTarget: typeof analyzeDoctorTarget;\n}\n\nexport interface RunDoctorCommandOptions {\n readonly runCommandImpl?: RunDoctorCommandImpl;\n readonly services?: Partial<DoctorCommandServices>;\n}\n\nexport type RunDoctorCommandImpl = (\n request: DoctorCommandInvocation,\n options?: RunDoctorCommandOptions,\n) => Promise<DoctorCommandRunResult>;\n\nconst COMMAND_CAPABILITIES = {\n validate: DOCTOR_CAPABILITIES[0],\n fix: DOCTOR_CAPABILITIES[1],\n repo: DOCTOR_CAPABILITIES[2],\n package: DOCTOR_CAPABILITIES[3],\n} as const satisfies Record<DoctorCommandName, AnkhCapabilityId>;\n\nexport const DOCTOR_COMMANDS = [\n {\n standaloneName: \"validate\",\n path: [\"validate\"],\n capability: COMMAND_CAPABILITIES.validate,\n mode: \"validate\",\n summary: \"Auto-detect lightweight repo and package diagnostics for a local path.\",\n run: runValidateCommand,\n },\n {\n standaloneName: \"fix\",\n path: [\"fix\"],\n capability: COMMAND_CAPABILITIES.fix,\n mode: \"fix\",\n summary: \"Run the same lightweight checks and report that no automatic fixes exist yet.\",\n run: runFixCommand,\n },\n {\n standaloneName: \"repo\",\n path: [\"repo\"],\n capability: COMMAND_CAPABILITIES.repo,\n mode: \"repo\",\n summary: \"Force repo-light diagnostics for a repo/workspace-root candidate path.\",\n run: runRepoCommand,\n },\n {\n standaloneName: \"package\",\n path: [\"package\"],\n capability: COMMAND_CAPABILITIES.package,\n mode: \"package\",\n summary: \"Force package-light diagnostics for a directory containing package.json.\",\n run: runPackageCommand,\n },\n] as const satisfies readonly DoctorCommandDefinition[];\n\nexport async function runDoctorCommand(\n request: DoctorCommandInvocation,\n options: RunDoctorCommandOptions = {},\n): Promise<DoctorCommandRunResult> {\n const services = createDoctorCommandServices(options.services);\n\n try {\n const parsedArgs = parseCommandArguments(request.command, request.argv);\n if (parsedArgs.kind === \"help\") {\n request.context.writeStdout(renderCommandHelp(request.command));\n return { exitCode: 0 };\n }\n\n return await request.command.run(\n {\n context: request.context,\n inputPath: parsedArgs.inputPath,\n },\n services,\n );\n } catch (error) {\n request.context.writeStderr(\n renderCommandFailure(request.command.standaloneName, error),\n );\n return { exitCode: 1 };\n }\n}\n\nexport function createProviderCommandDescriptors(): readonly AnkhCommandDescriptor[] {\n return DOCTOR_COMMANDS.map((command) => ({\n capability: command.capability,\n path: command.path,\n summary: command.summary,\n }));\n}\n\nexport function findDoctorCommandByStandaloneName(\n value: string,\n): DoctorCommandDefinition | null {\n return DOCTOR_COMMANDS.find((command) => command.standaloneName === value) ?? null;\n}\n\nexport function renderRootHelp(version: string): string {\n const commandLines = DOCTOR_COMMANDS.map(\n (command) => ` ${command.standaloneName.padEnd(8, \" \")} ${command.summary}`,\n ).join(\"\\n\");\n\n return [\n `@ankhorage/doctor v${version}`,\n \"\",\n \"Usage:\",\n \" ankhorage-doctor <command> [path]\",\n ` ankh ${DOCTOR_COMMAND_CATEGORY} <command> [path]`,\n \"\",\n \"Commands:\",\n commandLines,\n \"\",\n \"Path resolution:\",\n \" Pass [path], or omit it to validate the current working directory.\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport function renderUnknownCommand(value: string): string {\n return [\n `Unknown doctor command: ${value}`,\n \"\",\n \"Run ankhorage-doctor --help\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction renderCommandHelp(command: DoctorCommandDefinition): string {\n return [\n command.summary,\n \"\",\n \"Usage:\",\n ` ankhorage-doctor ${command.standaloneName} [path]`,\n ` ankh ${DOCTOR_COMMAND_CATEGORY} ${command.path.join(\" \")} [path]`,\n \"\",\n \"Path resolution:\",\n \" Pass [path], or omit it to validate the current working directory.\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction createDoctorCommandServices(\n overrides: Partial<DoctorCommandServices> = {},\n): DoctorCommandServices {\n return {\n analyzeTarget: overrides.analyzeTarget ?? analyzeDoctorTarget,\n };\n}\n\nfunction parseCommandArguments(\n command: DoctorCommandDefinition,\n argv: readonly string[],\n): { readonly kind: \"help\" } | { readonly kind: \"run\"; readonly inputPath?: string } {\n const firstArg = argv[0];\n\n if (argv.length === 1 && firstArg !== undefined && isHelpToken(firstArg)) {\n return { kind: \"help\" };\n }\n\n if (argv.length > 1) {\n throw new Error(`Doctor ${command.standaloneName} accepts at most one path argument.`);\n }\n\n return {\n kind: \"run\",\n inputPath: firstArg,\n };\n}\n\nasync function runValidateCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: \"validate\",\n });\n\n request.context.writeStdout(renderAnalysisReport(\"validate\", result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nasync function runFixCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: \"fix\",\n });\n\n request.context.writeStdout(renderAnalysisReport(\"fix\", result));\n request.context.writeStdout(\"No automatic fixes available.\\n\");\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nasync function runRepoCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: \"repo\",\n });\n\n request.context.writeStdout(renderAnalysisReport(\"repo\", result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nasync function runPackageCommand(\n request: DoctorCommandRunRequest,\n services: DoctorCommandServices,\n): Promise<DoctorCommandRunResult> {\n const result = await services.analyzeTarget({\n cwd: request.context.cwd,\n inputPath: request.inputPath,\n mode: \"package\",\n });\n\n request.context.writeStdout(renderAnalysisReport(\"package\", result));\n\n return {\n exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,\n };\n}\n\nfunction renderAnalysisReport(\n commandName: DoctorCommandName,\n result: DoctorAnalysisResult,\n): string {\n const lines = [\n `doctor ${commandName}`,\n `target: ${result.targetPath}`,\n `checks: ${result.appliedChecks.length > 0 ? result.appliedChecks.join(\", \") : \"none\"}`,\n `repoMarkers: ${result.repoMarkers.length > 0 ? result.repoMarkers.join(\", \") : \"none\"}`,\n \"\",\n \"Diagnostics:\",\n ];\n\n if (result.diagnostics.length === 0) {\n lines.push(\" none\");\n } else {\n for (const diagnostic of result.diagnostics) {\n lines.push(renderDiagnosticLine(diagnostic));\n }\n }\n\n const errorCount = countErrorDiagnostics(result.diagnostics);\n const warningCount = countWarningDiagnostics(result.diagnostics);\n\n lines.push(\"\");\n lines.push(`Summary: ${errorCount} error(s), ${warningCount} warning(s)`);\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n\nfunction renderDiagnosticLine(diagnostic: DoctorDiagnostic): string {\n return ` - ${diagnostic.severity.toUpperCase()} ${diagnostic.code}: ${diagnostic.message}`;\n}\n\nfunction renderCommandFailure(commandName: DoctorCommandName, error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n return [`Failed to run doctor ${commandName}: ${message}`, \"\"].join(\"\\n\");\n}\n\nfunction isHelpToken(value: string): boolean {\n return value === \"--help\" || value === \"-h\" || value === \"help\";\n}\n"]}
@@ -0,0 +1,11 @@
1
+ export type DoctorDiagnosticCode = "invalid-ankh-metadata" | "invalid-package-json" | "missing-changelog" | "missing-changeset-directory" | "missing-license" | "missing-readme" | "missing-workflows-directory" | "package-json-missing" | "package-name-missing" | "package-type-missing" | "package-version-missing" | "repo-markers-missing" | "target-not-directory" | "target-not-found" | "unsupported-target";
2
+ export type DoctorDiagnosticSeverity = "error" | "warning";
3
+ export interface DoctorDiagnostic {
4
+ readonly code: DoctorDiagnosticCode;
5
+ readonly message: string;
6
+ readonly path: string;
7
+ readonly severity: DoctorDiagnosticSeverity;
8
+ }
9
+ export declare function countErrorDiagnostics(diagnostics: readonly DoctorDiagnostic[]): number;
10
+ export declare function countWarningDiagnostics(diagnostics: readonly DoctorDiagnostic[]): number;
11
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,uBAAuB,GACvB,sBAAsB,GACtB,mBAAmB,GACnB,6BAA6B,GAC7B,iBAAiB,GACjB,gBAAgB,GAChB,6BAA6B,GAC7B,sBAAsB,GACtB,sBAAsB,GACtB,sBAAsB,GACtB,yBAAyB,GACzB,sBAAsB,GACtB,sBAAsB,GACtB,kBAAkB,GAClB,oBAAoB,CAAC;AAEzB,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GACvC,MAAM,CAGR;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GACvC,MAAM,CAGR"}
@@ -0,0 +1,9 @@
1
+ export function countErrorDiagnostics(diagnostics) {
2
+ return diagnostics.filter((diagnostic) => diagnostic.severity === "error")
3
+ .length;
4
+ }
5
+ export function countWarningDiagnostics(diagnostics) {
6
+ return diagnostics.filter((diagnostic) => diagnostic.severity === "warning")
7
+ .length;
8
+ }
9
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AA0BA,MAAM,UAAU,qBAAqB,CACnC,WAAwC;IAExC,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,OAAO,CAAC;SACvE,MAAM,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,WAAwC;IAExC,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,SAAS,CAAC;SACzE,MAAM,CAAC;AACZ,CAAC","sourcesContent":["export type DoctorDiagnosticCode =\n | \"invalid-ankh-metadata\"\n | \"invalid-package-json\"\n | \"missing-changelog\"\n | \"missing-changeset-directory\"\n | \"missing-license\"\n | \"missing-readme\"\n | \"missing-workflows-directory\"\n | \"package-json-missing\"\n | \"package-name-missing\"\n | \"package-type-missing\"\n | \"package-version-missing\"\n | \"repo-markers-missing\"\n | \"target-not-directory\"\n | \"target-not-found\"\n | \"unsupported-target\";\n\nexport type DoctorDiagnosticSeverity = \"error\" | \"warning\";\n\nexport interface DoctorDiagnostic {\n readonly code: DoctorDiagnosticCode;\n readonly message: string;\n readonly path: string;\n readonly severity: DoctorDiagnosticSeverity;\n}\n\nexport function countErrorDiagnostics(\n diagnostics: readonly DoctorDiagnostic[],\n): number {\n return diagnostics.filter((diagnostic) => diagnostic.severity === \"error\")\n .length;\n}\n\nexport function countWarningDiagnostics(\n diagnostics: readonly DoctorDiagnostic[],\n): number {\n return diagnostics.filter((diagnostic) => diagnostic.severity === \"warning\")\n .length;\n}\n"]}
@@ -0,0 +1,9 @@
1
+ export { runCli } from "./cli.js";
2
+ export type { DoctorCommandContext, DoctorCommandRunResult } from "./commandContext.js";
3
+ export { createDefaultCommandContext } from "./commandContext.js";
4
+ export type { DoctorAnalysisRequest, DoctorAnalysisResult, DoctorTargetCheck, DoctorTargetMode, } from "./analysis.js";
5
+ export { analyzeDoctorTarget } from "./analysis.js";
6
+ export { createDoctorRuntimeProvider, type CreateDoctorRuntimeProviderOptions, } from "./ankh.provider.js";
7
+ export type { DoctorDiagnostic, DoctorDiagnosticCode, DoctorDiagnosticSeverity, } from "./diagnostics.js";
8
+ export { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY, DOCTOR_PACKAGE_METADATA, DOCTOR_PACKAGE_NAME, DOCTOR_PACKAGE_VERSION, } from "./packageMetadata.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,2BAA2B,EAC3B,KAAK,kCAAkC,GACxC,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { runCli } from "./cli.js";
2
+ export { createDefaultCommandContext } from "./commandContext.js";
3
+ export { analyzeDoctorTarget } from "./analysis.js";
4
+ export { createDoctorRuntimeProvider, } from "./ankh.provider.js";
5
+ export { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY, DOCTOR_PACKAGE_METADATA, DOCTOR_PACKAGE_NAME, DOCTOR_PACKAGE_VERSION, } from "./packageMetadata.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAOlE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,2BAA2B,GAE5B,MAAM,oBAAoB,CAAC;AAM5B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC","sourcesContent":["export { runCli } from \"./cli.js\";\nexport type { DoctorCommandContext, DoctorCommandRunResult } from \"./commandContext.js\";\nexport { createDefaultCommandContext } from \"./commandContext.js\";\nexport type {\n DoctorAnalysisRequest,\n DoctorAnalysisResult,\n DoctorTargetCheck,\n DoctorTargetMode,\n} from \"./analysis.js\";\nexport { analyzeDoctorTarget } from \"./analysis.js\";\nexport {\n createDoctorRuntimeProvider,\n type CreateDoctorRuntimeProviderOptions,\n} from \"./ankh.provider.js\";\nexport type {\n DoctorDiagnostic,\n DoctorDiagnosticCode,\n DoctorDiagnosticSeverity,\n} from \"./diagnostics.js\";\nexport {\n DOCTOR_CAPABILITIES,\n DOCTOR_COMMAND_CATEGORY,\n DOCTOR_PACKAGE_METADATA,\n DOCTOR_PACKAGE_NAME,\n DOCTOR_PACKAGE_VERSION,\n} from \"./packageMetadata.js\";\n"]}
@@ -0,0 +1,10 @@
1
+ export declare const DOCTOR_PACKAGE_NAME: string;
2
+ export declare const DOCTOR_PACKAGE_VERSION: string;
3
+ export declare const DOCTOR_COMMAND_CATEGORY: "doctor";
4
+ export declare const DOCTOR_CAPABILITIES: readonly ["doctor.validate", "doctor.fix", "doctor.repo", "doctor.package"];
5
+ export declare const DOCTOR_PACKAGE_METADATA: {
6
+ readonly category: "doctor";
7
+ readonly provider: "./dist/ankh.provider.js";
8
+ readonly capabilities: readonly ["doctor.validate", "doctor.fix", "doctor.repo", "doctor.package"];
9
+ };
10
+ //# sourceMappingURL=packageMetadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageMetadata.d.ts","sourceRoot":"","sources":["../src/packageMetadata.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,mBAAmB,QAAmB,CAAC;AACpD,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAC1D,eAAO,MAAM,uBAAuB,UACa,CAAC;AAClD,eAAO,MAAM,mBAAmB,6EAKgB,CAAC;AAEjD,eAAO,MAAM,uBAAuB;;;;CAII,CAAC"}
@@ -0,0 +1,16 @@
1
+ import packageJson from "../package.json";
2
+ export const DOCTOR_PACKAGE_NAME = packageJson.name;
3
+ export const DOCTOR_PACKAGE_VERSION = packageJson.version;
4
+ export const DOCTOR_COMMAND_CATEGORY = "doctor";
5
+ export const DOCTOR_CAPABILITIES = [
6
+ "doctor.validate",
7
+ "doctor.fix",
8
+ "doctor.repo",
9
+ "doctor.package",
10
+ ];
11
+ export const DOCTOR_PACKAGE_METADATA = {
12
+ category: DOCTOR_COMMAND_CATEGORY,
13
+ provider: "./dist/ankh.provider.js",
14
+ capabilities: DOCTOR_CAPABILITIES,
15
+ };
16
+ //# sourceMappingURL=packageMetadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageMetadata.js","sourceRoot":"","sources":["../src/packageMetadata.ts"],"names":[],"mappings":"AAMA,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAE1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC,IAAI,CAAC;AACpD,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAC,OAAO,CAAC;AAC1D,MAAM,CAAC,MAAM,uBAAuB,GAClC,QAA+C,CAAC;AAClD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,iBAAiB;IACjB,YAAY;IACZ,aAAa;IACb,gBAAgB;CAC8B,CAAC;AAEjD,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,yBAAyB;IACnC,YAAY,EAAE,mBAAmB;CACK,CAAC","sourcesContent":["import type {\n AnkhCapabilityId,\n AnkhCommandCategory,\n AnkhPackageMetadata,\n} from \"@ankhorage/contracts/cli\";\n\nimport packageJson from \"../package.json\";\n\nexport const DOCTOR_PACKAGE_NAME = packageJson.name;\nexport const DOCTOR_PACKAGE_VERSION = packageJson.version;\nexport const DOCTOR_COMMAND_CATEGORY =\n \"doctor\" as const satisfies AnkhCommandCategory;\nexport const DOCTOR_CAPABILITIES = [\n \"doctor.validate\",\n \"doctor.fix\",\n \"doctor.repo\",\n \"doctor.package\",\n] as const satisfies readonly AnkhCapabilityId[];\n\nexport const DOCTOR_PACKAGE_METADATA = {\n category: DOCTOR_COMMAND_CATEGORY,\n provider: \"./dist/ankh.provider.js\",\n capabilities: DOCTOR_CAPABILITIES,\n} as const satisfies AnkhPackageMetadata;\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=readme-usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readme-usage.d.ts","sourceRoot":"","sources":["../src/readme-usage.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ import { runCli } from "./cli.js";
2
+ /***
3
+ * Provider and CLI surface
4
+ *
5
+ * `@ankhorage/doctor` is the repo/package compliance provider for Ankhorage.
6
+ *
7
+ * The same shared command implementation backs both:
8
+ *
9
+ * - `ankh doctor ...`
10
+ * - `bunx @ankhorage/doctor ...`
11
+ *
12
+ * Current command surface:
13
+ *
14
+ * - `validate`
15
+ * - `fix`
16
+ * - `repo`
17
+ * - `package`
18
+ *
19
+ * `doctor#1` intentionally stays lightweight:
20
+ *
21
+ * - path-aware local repo/package diagnostics are implemented now
22
+ * - GitHub checks, CI checks, full policy enforcement, and autofix rules are deferred
23
+ *
24
+ * Path handling:
25
+ *
26
+ * - pass `[path]`, or
27
+ * - omit it to inspect the current working directory
28
+ *
29
+ * @usage
30
+ */
31
+ await runCli(["--help"]);
32
+ //# sourceMappingURL=readme-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readme-usage.js","sourceRoot":"","sources":["../src/readme-usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC","sourcesContent":["import { runCli } from \"./cli.js\";\n\n/***\n * Provider and CLI surface\n *\n * `@ankhorage/doctor` is the repo/package compliance provider for Ankhorage.\n *\n * The same shared command implementation backs both:\n *\n * - `ankh doctor ...`\n * - `bunx @ankhorage/doctor ...`\n *\n * Current command surface:\n *\n * - `validate`\n * - `fix`\n * - `repo`\n * - `package`\n *\n * `doctor#1` intentionally stays lightweight:\n *\n * - path-aware local repo/package diagnostics are implemented now\n * - GitHub checks, CI checks, full policy enforcement, and autofix rules are deferred\n *\n * Path handling:\n *\n * - pass `[path]`, or\n * - omit it to inspect the current working directory\n *\n * @usage\n */\nawait runCli([\"--help\"]);\n"]}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@ankhorage/doctor",
3
+ "version": "0.2.0",
4
+ "description": "Executable Ankh provider and standalone CLI for lightweight repo and package compliance diagnostics.",
5
+ "license": "MIT",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "homepage": "https://github.com/ankhorage/doctor#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/ankhorage/doctor/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/ankhorage/doctor.git"
16
+ },
17
+ "keywords": [
18
+ "ankhorage",
19
+ "doctor",
20
+ "cli",
21
+ "compliance",
22
+ "typescript",
23
+ "bun"
24
+ ],
25
+ "type": "module",
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "./package.json": "./package.json"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "src",
39
+ "package.json",
40
+ "README.md",
41
+ "CHANGELOG.md",
42
+ "LICENSE"
43
+ ],
44
+ "bin": {
45
+ "ankhorage-doctor": "./dist/cli.js"
46
+ },
47
+ "ankh": {
48
+ "category": "doctor",
49
+ "provider": "./dist/ankh.provider.js",
50
+ "capabilities": [
51
+ "doctor.validate",
52
+ "doctor.fix",
53
+ "doctor.repo",
54
+ "doctor.package"
55
+ ]
56
+ },
57
+ "scripts": {
58
+ "build": "rm -rf dist tsconfig.tsbuildinfo tsconfig.build.tsbuildinfo && bun x tsc -p tsconfig.build.json",
59
+ "typecheck": "bun x tsc --noEmit -p tsconfig.json",
60
+ "lint": "ankhorage-eslint . --max-warnings=0",
61
+ "lint:fix": "ankhorage-eslint . --fix --max-warnings=0",
62
+ "format": "ankhorage-prettier --write .",
63
+ "format:check": "ankhorage-prettier --check .",
64
+ "test": "bun test",
65
+ "knip": "ankhorage-knip",
66
+ "docs": "bunx @ankhorage/paradox && ankhorage-prettier --write README.md paradox",
67
+ "changeset": "changeset",
68
+ "changeset:status": "changeset status --since=origin/main",
69
+ "version-packages": "changeset version"
70
+ },
71
+ "dependencies": {
72
+ "@ankhorage/contracts": "^1.19.0"
73
+ },
74
+ "devDependencies": {
75
+ "@ankhorage/ankh": "^0.4.0",
76
+ "@ankhorage/devtools": "^1.0.6",
77
+ "@ankhorage/paradox": "^0.1.10",
78
+ "@changesets/cli": "^2.31.0",
79
+ "@types/bun": "^1.3.13",
80
+ "@types/node": "^25.6.0",
81
+ "typescript": "^5.9.3"
82
+ },
83
+ "sideEffects": false,
84
+ "packageManager": "bun@1.3.13"
85
+ }