@ankhorage/doctor 0.2.1 → 0.3.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.
- package/CHANGELOG.md +6 -0
- package/README.md +12 -4
- package/dist/analysis.d.ts +18 -1
- package/dist/analysis.d.ts.map +1 -1
- package/dist/analysis.js +786 -57
- package/dist/analysis.js.map +1 -1
- package/dist/commands.d.ts +2 -2
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +19 -4
- package/dist/commands.js.map +1 -1
- package/dist/diagnostics.d.ts +5 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/readme-usage.js +11 -3
- package/dist/readme-usage.js.map +1 -1
- package/package.json +1 -1
- package/src/analysis.ts +1082 -145
- package/src/commands.ts +22 -5
- package/src/diagnostics.ts +67 -10
- package/src/index.ts +5 -0
- package/src/readme-usage.ts +11 -3
package/dist/analysis.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport type { DoctorDiagnostic } from './diagnostics.js';\n\nexport type DoctorTargetCheck = 'package' | 'repo';\nexport type DoctorTargetMode = 'fix' | 'package' | 'repo' | 'validate';\n\nexport interface DoctorAnalysisRequest {\n readonly cwd: string;\n readonly inputPath?: string;\n readonly mode: DoctorTargetMode;\n}\n\nexport interface DoctorAnalysisResult {\n readonly appliedChecks: readonly DoctorTargetCheck[];\n readonly diagnostics: readonly DoctorDiagnostic[];\n readonly hasPackageJson: boolean;\n readonly repoMarkers: readonly string[];\n readonly targetPath: string;\n}\n\nconst REPO_MARKERS = [\n { label: '.git', relativePath: '.git' },\n { label: '.github/workflows', relativePath: path.join('.github', 'workflows') },\n { label: '.changeset', relativePath: '.changeset' },\n { label: 'package.json', relativePath: 'package.json' },\n { label: 'pnpm-workspace.yaml', relativePath: 'pnpm-workspace.yaml' },\n { label: 'bun.lock', relativePath: 'bun.lock' },\n { label: 'bun.lockb', relativePath: 'bun.lockb' },\n { label: 'package-lock.json', relativePath: 'package-lock.json' },\n { label: 'yarn.lock', relativePath: 'yarn.lock' },\n] as const;\n\nexport async function analyzeDoctorTarget(\n request: DoctorAnalysisRequest,\n): Promise<DoctorAnalysisResult> {\n const targetPath = path.resolve(request.cwd, request.inputPath ?? '.');\n const stats = await statOrNull(targetPath);\n\n if (stats === null) {\n return {\n appliedChecks: [],\n diagnostics: [\n createDiagnostic(\n 'error',\n 'target-not-found',\n targetPath,\n `Target path does not exist: ${targetPath}`,\n ),\n ],\n hasPackageJson: false,\n repoMarkers: [],\n targetPath,\n };\n }\n\n if (!stats.isDirectory()) {\n return {\n appliedChecks: [],\n diagnostics: [\n createDiagnostic(\n 'error',\n 'target-not-directory',\n targetPath,\n `Target path must be a directory: ${targetPath}`,\n ),\n ],\n hasPackageJson: false,\n repoMarkers: [],\n targetPath,\n };\n }\n\n const repoMarkers = (\n await Promise.all(\n REPO_MARKERS.map(async (marker) =>\n (await pathExists(path.join(targetPath, marker.relativePath))) ? marker.label : null,\n ),\n )\n ).filter((marker): marker is (typeof REPO_MARKERS)[number]['label'] => marker !== null);\n\n const packageJsonPath = path.join(targetPath, 'package.json');\n const hasPackageJson = repoMarkers.includes('package.json');\n const appliedChecks: DoctorTargetCheck[] = [];\n const diagnostics: DoctorDiagnostic[] = [];\n\n const shouldRunRepoChecks =\n request.mode === 'repo' ||\n ((request.mode === 'validate' || request.mode === 'fix') && repoMarkers.length > 0);\n const shouldRunPackageChecks =\n request.mode === 'package' ||\n ((request.mode === 'validate' || request.mode === 'fix') && hasPackageJson);\n\n if (request.mode === 'repo' && repoMarkers.length === 0) {\n diagnostics.push(\n createDiagnostic(\n 'error',\n 'repo-markers-missing',\n targetPath,\n 'Target is not a repo/workspace-root candidate because no repo markers were found.',\n ),\n );\n }\n\n if (request.mode === 'package' && !hasPackageJson) {\n diagnostics.push(\n createDiagnostic(\n 'error',\n 'package-json-missing',\n packageJsonPath,\n 'Target does not contain a readable package.json file.',\n ),\n );\n }\n\n if (\n (request.mode === 'validate' || request.mode === 'fix') &&\n repoMarkers.length === 0 &&\n !hasPackageJson\n ) {\n diagnostics.push(\n createDiagnostic(\n 'error',\n 'unsupported-target',\n targetPath,\n 'Target is neither a repo/workspace-root candidate nor a package root.',\n ),\n );\n }\n\n if (shouldRunRepoChecks && repoMarkers.length > 0) {\n appliedChecks.push('repo');\n diagnostics.push(...(await analyzeRepoLight(targetPath)));\n }\n\n if (shouldRunPackageChecks && hasPackageJson) {\n appliedChecks.push('package');\n diagnostics.push(...(await analyzePackageLight(targetPath, packageJsonPath)));\n }\n\n return {\n appliedChecks,\n diagnostics,\n hasPackageJson,\n repoMarkers,\n targetPath,\n };\n}\n\nasync function analyzeRepoLight(targetPath: string): Promise<DoctorDiagnostic[]> {\n const diagnostics: DoctorDiagnostic[] = [];\n\n await maybeWarnForMissingPath(diagnostics, targetPath, 'README.md', 'missing-readme');\n await maybeWarnForMissingPath(diagnostics, targetPath, 'CHANGELOG.md', 'missing-changelog');\n await maybeWarnForMissingPath(diagnostics, targetPath, 'LICENSE', 'missing-license');\n await maybeWarnForMissingPath(\n diagnostics,\n targetPath,\n '.changeset',\n 'missing-changeset-directory',\n );\n await maybeWarnForMissingPath(\n diagnostics,\n targetPath,\n path.join('.github', 'workflows'),\n 'missing-workflows-directory',\n );\n\n return diagnostics;\n}\n\nasync function analyzePackageLight(\n targetPath: string,\n packageJsonPath: string,\n): Promise<DoctorDiagnostic[]> {\n const diagnostics: DoctorDiagnostic[] = [];\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(await fs.readFile(packageJsonPath, 'utf8')) as unknown;\n } catch (error) {\n diagnostics.push(\n createDiagnostic(\n 'error',\n 'invalid-package-json',\n packageJsonPath,\n createInvalidPackageJsonMessage(error),\n ),\n );\n return diagnostics;\n }\n\n if (!isRecord(parsed)) {\n diagnostics.push(\n createDiagnostic(\n 'error',\n 'invalid-package-json',\n packageJsonPath,\n 'package.json must contain a JSON object.',\n ),\n );\n return diagnostics;\n }\n\n if (!isNonEmptyString(parsed.name)) {\n diagnostics.push(\n createDiagnostic(\n 'error',\n 'package-name-missing',\n packageJsonPath,\n 'package.json must define a non-empty \"name\" field.',\n ),\n );\n }\n\n if (!isNonEmptyString(parsed.version)) {\n diagnostics.push(\n createDiagnostic(\n 'error',\n 'package-version-missing',\n packageJsonPath,\n 'package.json must define a non-empty \"version\" field.',\n ),\n );\n }\n\n if (!isNonEmptyString(parsed.type)) {\n diagnostics.push(\n createDiagnostic(\n 'error',\n 'package-type-missing',\n packageJsonPath,\n 'package.json must define a non-empty \"type\" field.',\n ),\n );\n }\n\n if ('ankh' in parsed) {\n const validationError = validateAnkhMetadataShape(parsed.ankh);\n if (validationError !== null) {\n diagnostics.push(\n createDiagnostic('error', 'invalid-ankh-metadata', targetPath, validationError),\n );\n }\n }\n\n return diagnostics;\n}\n\nasync function maybeWarnForMissingPath(\n diagnostics: DoctorDiagnostic[],\n rootPath: string,\n relativePath: string,\n code:\n | 'missing-changelog'\n | 'missing-changeset-directory'\n | 'missing-license'\n | 'missing-readme'\n | 'missing-workflows-directory',\n): Promise<void> {\n const absolutePath = path.join(rootPath, relativePath);\n if (await pathExists(absolutePath)) {\n return;\n }\n\n diagnostics.push(\n createDiagnostic(\n 'warning',\n code,\n absolutePath,\n `Missing expected repo artifact: ${relativePath}`,\n ),\n );\n}\n\nfunction validateAnkhMetadataShape(value: unknown): string | null {\n if (!isRecord(value)) {\n return 'package.json \"ankh\" metadata must be an object when present.';\n }\n\n if (!isNonEmptyString(value.category)) {\n return 'package.json \"ankh.category\" must be a non-empty string.';\n }\n\n if (!(value.provider === null || isPackageRelativeProviderPath(value.provider))) {\n return 'package.json \"ankh.provider\" must be null or a package-relative \"./...\" string.';\n }\n\n if (\n !Array.isArray(value.capabilities) ||\n value.capabilities.some((capability) => !isNonEmptyString(capability))\n ) {\n return 'package.json \"ankh.capabilities\" must be an array of non-empty strings.';\n }\n\n return null;\n}\n\nfunction createDiagnostic(\n severity: DoctorDiagnostic['severity'],\n code: DoctorDiagnostic['code'],\n diagnosticPath: string,\n message: string,\n): DoctorDiagnostic {\n return {\n code,\n message,\n path: diagnosticPath,\n severity,\n };\n}\n\nfunction createInvalidPackageJsonMessage(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n return `package.json contains invalid JSON: ${message}`;\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n return (await statOrNull(targetPath)) !== null;\n}\n\nasync function statOrNull(targetPath: string) {\n try {\n return await fs.stat(targetPath);\n } catch (error) {\n if (isMissingPathError(error)) {\n return null;\n }\n\n throw error;\n }\n}\n\nfunction isMissingPathError(error: unknown): error is NodeJS.ErrnoException {\n return (\n error instanceof Error &&\n 'code' in error &&\n typeof error.code === 'string' &&\n error.code === 'ENOENT'\n );\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim() !== '';\n}\n\nfunction isPackageRelativeProviderPath(value: unknown): value is string {\n return isNonEmptyString(value) && value.startsWith('./');\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport type { DoctorDiagnostic, DoctorPolicyProfile, DoctorRuleId } from './diagnostics.js';\n\nexport type DoctorTargetCheck = 'package' | 'repo';\nexport type DoctorTargetMode = 'fix' | 'package' | 'repo' | 'validate';\nexport type DoctorPlannedChangeKind =\n 'create-directory' | 'create-file' | 'update-json' | 'update-text';\n\nexport interface DoctorAnalysisRequest {\n readonly cwd: string;\n readonly inputPath?: string;\n readonly mode: DoctorTargetMode;\n}\n\nexport interface DoctorPlannedChange {\n readonly description: string;\n readonly filePath: string;\n readonly kind: DoctorPlannedChangeKind;\n readonly ruleId: DoctorRuleId;\n readonly safe: boolean;\n}\n\nexport interface DoctorFixPlan {\n readonly changes: readonly DoctorPlannedChange[];\n readonly diagnostics: readonly DoctorDiagnostic[];\n readonly profile: DoctorPolicyProfile;\n readonly targetPath: string;\n}\n\nexport interface DoctorAnalysisResult {\n readonly appliedChecks: readonly DoctorTargetCheck[];\n readonly diagnostics: readonly DoctorDiagnostic[];\n readonly fixPlan: DoctorFixPlan | null;\n readonly hasPackageJson: boolean;\n readonly plannedChanges: readonly DoctorPlannedChange[];\n readonly profile: DoctorPolicyProfile;\n readonly repoMarkers: readonly string[];\n readonly targetPath: string;\n}\n\ninterface ProviderInspectionResult {\n readonly capabilities: readonly string[];\n readonly commandCapabilities: readonly string[];\n readonly commandPaths: readonly string[];\n readonly handlerPaths: readonly string[];\n readonly sourcePath: string;\n}\n\nconst REPO_MARKERS = [\n { label: '.git', relativePath: '.git' },\n { label: '.github/workflows', relativePath: path.join('.github', 'workflows') },\n { label: '.changeset', relativePath: '.changeset' },\n { label: 'package.json', relativePath: 'package.json' },\n { label: 'pnpm-workspace.yaml', relativePath: 'pnpm-workspace.yaml' },\n { label: 'bun.lock', relativePath: 'bun.lock' },\n { label: 'bun.lockb', relativePath: 'bun.lockb' },\n { label: 'package-lock.json', relativePath: 'package-lock.json' },\n { label: 'yarn.lock', relativePath: 'yarn.lock' },\n] as const;\n\nconst REQUIRED_PUBLIC_PACKAGE_SCRIPTS = [\n 'build',\n 'typecheck',\n 'lint',\n 'lint:fix',\n 'format',\n 'format:check',\n 'test',\n 'knip',\n 'docs',\n 'changeset',\n 'changeset:status',\n 'version-packages',\n] as const;\n\nconst PROVIDER_SOURCE_CANDIDATES = [\n path.join('src', 'ankh.provider.ts'),\n path.join('src', 'ankh.provider.tsx'),\n path.join('src', 'ankh.provider.js'),\n path.join('src', 'ankh.provider.mjs'),\n] as const;\n\nexport async function analyzeDoctorTarget(\n request: DoctorAnalysisRequest,\n): Promise<DoctorAnalysisResult> {\n const targetPath = path.resolve(request.cwd, request.inputPath ?? '.');\n const stats = await statOrNull(targetPath);\n\n if (stats === null) {\n return createEarlyResult(\n targetPath,\n createDiagnostic({\n code: 'target-not-found',\n message: `Target path does not exist: ${targetPath}`,\n path: targetPath,\n profile: 'unknown',\n ruleId: 'target.path.exists',\n severity: 'error',\n }),\n );\n }\n\n if (!stats.isDirectory()) {\n return createEarlyResult(\n targetPath,\n createDiagnostic({\n code: 'target-not-directory',\n message: `Target path must be a directory: ${targetPath}`,\n path: targetPath,\n profile: 'unknown',\n ruleId: 'target.path.directory',\n severity: 'error',\n }),\n );\n }\n\n const repoMarkers = await findRepoMarkers(targetPath);\n const packageJsonPath = path.join(targetPath, 'package.json');\n const hasPackageJson = repoMarkers.includes('package.json');\n const appliedChecks: DoctorTargetCheck[] = [];\n const diagnostics: DoctorDiagnostic[] = [];\n const plannedChanges: DoctorPlannedChange[] = [];\n\n const packageJson = hasPackageJson ? await readPackageJson(packageJsonPath) : null;\n if (packageJson !== null && packageJson.diagnostic !== null) {\n diagnostics.push(packageJson.diagnostic);\n }\n\n const profile = detectProfile(repoMarkers, packageJson?.parsed ?? null);\n\n const shouldRunRepoChecks =\n request.mode === 'repo' ||\n ((request.mode === 'validate' || request.mode === 'fix') && repoMarkers.length > 0);\n const shouldRunPackageChecks =\n request.mode === 'package' ||\n ((request.mode === 'validate' || request.mode === 'fix') && hasPackageJson);\n\n if (request.mode === 'repo' && repoMarkers.length === 0) {\n diagnostics.push(\n createDiagnostic({\n code: 'unsupported-target',\n message:\n 'Target is not a repo/workspace-root candidate because no repo markers were found.',\n path: targetPath,\n profile,\n ruleId: 'target.repo-markers.required',\n severity: 'error',\n }),\n );\n }\n\n if (request.mode === 'package' && !hasPackageJson) {\n diagnostics.push(\n createDiagnostic({\n code: 'unsupported-target',\n message: 'Target does not contain a readable package.json file.',\n path: packageJsonPath,\n profile,\n ruleId: 'target.package-json.required',\n severity: 'error',\n }),\n );\n }\n\n if (\n (request.mode === 'validate' || request.mode === 'fix') &&\n repoMarkers.length === 0 &&\n !hasPackageJson\n ) {\n diagnostics.push(\n createDiagnostic({\n code: 'unsupported-target',\n message: 'Target is neither a repo/workspace-root candidate nor a package root.',\n path: targetPath,\n profile,\n ruleId: 'target.profile.supported',\n severity: 'error',\n }),\n );\n }\n\n if (shouldRunRepoChecks && repoMarkers.length > 0) {\n appliedChecks.push('repo');\n diagnostics.push(\n ...(await analyzeRepoPolicy({\n packageJson: packageJson?.parsed ?? null,\n plannedChanges,\n profile,\n repoMarkers,\n targetPath,\n })),\n );\n }\n\n if (shouldRunPackageChecks && hasPackageJson) {\n appliedChecks.push('package');\n diagnostics.push(\n ...(await analyzePackagePolicy({\n packageJson: packageJson?.parsed ?? null,\n packageJsonPath,\n plannedChanges,\n profile,\n targetPath,\n })),\n );\n }\n\n const fixPlan =\n request.mode === 'fix'\n ? {\n changes: plannedChanges,\n diagnostics,\n profile,\n targetPath,\n }\n : null;\n\n return {\n appliedChecks,\n diagnostics,\n fixPlan,\n hasPackageJson,\n plannedChanges,\n profile,\n repoMarkers,\n targetPath,\n };\n}\n\nasync function analyzeRepoPolicy(request: {\n readonly packageJson: Record<string, unknown> | null;\n readonly plannedChanges: DoctorPlannedChange[];\n readonly profile: DoctorPolicyProfile;\n readonly repoMarkers: readonly string[];\n readonly targetPath: string;\n}): Promise<DoctorDiagnostic[]> {\n const diagnostics: DoctorDiagnostic[] = [];\n\n if (request.profile === 'public-package') {\n await maybeRequirePath(\n diagnostics,\n request.plannedChanges,\n request.targetPath,\n 'README.md',\n 'repo.readme.required',\n 'create-file',\n );\n await maybeRequirePath(\n diagnostics,\n request.plannedChanges,\n request.targetPath,\n 'CHANGELOG.md',\n 'repo.changelog.required',\n 'create-file',\n );\n await maybeRequirePath(\n diagnostics,\n request.plannedChanges,\n request.targetPath,\n 'LICENSE',\n 'repo.license.required',\n 'create-file',\n );\n await maybeRequirePath(\n diagnostics,\n request.plannedChanges,\n request.targetPath,\n '.changeset',\n 'repo.changeset.required',\n 'create-directory',\n );\n await maybeRequirePath(\n diagnostics,\n request.plannedChanges,\n request.targetPath,\n path.join('.github', 'workflows'),\n 'repo.workflows.required',\n 'create-directory',\n );\n }\n\n if (request.profile === 'integration-monorepo') {\n if (!request.repoMarkers.includes('package.json')) {\n diagnostics.push(\n createDiagnostic({\n code: 'missing-path',\n message: 'The integration monorepo root must include a package.json file.',\n path: path.join(request.targetPath, 'package.json'),\n profile: request.profile,\n ruleId: 'target.package-json.required',\n severity: 'error',\n }),\n );\n }\n\n if (request.packageJson !== null) {\n if (request.packageJson.ankh !== undefined) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-invalid',\n message:\n 'The integration monorepo root must not publish top-level package.json.ankh metadata.',\n path: path.join(request.targetPath, 'package.json'),\n profile: request.profile,\n ruleId: 'integration.package.ankh.disallowed',\n severity: 'error',\n }),\n );\n }\n\n if (request.packageJson.private !== true) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-invalid',\n message: 'The integration monorepo root must remain private.',\n path: path.join(request.targetPath, 'package.json'),\n profile: request.profile,\n ruleId: 'integration.package.private.required',\n severity: 'error',\n }),\n );\n }\n\n if (!Array.isArray(request.packageJson.workspaces)) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-missing',\n message: 'The integration monorepo root must declare workspaces.',\n path: path.join(request.targetPath, 'package.json'),\n profile: request.profile,\n ruleId: 'integration.package.workspaces.required',\n severity: 'error',\n }),\n );\n }\n }\n }\n\n return diagnostics;\n}\n\nasync function analyzePackagePolicy(request: {\n readonly packageJson: Record<string, unknown> | null;\n readonly packageJsonPath: string;\n readonly plannedChanges: DoctorPlannedChange[];\n readonly profile: DoctorPolicyProfile;\n readonly targetPath: string;\n}): Promise<DoctorDiagnostic[]> {\n if (request.packageJson === null) {\n return [];\n }\n\n const diagnostics: DoctorDiagnostic[] = [];\n const { packageJson } = request;\n\n if (request.profile === 'public-package') {\n requireNonEmptyStringField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.name.required',\n fieldName: 'name',\n });\n requireNonEmptyStringField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.version.required',\n fieldName: 'version',\n });\n requireNonEmptyStringField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.type.required',\n fieldName: 'type',\n });\n }\n\n if (request.profile !== 'public-package') {\n return diagnostics.concat(\n await validateAnkhMetadataAndProvider({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n plannedChanges: request.plannedChanges,\n profile: request.profile,\n targetPath: request.targetPath,\n }),\n );\n }\n\n requireNonEmptyStringField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.description.required',\n fieldName: 'description',\n });\n requireRecordField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.repository.required',\n fieldName: 'repository',\n });\n requireNonEmptyStringField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.homepage.required',\n fieldName: 'homepage',\n });\n requireRecordField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.bugs.required',\n fieldName: 'bugs',\n });\n requireNonEmptyStringField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.license.required',\n fieldName: 'license',\n });\n requireStringArrayField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.keywords.required',\n fieldName: 'keywords',\n });\n requireStringArrayField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.files.required',\n fieldName: 'files',\n });\n requireRecordField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.exports.required',\n fieldName: 'exports',\n });\n requireRecordField({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.publish-config.required',\n fieldName: 'publishConfig',\n });\n\n if (packageJson.private === true) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-invalid',\n message: 'Public package profiles must not set private: true.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.private.public-package-disallowed',\n severity: 'error',\n }),\n );\n }\n\n if (packageJson.type !== undefined && packageJson.type !== 'module') {\n diagnostics.push(\n createDiagnostic({\n code: 'field-invalid',\n message: 'package.json \"type\" must be \"module\".',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.type.module',\n severity: 'error',\n }),\n );\n }\n\n const { publishConfig } = packageJson;\n if (isRecord(publishConfig) && publishConfig.access !== 'public') {\n diagnostics.push(\n createDiagnostic({\n code: isNonEmptyString(publishConfig.access) ? 'field-invalid' : 'field-missing',\n message: 'package.json publishConfig.access must exist and equal \"public\".',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.publish-config.public',\n severity: 'error',\n }),\n );\n }\n\n if (!isNonEmptyString(packageJson.packageManager)) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-missing',\n message: 'package.json must define a Bun-aligned packageManager field.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.package-manager.required',\n severity: 'error',\n }),\n );\n request.plannedChanges.push(\n createPlannedChange({\n description: `Add packageManager: \"bun@${Bun.version}\" to package.json.`,\n filePath: request.packageJsonPath,\n kind: 'update-json',\n ruleId: 'package.json.package-manager.required',\n }),\n );\n } else if (!packageJson.packageManager.startsWith('bun@')) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-invalid',\n message: 'package.json packageManager must be Bun-aligned, for example \"bun@1.x\".',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.json.package-manager.bun',\n severity: 'error',\n }),\n );\n }\n\n const scripts = isRecord(packageJson.scripts) ? packageJson.scripts : null;\n for (const scriptName of REQUIRED_PUBLIC_PACKAGE_SCRIPTS) {\n if (scripts === null || !isNonEmptyString(scripts[scriptName])) {\n diagnostics.push(\n createDiagnostic({\n code: 'missing-script',\n message: `Missing required package script: ${scriptName}`,\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: mapScriptRule(scriptName),\n severity: 'error',\n }),\n );\n }\n }\n\n const devDependencies = isRecord(packageJson.devDependencies)\n ? packageJson.devDependencies\n : null;\n if (!hasDependency(devDependencies, 'typescript')) {\n diagnostics.push(\n createDiagnostic({\n code: 'missing-dependency',\n message: 'Public package repos must declare TypeScript in devDependencies.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.dependencies.typescript.required',\n severity: 'error',\n }),\n );\n }\n\n if (!hasDependency(devDependencies, '@changesets/cli')) {\n diagnostics.push(\n createDiagnostic({\n code: 'missing-dependency',\n message: 'Public package repos must declare @changesets/cli in devDependencies.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.dependencies.changesets.required',\n severity: 'error',\n }),\n );\n }\n\n if (!hasDependency(devDependencies, '@types/bun')) {\n diagnostics.push(\n createDiagnostic({\n code: 'missing-dependency',\n message: 'Public package repos must declare @types/bun in devDependencies.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.dependencies.types-bun.required',\n severity: 'error',\n }),\n );\n }\n\n if (!hasDependency(devDependencies, '@types/node')) {\n diagnostics.push(\n createDiagnostic({\n code: 'missing-dependency',\n message: 'Public package repos must declare @types/node in devDependencies.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.dependencies.types-node.required',\n severity: 'error',\n }),\n );\n }\n\n if (expectsDevtools(packageJson) && !hasDependency(devDependencies, '@ankhorage/devtools')) {\n diagnostics.push(\n createDiagnostic({\n code: 'missing-dependency',\n message:\n 'This package consumes shared Ankhorage lint/format/knip tooling and must declare @ankhorage/devtools.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.dependencies.devtools.required',\n severity: 'error',\n }),\n );\n }\n\n if (\n (await expectsParadox(request.targetPath, packageJson)) &&\n !hasDependency(devDependencies, '@ankhorage/paradox')\n ) {\n diagnostics.push(\n createDiagnostic({\n code: 'missing-dependency',\n message: 'This package owns Paradox docs generation and must declare @ankhorage/paradox.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.dependencies.paradox.required',\n severity: 'error',\n }),\n );\n }\n\n return diagnostics.concat(\n await validateAnkhMetadataAndProvider({\n diagnostics,\n packageJson,\n packageJsonPath: request.packageJsonPath,\n plannedChanges: request.plannedChanges,\n profile: request.profile,\n targetPath: request.targetPath,\n }),\n );\n}\n\nasync function validateAnkhMetadataAndProvider(request: {\n readonly diagnostics: readonly DoctorDiagnostic[];\n readonly packageJson: Record<string, unknown>;\n readonly packageJsonPath: string;\n readonly plannedChanges: DoctorPlannedChange[];\n readonly profile: DoctorPolicyProfile;\n readonly targetPath: string;\n}): Promise<DoctorDiagnostic[]> {\n const diagnostics: DoctorDiagnostic[] = [];\n const providerPackage = await isProviderPackage(request.targetPath);\n const metadata = request.packageJson.ankh;\n\n if (providerPackage && metadata === undefined) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-missing',\n message: 'Provider packages must define package.json.ankh metadata.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.ankh.required-for-provider',\n severity: 'error',\n }),\n );\n request.plannedChanges.push(\n createPlannedChange({\n description:\n 'Add a package.json.ankh block describing the implemented provider category, provider path, and capabilities.',\n filePath: request.packageJsonPath,\n kind: 'update-json',\n ruleId: 'package.ankh.required-for-provider',\n }),\n );\n return diagnostics;\n }\n\n if (metadata === undefined) {\n return diagnostics;\n }\n\n const metadataValidation = validateAnkhMetadataShape(metadata, providerPackage);\n if (metadataValidation !== null) {\n diagnostics.push(\n createDiagnostic({\n code: 'invalid-ankh-metadata',\n message: metadataValidation,\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.ankh.present.valid-shape',\n severity: 'error',\n }),\n );\n return diagnostics;\n }\n\n if (!providerPackage) {\n return diagnostics;\n }\n\n if (!isRecord(metadata) || !isNonEmptyString(metadata.provider)) {\n diagnostics.push(\n createDiagnostic({\n code: 'invalid-ankh-metadata',\n message: 'Provider package metadata must define a package-relative provider path.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.ankh.provider-path.required',\n severity: 'error',\n }),\n );\n return diagnostics;\n }\n\n const inspection = await inspectProviderSource({\n metadataProviderPath: metadata.provider,\n packageRoot: request.targetPath,\n profile: request.profile,\n });\n\n if (inspection.diagnostic !== null) {\n diagnostics.push(inspection.diagnostic);\n return diagnostics;\n }\n\n if (inspection.result === null) {\n return diagnostics;\n }\n\n const metadataCapabilities = Array.isArray(metadata.capabilities)\n ? metadata.capabilities.filter(isNonEmptyString)\n : [];\n const providerCapabilities = uniqueSorted(inspection.result.capabilities);\n const commandCapabilities = uniqueSorted(inspection.result.commandCapabilities);\n\n if (!sameStringSet(metadataCapabilities, commandCapabilities)) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-invalid',\n message:\n 'package.json.ankh capabilities must match the implemented provider command capabilities exactly.',\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: 'package.ankh.capabilities.match-provider',\n severity: 'error',\n }),\n );\n }\n\n if (!sameStringSet(providerCapabilities, commandCapabilities)) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-invalid',\n message: 'Provider export capabilities must match the provider command capability surface.',\n path: inspection.result.sourcePath,\n profile: request.profile,\n ruleId: 'provider.commands.match-capabilities',\n severity: 'error',\n }),\n );\n }\n\n if (!sameStringSet(inspection.result.commandPaths, inspection.result.handlerPaths)) {\n diagnostics.push(\n createDiagnostic({\n code: 'field-invalid',\n message: 'Every provider command descriptor must have a matching handler path.',\n path: inspection.result.sourcePath,\n profile: request.profile,\n ruleId: 'provider.commands.match-handlers',\n severity: 'error',\n }),\n );\n }\n\n return diagnostics;\n}\n\nasync function inspectProviderSource(request: {\n readonly metadataProviderPath: string;\n readonly packageRoot: string;\n readonly profile: DoctorPolicyProfile;\n}): Promise<{\n readonly diagnostic: DoctorDiagnostic | null;\n readonly result: ProviderInspectionResult | null;\n}> {\n const sourcePath = await resolveProviderSourcePath(\n request.packageRoot,\n request.metadataProviderPath,\n );\n if (sourcePath === null) {\n return {\n diagnostic: createDiagnostic({\n code: 'provider-source-missing',\n message:\n 'Provider package metadata is present, but no provider source file could be resolved for inspection.',\n path: request.packageRoot,\n profile: request.profile,\n ruleId: 'provider.source.required',\n severity: 'error',\n }),\n result: null,\n };\n }\n\n try {\n const importedModule: unknown = await import(pathToFileURL(sourcePath).href);\n const provider = isRecord(importedModule) ? importedModule.default : undefined;\n if (!isRecord(provider)) {\n return {\n diagnostic: createDiagnostic({\n code: 'provider-source-import-failed',\n message: 'Provider source default export must be an object.',\n path: sourcePath,\n profile: request.profile,\n ruleId: 'provider.source.importable',\n severity: 'error',\n }),\n result: null,\n };\n }\n\n const capabilities = readStringArray(provider.capabilities);\n const commands = Array.isArray(provider.commands) ? provider.commands : [];\n const handlers = Array.isArray(provider.handlers) ? provider.handlers : [];\n\n const commandCapabilities = commands.flatMap((command) =>\n isRecord(command) && isNonEmptyString(command.capability) ? [command.capability] : [],\n );\n const commandPaths = commands.flatMap((command) => {\n const pathValue = isRecord(command) ? command.path : undefined;\n return isStringTuple(pathValue) ? [pathValue.join(' ')] : [];\n });\n const handlerPaths = handlers.flatMap((handler) => {\n const pathValue = isRecord(handler) ? handler.path : undefined;\n const handlerFunction = isRecord(handler) ? handler.handler : undefined;\n return isStringTuple(pathValue) && typeof handlerFunction === 'function'\n ? [pathValue.join(' ')]\n : [];\n });\n\n return {\n diagnostic: null,\n result: {\n capabilities,\n commandCapabilities,\n commandPaths,\n handlerPaths,\n sourcePath,\n },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n diagnostic: createDiagnostic({\n code: 'provider-source-import-failed',\n message: `Failed to import provider source: ${message}`,\n path: sourcePath,\n profile: request.profile,\n ruleId: 'provider.source.importable',\n severity: 'error',\n }),\n result: null,\n };\n }\n}\n\nasync function resolveProviderSourcePath(\n packageRoot: string,\n metadataProviderPath: string,\n): Promise<string | null> {\n const candidates = new Set<string>();\n candidates.add(path.resolve(packageRoot, metadataProviderPath));\n\n if (metadataProviderPath.startsWith('./dist/') && metadataProviderPath.endsWith('.js')) {\n const relativeStem = metadataProviderPath.slice('./dist/'.length, -'.js'.length);\n candidates.add(path.resolve(packageRoot, 'src', `${relativeStem}.ts`));\n candidates.add(path.resolve(packageRoot, 'src', `${relativeStem}.tsx`));\n candidates.add(path.resolve(packageRoot, 'src', `${relativeStem}.js`));\n candidates.add(path.resolve(packageRoot, 'src', `${relativeStem}.mjs`));\n }\n\n for (const providerSourceCandidate of PROVIDER_SOURCE_CANDIDATES) {\n candidates.add(path.resolve(packageRoot, providerSourceCandidate));\n }\n\n for (const candidate of candidates) {\n if (await pathExists(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nasync function findRepoMarkers(targetPath: string): Promise<readonly string[]> {\n return (\n await Promise.all(\n REPO_MARKERS.map(async (marker) =>\n (await pathExists(path.join(targetPath, marker.relativePath))) ? marker.label : null,\n ),\n )\n ).filter((marker): marker is (typeof REPO_MARKERS)[number]['label'] => marker !== null);\n}\n\nasync function readPackageJson(packageJsonPath: string): Promise<{\n readonly diagnostic: DoctorDiagnostic | null;\n readonly parsed: Record<string, unknown> | null;\n}> {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(await fs.readFile(packageJsonPath, 'utf8')) as unknown;\n } catch (error) {\n return {\n diagnostic: createDiagnostic({\n code: 'invalid-package-json',\n message: createInvalidPackageJsonMessage(error),\n path: packageJsonPath,\n profile: 'unknown',\n ruleId: 'target.package-json.required',\n severity: 'error',\n }),\n parsed: null,\n };\n }\n\n if (!isRecord(parsed)) {\n return {\n diagnostic: createDiagnostic({\n code: 'invalid-package-json',\n message: 'package.json must contain a JSON object.',\n path: packageJsonPath,\n profile: 'unknown',\n ruleId: 'target.package-json.required',\n severity: 'error',\n }),\n parsed: null,\n };\n }\n\n return {\n diagnostic: null,\n parsed,\n };\n}\n\nfunction detectProfile(\n repoMarkers: readonly string[],\n packageJson: Record<string, unknown> | null,\n): DoctorPolicyProfile {\n if (packageJson !== null) {\n if (packageJson.name === 'ankhorage4') {\n return 'integration-monorepo';\n }\n\n if (isNonEmptyString(packageJson.name) && packageJson.name.startsWith('@ankhorage/')) {\n return packageJson.private === true ? 'unknown' : 'public-package';\n }\n }\n\n if (repoMarkers.length > 0) {\n return 'unknown';\n }\n\n return 'unknown';\n}\n\nasync function isProviderPackage(targetPath: string): Promise<boolean> {\n for (const candidate of PROVIDER_SOURCE_CANDIDATES) {\n if (await pathExists(path.join(targetPath, candidate))) {\n return true;\n }\n }\n\n return false;\n}\n\nasync function maybeRequirePath(\n diagnostics: DoctorDiagnostic[],\n plannedChanges: DoctorPlannedChange[],\n rootPath: string,\n relativePath: string,\n ruleId:\n | 'repo.changelog.required'\n | 'repo.changeset.required'\n | 'repo.license.required'\n | 'repo.readme.required'\n | 'repo.workflows.required',\n kind: DoctorPlannedChangeKind,\n): Promise<void> {\n const absolutePath = path.join(rootPath, relativePath);\n if (await pathExists(absolutePath)) {\n return;\n }\n\n diagnostics.push(\n createDiagnostic({\n code: 'missing-path',\n message: `Missing expected repo artifact: ${relativePath}`,\n path: absolutePath,\n profile: 'public-package',\n ruleId,\n severity: 'error',\n }),\n );\n plannedChanges.push(\n createPlannedChange({\n description: `Create missing ${relativePath}.`,\n filePath: absolutePath,\n kind,\n ruleId,\n }),\n );\n}\n\nfunction requireNonEmptyStringField(request: {\n readonly diagnostics: DoctorDiagnostic[];\n readonly fieldName: string;\n readonly packageJson: Record<string, unknown>;\n readonly packageJsonPath: string;\n readonly profile: DoctorPolicyProfile;\n readonly ruleId: DoctorRuleId;\n}): void {\n if (isNonEmptyString(request.packageJson[request.fieldName])) {\n return;\n }\n\n request.diagnostics.push(\n createDiagnostic({\n code: 'field-missing',\n message: `package.json must define a non-empty \"${request.fieldName}\" field.`,\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: request.ruleId,\n severity: 'error',\n }),\n );\n}\n\nfunction requireRecordField(request: {\n readonly diagnostics: DoctorDiagnostic[];\n readonly fieldName: string;\n readonly packageJson: Record<string, unknown>;\n readonly packageJsonPath: string;\n readonly profile: DoctorPolicyProfile;\n readonly ruleId: DoctorRuleId;\n}): void {\n if (isRecord(request.packageJson[request.fieldName])) {\n return;\n }\n\n request.diagnostics.push(\n createDiagnostic({\n code: 'field-missing',\n message: `package.json must define an object \"${request.fieldName}\" field.`,\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: request.ruleId,\n severity: 'error',\n }),\n );\n}\n\nfunction requireStringArrayField(request: {\n readonly diagnostics: DoctorDiagnostic[];\n readonly fieldName: string;\n readonly packageJson: Record<string, unknown>;\n readonly packageJsonPath: string;\n readonly profile: DoctorPolicyProfile;\n readonly ruleId: DoctorRuleId;\n}): void {\n if (readStringArray(request.packageJson[request.fieldName]).length > 0) {\n return;\n }\n\n request.diagnostics.push(\n createDiagnostic({\n code: 'field-missing',\n message: `package.json must define a non-empty string array \"${request.fieldName}\" field.`,\n path: request.packageJsonPath,\n profile: request.profile,\n ruleId: request.ruleId,\n severity: 'error',\n }),\n );\n}\n\nasync function expectsParadox(\n targetPath: string,\n packageJson: Record<string, unknown>,\n): Promise<boolean> {\n const scripts = isRecord(packageJson.scripts) ? packageJson.scripts : null;\n const docsScript = scripts?.docs;\n if (\n isNonEmptyString(docsScript) &&\n (docsScript.includes('paradox') || docsScript.includes('@ankhorage/paradox'))\n ) {\n return true;\n }\n\n return (\n (await pathExists(path.join(targetPath, 'paradox.config.ts'))) ||\n (await pathExists(path.join(targetPath, 'src', 'readme-usage.ts')))\n );\n}\n\nfunction expectsDevtools(packageJson: Record<string, unknown>): boolean {\n const scripts = isRecord(packageJson.scripts) ? packageJson.scripts : null;\n if (scripts === null) {\n return false;\n }\n\n return Object.values(scripts).some(\n (scriptValue) =>\n isNonEmptyString(scriptValue) &&\n (scriptValue.includes('ankhorage-eslint') ||\n scriptValue.includes('ankhorage-prettier') ||\n scriptValue.includes('ankhorage-knip')),\n );\n}\n\nfunction hasDependency(\n dependencyMap: Record<string, unknown> | null,\n dependencyName: string,\n): boolean {\n return dependencyMap !== null && isNonEmptyString(dependencyMap[dependencyName]);\n}\n\nfunction validateAnkhMetadataShape(value: unknown, providerPackage: boolean): string | null {\n if (!isRecord(value)) {\n return 'package.json \"ankh\" metadata must be an object when present.';\n }\n\n if (!isNonEmptyString(value.category)) {\n return 'package.json \"ankh.category\" must be a non-empty string.';\n }\n\n if (\n providerPackage &&\n !(isNonEmptyString(value.provider) && isPackageRelativeProviderPath(value.provider))\n ) {\n return 'Provider package metadata must define a package-relative \"./...\" provider path.';\n }\n\n if (\n !providerPackage &&\n value.provider !== undefined &&\n !(value.provider === null || isPackageRelativeProviderPath(value.provider))\n ) {\n return 'Non-provider package metadata, when present, must use null or a package-relative \"./...\" provider value.';\n }\n\n if (\n !Array.isArray(value.capabilities) ||\n value.capabilities.some((capability) => !isNonEmptyString(capability))\n ) {\n return 'package.json \"ankh.capabilities\" must be an array of non-empty strings.';\n }\n\n return null;\n}\n\nfunction mapScriptRule(scriptName: (typeof REQUIRED_PUBLIC_PACKAGE_SCRIPTS)[number]): DoctorRuleId {\n switch (scriptName) {\n case 'build':\n return 'package.scripts.build.required';\n case 'typecheck':\n return 'package.scripts.typecheck.required';\n case 'lint':\n return 'package.scripts.lint.required';\n case 'lint:fix':\n return 'package.scripts.lint-fix.required';\n case 'format':\n return 'package.scripts.format.required';\n case 'format:check':\n return 'package.scripts.format-check.required';\n case 'test':\n return 'package.scripts.test.required';\n case 'knip':\n return 'package.scripts.knip.required';\n case 'docs':\n return 'package.scripts.docs.required';\n case 'changeset':\n return 'package.scripts.changeset.required';\n case 'changeset:status':\n return 'package.scripts.changeset-status.required';\n case 'version-packages':\n return 'package.scripts.version-packages.required';\n }\n}\n\nfunction createEarlyResult(targetPath: string, diagnostic: DoctorDiagnostic): DoctorAnalysisResult {\n return {\n appliedChecks: [],\n diagnostics: [diagnostic],\n fixPlan: null,\n hasPackageJson: false,\n plannedChanges: [],\n profile: 'unknown',\n repoMarkers: [],\n targetPath,\n };\n}\n\nfunction createDiagnostic(diagnostic: DoctorDiagnostic): DoctorDiagnostic {\n return diagnostic;\n}\n\nfunction createPlannedChange(change: Omit<DoctorPlannedChange, 'safe'>): DoctorPlannedChange {\n return {\n ...change,\n safe: true,\n };\n}\n\nfunction createInvalidPackageJsonMessage(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n return `package.json contains invalid JSON: ${message}`;\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n return (await statOrNull(targetPath)) !== null;\n}\n\nasync function statOrNull(targetPath: string) {\n try {\n return await fs.stat(targetPath);\n } catch (error) {\n if (isMissingPathError(error)) {\n return null;\n }\n\n throw error;\n }\n}\n\nfunction isMissingPathError(error: unknown): error is NodeJS.ErrnoException {\n return (\n error instanceof Error &&\n 'code' in error &&\n typeof error.code === 'string' &&\n error.code === 'ENOENT'\n );\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim() !== '';\n}\n\nfunction isPackageRelativeProviderPath(value: unknown): value is string {\n return isNonEmptyString(value) && value.startsWith('./');\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isStringTuple(value: unknown): value is readonly string[] {\n return Array.isArray(value) && value.length > 0 && value.every(isNonEmptyString);\n}\n\nfunction readStringArray(value: unknown): string[] {\n return Array.isArray(value) ? value.filter(isNonEmptyString) : [];\n}\n\nfunction sameStringSet(left: readonly string[], right: readonly string[]): boolean {\n const leftSet = uniqueSorted(left);\n const rightSet = uniqueSorted(right);\n return (\n leftSet.length === rightSet.length && leftSet.every((value, index) => value === rightSet[index])\n );\n}\n\nfunction uniqueSorted(values: readonly string[]): string[] {\n return [...new Set(values)].sort((left, right) => left.localeCompare(right));\n}\n"]}
|
package/dist/commands.d.ts
CHANGED
|
@@ -34,14 +34,14 @@ export declare const DOCTOR_COMMANDS: readonly [{
|
|
|
34
34
|
readonly path: readonly ["validate"];
|
|
35
35
|
readonly capability: "doctor.validate";
|
|
36
36
|
readonly mode: "validate";
|
|
37
|
-
readonly summary: "Auto-detect
|
|
37
|
+
readonly summary: "Auto-detect the applicable doctor policy profile and validate a local path.";
|
|
38
38
|
readonly run: typeof runValidateCommand;
|
|
39
39
|
}, {
|
|
40
40
|
readonly standaloneName: "fix";
|
|
41
41
|
readonly path: readonly ["fix"];
|
|
42
42
|
readonly capability: "doctor.fix";
|
|
43
43
|
readonly mode: "fix";
|
|
44
|
-
readonly summary: "
|
|
44
|
+
readonly summary: "Build a non-mutating fix plan for deterministic doctor policy violations.";
|
|
45
45
|
readonly run: typeof runFixCommand;
|
|
46
46
|
}, {
|
|
47
47
|
readonly standaloneName: "repo";
|
package/dist/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAExF,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAExF,OAAO,KAAK,EAA6C,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAQxF,KAAK,iBAAiB,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjE,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,KAAK,2BAA2B,GAAG,CACjC,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,KAC5B,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAErC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,iBAAiB,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,2BAA2B,CAAC;CAC3C;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;CACxC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,OAAO,mBAAmB,CAAC;CACpD;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACpD;AAED,MAAM,MAAM,oBAAoB,GAAG,CACjC,OAAO,EAAE,uBAAuB,EAChC,OAAO,CAAC,EAAE,uBAAuB,KAC9B,OAAO,CAAC,sBAAsB,CAAC,CAAC;AASrC,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiC2B,CAAC;AAExD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,EAChC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAqBjC;AAED,wBAAgB,gCAAgC,IAAI,SAAS,qBAAqB,EAAE,CAMnF;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI,CAE/F;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBtD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AA4CD,iBAAe,kBAAkB,CAC/B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAYjC;AAED,iBAAe,aAAa,CAC1B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAYjC;AAED,iBAAe,cAAc,CAC3B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAYjC;AAED,iBAAe,iBAAiB,CAC9B,OAAO,EAAE,uBAAuB,EAChC,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAYjC"}
|
package/dist/commands.js
CHANGED
|
@@ -13,7 +13,7 @@ export const DOCTOR_COMMANDS = [
|
|
|
13
13
|
path: ['validate'],
|
|
14
14
|
capability: COMMAND_CAPABILITIES.validate,
|
|
15
15
|
mode: 'validate',
|
|
16
|
-
summary: 'Auto-detect
|
|
16
|
+
summary: 'Auto-detect the applicable doctor policy profile and validate a local path.',
|
|
17
17
|
run: runValidateCommand,
|
|
18
18
|
},
|
|
19
19
|
{
|
|
@@ -21,7 +21,7 @@ export const DOCTOR_COMMANDS = [
|
|
|
21
21
|
path: ['fix'],
|
|
22
22
|
capability: COMMAND_CAPABILITIES.fix,
|
|
23
23
|
mode: 'fix',
|
|
24
|
-
summary: '
|
|
24
|
+
summary: 'Build a non-mutating fix plan for deterministic doctor policy violations.',
|
|
25
25
|
run: runFixCommand,
|
|
26
26
|
},
|
|
27
27
|
{
|
|
@@ -138,7 +138,6 @@ async function runFixCommand(request, services) {
|
|
|
138
138
|
mode: 'fix',
|
|
139
139
|
});
|
|
140
140
|
request.context.writeStdout(renderAnalysisReport('fix', result));
|
|
141
|
-
request.context.writeStdout('No automatic fixes available.\n');
|
|
142
141
|
return {
|
|
143
142
|
exitCode: countErrorDiagnostics(result.diagnostics) > 0 ? 1 : 0,
|
|
144
143
|
};
|
|
@@ -169,6 +168,7 @@ function renderAnalysisReport(commandName, result) {
|
|
|
169
168
|
const lines = [
|
|
170
169
|
`doctor ${commandName}`,
|
|
171
170
|
`target: ${result.targetPath}`,
|
|
171
|
+
`profile: ${result.profile}`,
|
|
172
172
|
`checks: ${result.appliedChecks.length > 0 ? result.appliedChecks.join(', ') : 'none'}`,
|
|
173
173
|
`repoMarkers: ${result.repoMarkers.length > 0 ? result.repoMarkers.join(', ') : 'none'}`,
|
|
174
174
|
'',
|
|
@@ -182,6 +182,18 @@ function renderAnalysisReport(commandName, result) {
|
|
|
182
182
|
lines.push(renderDiagnosticLine(diagnostic));
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
+
if (commandName === 'fix') {
|
|
186
|
+
lines.push('');
|
|
187
|
+
lines.push('Planned changes:');
|
|
188
|
+
if (result.plannedChanges.length === 0) {
|
|
189
|
+
lines.push(' none');
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
for (const change of result.plannedChanges) {
|
|
193
|
+
lines.push(renderPlannedChangeLine(change));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
185
197
|
const errorCount = countErrorDiagnostics(result.diagnostics);
|
|
186
198
|
const warningCount = countWarningDiagnostics(result.diagnostics);
|
|
187
199
|
lines.push('');
|
|
@@ -190,7 +202,10 @@ function renderAnalysisReport(commandName, result) {
|
|
|
190
202
|
return lines.join('\n');
|
|
191
203
|
}
|
|
192
204
|
function renderDiagnosticLine(diagnostic) {
|
|
193
|
-
return ` - ${diagnostic.severity.toUpperCase()} ${diagnostic.code}: ${diagnostic.message}`;
|
|
205
|
+
return ` - ${diagnostic.severity.toUpperCase()} ${diagnostic.ruleId} (${diagnostic.code}): ${diagnostic.message}`;
|
|
206
|
+
}
|
|
207
|
+
function renderPlannedChangeLine(change) {
|
|
208
|
+
return ` - ${change.ruleId} [${change.kind}]: ${change.description}`;
|
|
194
209
|
}
|
|
195
210
|
function renderCommandFailure(commandName, error) {
|
|
196
211
|
const message = error instanceof Error ? error.message : String(error);
|
package/dist/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnkhCapabilityId, AnkhCommandDescriptor } from '@ankhorage/contracts/cli';\n\nimport type { DoctorAnalysisResult, DoctorTargetMode } from './analysis.js';\nimport { analyzeDoctorTarget } from './analysis.js';\nimport type { DoctorCommandContext, DoctorCommandRunResult } from './commandContext.js';\nimport {\n countErrorDiagnostics,\n countWarningDiagnostics,\n type DoctorDiagnostic,\n} from './diagnostics.js';\nimport { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY } from './packageMetadata.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(renderCommandFailure(request.command.standaloneName, error));\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(value: string): 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 [`Unknown doctor command: ${value}`, '', 'Run ankhorage-doctor --help', ''].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;\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"]}
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnkhCapabilityId, AnkhCommandDescriptor } from '@ankhorage/contracts/cli';\n\nimport type { DoctorAnalysisResult, DoctorPlannedChange, DoctorTargetMode } from './analysis.js';\nimport { analyzeDoctorTarget } from './analysis.js';\nimport type { DoctorCommandContext, DoctorCommandRunResult } from './commandContext.js';\nimport {\n countErrorDiagnostics,\n countWarningDiagnostics,\n type DoctorDiagnostic,\n} from './diagnostics.js';\nimport { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY } from './packageMetadata.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 the applicable doctor policy profile and validate a local path.',\n run: runValidateCommand,\n },\n {\n standaloneName: 'fix',\n path: ['fix'],\n capability: COMMAND_CAPABILITIES.fix,\n mode: 'fix',\n summary: 'Build a non-mutating fix plan for deterministic doctor policy violations.',\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(renderCommandFailure(request.command.standaloneName, error));\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(value: string): 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 [`Unknown doctor command: ${value}`, '', 'Run ankhorage-doctor --help', ''].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;\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\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 `profile: ${result.profile}`,\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 if (commandName === 'fix') {\n lines.push('');\n lines.push('Planned changes:');\n\n if (result.plannedChanges.length === 0) {\n lines.push(' none');\n } else {\n for (const change of result.plannedChanges) {\n lines.push(renderPlannedChangeLine(change));\n }\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.ruleId} (${diagnostic.code}): ${diagnostic.message}`;\n}\n\nfunction renderPlannedChangeLine(change: DoctorPlannedChange): string {\n return ` - ${change.ruleId} [${change.kind}]: ${change.description}`;\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"]}
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
export type DoctorDiagnosticCode = 'invalid
|
|
1
|
+
export type DoctorDiagnosticCode = 'field-invalid' | 'field-missing' | 'invalid-ankh-metadata' | 'invalid-package-json' | 'missing-dependency' | 'missing-path' | 'missing-script' | 'provider-source-import-failed' | 'provider-source-missing' | 'target-not-directory' | 'target-not-found' | 'unsupported-target';
|
|
2
2
|
export type DoctorDiagnosticSeverity = 'error' | 'warning';
|
|
3
|
+
export type DoctorPolicyProfile = 'integration-monorepo' | 'public-package' | 'unknown';
|
|
4
|
+
export type DoctorRuleId = 'integration.package.ankh.disallowed' | 'integration.package.private.required' | 'integration.package.workspaces.required' | 'package.ankh.capabilities.match-provider' | 'package.ankh.present.valid-shape' | 'package.ankh.provider-path.required' | 'package.ankh.required-for-provider' | 'package.dependencies.changesets.required' | 'package.dependencies.devtools.required' | 'package.dependencies.paradox.required' | 'package.dependencies.types-bun.required' | 'package.dependencies.types-node.required' | 'package.dependencies.typescript.required' | 'package.json.bugs.required' | 'package.json.description.required' | 'package.json.exports.required' | 'package.json.files.required' | 'package.json.homepage.required' | 'package.json.keywords.required' | 'package.json.license.required' | 'package.json.name.required' | 'package.json.package-manager.bun' | 'package.json.package-manager.required' | 'package.json.private.public-package-disallowed' | 'package.json.publish-config.public' | 'package.json.publish-config.required' | 'package.json.repository.required' | 'package.json.type.module' | 'package.json.type.required' | 'package.json.version.required' | 'package.scripts.build.required' | 'package.scripts.changeset-status.required' | 'package.scripts.changeset.required' | 'package.scripts.docs.required' | 'package.scripts.format-check.required' | 'package.scripts.format.required' | 'package.scripts.knip.required' | 'package.scripts.lint-fix.required' | 'package.scripts.lint.required' | 'package.scripts.test.required' | 'package.scripts.typecheck.required' | 'package.scripts.version-packages.required' | 'provider.commands.match-capabilities' | 'provider.commands.match-handlers' | 'provider.source.importable' | 'provider.source.required' | 'repo.changelog.required' | 'repo.changeset.required' | 'repo.license.required' | 'repo.readme.required' | 'repo.workflows.required' | 'target.package-json.required' | 'target.path.directory' | 'target.path.exists' | 'target.profile.supported' | 'target.repo-markers.required';
|
|
3
5
|
export interface DoctorDiagnostic {
|
|
4
6
|
readonly code: DoctorDiagnosticCode;
|
|
5
7
|
readonly message: string;
|
|
6
8
|
readonly path: string;
|
|
9
|
+
readonly profile: DoctorPolicyProfile;
|
|
10
|
+
readonly ruleId: DoctorRuleId;
|
|
7
11
|
readonly severity: DoctorDiagnosticSeverity;
|
|
8
12
|
}
|
|
9
13
|
export declare function countErrorDiagnostics(diagnostics: readonly DoctorDiagnostic[]): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,uBAAuB,GACvB,sBAAsB,GACtB,
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,eAAe,GACf,eAAe,GACf,uBAAuB,GACvB,sBAAsB,GACtB,oBAAoB,GACpB,cAAc,GACd,gBAAgB,GAChB,+BAA+B,GAC/B,yBAAyB,GACzB,sBAAsB,GACtB,kBAAkB,GAClB,oBAAoB,CAAC;AAEzB,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,SAAS,CAAC;AAC3D,MAAM,MAAM,mBAAmB,GAAG,sBAAsB,GAAG,gBAAgB,GAAG,SAAS,CAAC;AACxF,MAAM,MAAM,YAAY,GACpB,qCAAqC,GACrC,sCAAsC,GACtC,yCAAyC,GACzC,0CAA0C,GAC1C,kCAAkC,GAClC,qCAAqC,GACrC,oCAAoC,GACpC,0CAA0C,GAC1C,wCAAwC,GACxC,uCAAuC,GACvC,yCAAyC,GACzC,0CAA0C,GAC1C,0CAA0C,GAC1C,4BAA4B,GAC5B,mCAAmC,GACnC,+BAA+B,GAC/B,6BAA6B,GAC7B,gCAAgC,GAChC,gCAAgC,GAChC,+BAA+B,GAC/B,4BAA4B,GAC5B,kCAAkC,GAClC,uCAAuC,GACvC,gDAAgD,GAChD,oCAAoC,GACpC,sCAAsC,GACtC,kCAAkC,GAClC,0BAA0B,GAC1B,4BAA4B,GAC5B,+BAA+B,GAC/B,gCAAgC,GAChC,2CAA2C,GAC3C,oCAAoC,GACpC,+BAA+B,GAC/B,uCAAuC,GACvC,iCAAiC,GACjC,+BAA+B,GAC/B,mCAAmC,GACnC,+BAA+B,GAC/B,+BAA+B,GAC/B,oCAAoC,GACpC,2CAA2C,GAC3C,sCAAsC,GACtC,kCAAkC,GAClC,4BAA4B,GAC5B,0BAA0B,GAC1B,yBAAyB,GACzB,yBAAyB,GACzB,uBAAuB,GACvB,sBAAsB,GACtB,yBAAyB,GACzB,8BAA8B,GAC9B,uBAAuB,GACvB,oBAAoB,GACpB,0BAA0B,GAC1B,8BAA8B,CAAC;AAEnC,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,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,CAEtF;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,CAExF"}
|
package/dist/diagnostics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAmFA,MAAM,UAAU,qBAAqB,CAAC,WAAwC;IAC5E,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,WAAwC;IAC9E,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;AACtF,CAAC","sourcesContent":["export type DoctorDiagnosticCode =\n | 'field-invalid'\n | 'field-missing'\n | 'invalid-ankh-metadata'\n | 'invalid-package-json'\n | 'missing-dependency'\n | 'missing-path'\n | 'missing-script'\n | 'provider-source-import-failed'\n | 'provider-source-missing'\n | 'target-not-directory'\n | 'target-not-found'\n | 'unsupported-target';\n\nexport type DoctorDiagnosticSeverity = 'error' | 'warning';\nexport type DoctorPolicyProfile = 'integration-monorepo' | 'public-package' | 'unknown';\nexport type DoctorRuleId =\n | 'integration.package.ankh.disallowed'\n | 'integration.package.private.required'\n | 'integration.package.workspaces.required'\n | 'package.ankh.capabilities.match-provider'\n | 'package.ankh.present.valid-shape'\n | 'package.ankh.provider-path.required'\n | 'package.ankh.required-for-provider'\n | 'package.dependencies.changesets.required'\n | 'package.dependencies.devtools.required'\n | 'package.dependencies.paradox.required'\n | 'package.dependencies.types-bun.required'\n | 'package.dependencies.types-node.required'\n | 'package.dependencies.typescript.required'\n | 'package.json.bugs.required'\n | 'package.json.description.required'\n | 'package.json.exports.required'\n | 'package.json.files.required'\n | 'package.json.homepage.required'\n | 'package.json.keywords.required'\n | 'package.json.license.required'\n | 'package.json.name.required'\n | 'package.json.package-manager.bun'\n | 'package.json.package-manager.required'\n | 'package.json.private.public-package-disallowed'\n | 'package.json.publish-config.public'\n | 'package.json.publish-config.required'\n | 'package.json.repository.required'\n | 'package.json.type.module'\n | 'package.json.type.required'\n | 'package.json.version.required'\n | 'package.scripts.build.required'\n | 'package.scripts.changeset-status.required'\n | 'package.scripts.changeset.required'\n | 'package.scripts.docs.required'\n | 'package.scripts.format-check.required'\n | 'package.scripts.format.required'\n | 'package.scripts.knip.required'\n | 'package.scripts.lint-fix.required'\n | 'package.scripts.lint.required'\n | 'package.scripts.test.required'\n | 'package.scripts.typecheck.required'\n | 'package.scripts.version-packages.required'\n | 'provider.commands.match-capabilities'\n | 'provider.commands.match-handlers'\n | 'provider.source.importable'\n | 'provider.source.required'\n | 'repo.changelog.required'\n | 'repo.changeset.required'\n | 'repo.license.required'\n | 'repo.readme.required'\n | 'repo.workflows.required'\n | 'target.package-json.required'\n | 'target.path.directory'\n | 'target.path.exists'\n | 'target.profile.supported'\n | 'target.repo-markers.required';\n\nexport interface DoctorDiagnostic {\n readonly code: DoctorDiagnosticCode;\n readonly message: string;\n readonly path: string;\n readonly profile: DoctorPolicyProfile;\n readonly ruleId: DoctorRuleId;\n readonly severity: DoctorDiagnosticSeverity;\n}\n\nexport function countErrorDiagnostics(diagnostics: readonly DoctorDiagnostic[]): number {\n return diagnostics.filter((diagnostic) => diagnostic.severity === 'error').length;\n}\n\nexport function countWarningDiagnostics(diagnostics: readonly DoctorDiagnostic[]): number {\n return diagnostics.filter((diagnostic) => diagnostic.severity === 'warning').length;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export type { DoctorAnalysisRequest, DoctorAnalysisResult, DoctorTargetCheck, DoctorTargetMode, } from './analysis.js';
|
|
1
|
+
export type { DoctorAnalysisRequest, DoctorAnalysisResult, DoctorFixPlan, DoctorPlannedChange, DoctorPlannedChangeKind, DoctorTargetCheck, DoctorTargetMode, } from './analysis.js';
|
|
2
2
|
export { analyzeDoctorTarget } from './analysis.js';
|
|
3
3
|
export { createDoctorRuntimeProvider, type CreateDoctorRuntimeProviderOptions, } from './ankh.provider.js';
|
|
4
4
|
export { runCli } from './cli.js';
|
|
5
5
|
export type { DoctorCommandContext, DoctorCommandRunResult } from './commandContext.js';
|
|
6
6
|
export { createDefaultCommandContext } from './commandContext.js';
|
|
7
|
-
export type { DoctorDiagnostic, DoctorDiagnosticCode, DoctorDiagnosticSeverity, } from './diagnostics.js';
|
|
7
|
+
export type { DoctorDiagnostic, DoctorDiagnosticCode, DoctorDiagnosticSeverity, DoctorPolicyProfile, DoctorRuleId, } from './diagnostics.js';
|
|
8
8
|
export { DOCTOR_CAPABILITIES, DOCTOR_COMMAND_CATEGORY, DOCTOR_PACKAGE_METADATA, DOCTOR_PACKAGE_NAME, DOCTOR_PACKAGE_VERSION, } from './packageMetadata.js';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,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,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,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,uBAAuB,EACvB,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,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,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,2BAA2B,GAE5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAQlE,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC","sourcesContent":["export type {\n DoctorAnalysisRequest,\n DoctorAnalysisResult,\n DoctorFixPlan,\n DoctorPlannedChange,\n DoctorPlannedChangeKind,\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 { runCli } from './cli.js';\nexport type { DoctorCommandContext, DoctorCommandRunResult } from './commandContext.js';\nexport { createDefaultCommandContext } from './commandContext.js';\nexport type {\n DoctorDiagnostic,\n DoctorDiagnosticCode,\n DoctorDiagnosticSeverity,\n DoctorPolicyProfile,\n DoctorRuleId,\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"]}
|
package/dist/readme-usage.js
CHANGED
|
@@ -16,10 +16,18 @@ import { runCli } from './cli.js';
|
|
|
16
16
|
* - `repo`
|
|
17
17
|
* - `package`
|
|
18
18
|
*
|
|
19
|
-
* `doctor#
|
|
19
|
+
* `doctor#2` adds a profile-based policy engine:
|
|
20
20
|
*
|
|
21
|
-
* -
|
|
22
|
-
* -
|
|
21
|
+
* - strict `public-package` validation for extracted public package repos
|
|
22
|
+
* - light recognized `integration-monorepo` validation for `ankhorage4`
|
|
23
|
+
* - non-mutating `fix` plans for deterministic mechanical changes only
|
|
24
|
+
*
|
|
25
|
+
* Still deferred:
|
|
26
|
+
*
|
|
27
|
+
* - GitHub checks
|
|
28
|
+
* - CI checks
|
|
29
|
+
* - on-disk `fix --apply`
|
|
30
|
+
* - deeper cross-repo policy enforcement
|
|
23
31
|
*
|
|
24
32
|
* Path handling:
|
|
25
33
|
*
|
package/dist/readme-usage.js.map
CHANGED
|
@@ -1 +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
|
|
1
|
+
{"version":3,"file":"readme-usage.js","sourceRoot":"","sources":["../src/readme-usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;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#2` adds a profile-based policy engine:\n *\n * - strict `public-package` validation for extracted public package repos\n * - light recognized `integration-monorepo` validation for `ankhorage4`\n * - non-mutating `fix` plans for deterministic mechanical changes only\n *\n * Still deferred:\n *\n * - GitHub checks\n * - CI checks\n * - on-disk `fix --apply`\n * - deeper cross-repo policy enforcement\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"]}
|