@documentation-robotics/cli 0.2.0 → 0.4.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/README.md +46 -16
- package/dist/analysis/relationship-classifier.js +2 -9
- package/dist/analysis/relationship-classifier.js.map +2 -2
- package/dist/analyzers/active-analyzer.js +62 -0
- package/dist/analyzers/active-analyzer.js.map +7 -0
- package/dist/analyzers/call-graph-utils.js +2 -2
- package/dist/analyzers/call-graph-utils.js.map +2 -2
- package/dist/analyzers/cards/build.js +191 -0
- package/dist/analyzers/cards/build.js.map +7 -0
- package/dist/analyzers/cards/classify.js +42 -0
- package/dist/analyzers/cards/classify.js.map +7 -0
- package/dist/analyzers/cards/edge-index.js +44 -0
- package/dist/analyzers/cards/edge-index.js.map +7 -0
- package/dist/analyzers/cards/extract.js +138 -0
- package/dist/analyzers/cards/extract.js.map +7 -0
- package/dist/analyzers/cards/facts.js +46 -0
- package/dist/analyzers/cards/facts.js.map +7 -0
- package/dist/analyzers/cards/graph.js +42 -0
- package/dist/analyzers/cards/graph.js.map +7 -0
- package/dist/analyzers/cards/index.js +8 -0
- package/dist/analyzers/cards/index.js.map +7 -0
- package/dist/analyzers/cards/routes.js +96 -0
- package/dist/analyzers/cards/routes.js.map +7 -0
- package/dist/analyzers/cards/tier0.js +18 -0
- package/dist/analyzers/cards/tier0.js.map +7 -0
- package/dist/analyzers/cards/types.js +1 -0
- package/dist/analyzers/cards/types.js.map +7 -0
- package/dist/analyzers/cbm-analyzer.js +270 -174
- package/dist/analyzers/cbm-analyzer.js.map +2 -2
- package/dist/analyzers/cbm-responses.js +342 -0
- package/dist/analyzers/cbm-responses.js.map +7 -0
- package/dist/analyzers/code-changes.js +159 -0
- package/dist/analyzers/code-changes.js.map +7 -0
- package/dist/analyzers/edge-relationships.js +49 -0
- package/dist/analyzers/edge-relationships.js.map +7 -0
- package/dist/analyzers/extraction-plan.js +541 -0
- package/dist/analyzers/extraction-plan.js.map +7 -0
- package/dist/analyzers/index-job.js +229 -0
- package/dist/analyzers/index-job.js.map +7 -0
- package/dist/analyzers/mapping-loader.js +9 -0
- package/dist/analyzers/mapping-loader.js.map +2 -2
- package/dist/analyzers/tier0-rules.js +153 -0
- package/dist/analyzers/tier0-rules.js.map +7 -0
- package/dist/analyzers/types.js.map +1 -1
- package/dist/audit/relationships/ai/prompts.js +10 -10
- package/dist/audit/relationships/ai/prompts.js.map +2 -2
- package/dist/audit/relationships/analysis/layer-templates.js +52 -52
- package/dist/audit/relationships/analysis/layer-templates.js.map +1 -1
- package/dist/cli.js +23 -11
- package/dist/cli.js.map +2 -2
- package/dist/coding-agents/default-permissions.js +31 -1
- package/dist/coding-agents/default-permissions.js.map +2 -2
- package/dist/coding-agents/drbot-mcp.js +269 -0
- package/dist/coding-agents/drbot-mcp.js.map +7 -0
- package/dist/commands/add.js +7 -4
- package/dist/commands/add.js.map +2 -2
- package/dist/commands/analyzer.js +143 -40
- package/dist/commands/analyzer.js.map +2 -2
- package/dist/commands/changeset-verify.js +63 -0
- package/dist/commands/changeset-verify.js.map +7 -0
- package/dist/commands/changeset.js +80 -29
- package/dist/commands/changeset.js.map +2 -2
- package/dist/commands/delete.js +10 -4
- package/dist/commands/delete.js.map +2 -2
- package/dist/commands/farm.js +176 -60
- package/dist/commands/farm.js.map +2 -2
- package/dist/commands/init.js +9 -26
- package/dist/commands/init.js.map +2 -2
- package/dist/commands/mcp.js +40 -21
- package/dist/commands/mcp.js.map +3 -3
- package/dist/commands/relationship.js +208 -37
- package/dist/commands/relationship.js.map +2 -2
- package/dist/commands/reports.js +3 -3
- package/dist/commands/reports.js.map +2 -2
- package/dist/commands/update.js +52 -32
- package/dist/commands/update.js.map +2 -2
- package/dist/commands/upgrade.js +99 -103
- package/dist/commands/upgrade.js.map +3 -3
- package/dist/commands/validate.js +19 -3
- package/dist/commands/validate.js.map +2 -2
- package/dist/commands/version.js +1 -1
- package/dist/commands/visualize.js +34 -15
- package/dist/commands/visualize.js.map +2 -2
- package/dist/core/annotation-store.js +15 -5
- package/dist/core/annotation-store.js.map +2 -2
- package/dist/core/catalog-migration.js +34 -0
- package/dist/core/catalog-migration.js.map +7 -0
- package/dist/core/changeset-analysis.js +421 -0
- package/dist/core/changeset-analysis.js.map +7 -0
- package/dist/core/changeset-base-index.js +160 -0
- package/dist/core/changeset-base-index.js.map +7 -0
- package/dist/core/changeset-brief-compact.js +256 -0
- package/dist/core/changeset-brief-compact.js.map +7 -0
- package/dist/core/changeset-brief-delta.js +102 -0
- package/dist/core/changeset-brief-delta.js.map +7 -0
- package/dist/core/changeset-graph.js +281 -0
- package/dist/core/changeset-graph.js.map +7 -0
- package/dist/core/changeset-only-guard.js +32 -0
- package/dist/core/changeset-only-guard.js.map +7 -0
- package/dist/core/changeset-summary.js +68 -0
- package/dist/core/changeset-summary.js.map +7 -0
- package/dist/core/changeset-validator.js +66 -20
- package/dist/core/changeset-validator.js.map +2 -2
- package/dist/core/changeset-verify.js +848 -0
- package/dist/core/changeset-verify.js.map +7 -0
- package/dist/core/changeset.js +56 -9
- package/dist/core/changeset.js.map +2 -2
- package/dist/core/element-type-migration.js +145 -0
- package/dist/core/element-type-migration.js.map +7 -0
- package/dist/core/extraction-observability.js +161 -0
- package/dist/core/extraction-observability.js.map +7 -0
- package/dist/core/farm-manifest.js +12 -6
- package/dist/core/farm-manifest.js.map +2 -2
- package/dist/core/farm-sync-engine.js +1 -1
- package/dist/core/farm-sync-engine.js.map +2 -2
- package/dist/core/farm-sync-state.js +10 -2
- package/dist/core/farm-sync-state.js.map +2 -2
- package/dist/core/migration-registry.js +88 -47
- package/dist/core/migration-registry.js.map +2 -2
- package/dist/core/model-upgrade.js +102 -0
- package/dist/core/model-upgrade.js.map +7 -0
- package/dist/core/model.js +82 -30
- package/dist/core/model.js.map +2 -2
- package/dist/core/mutation-handler.js +71 -6
- package/dist/core/mutation-handler.js.map +2 -2
- package/dist/core/project-init.js +53 -0
- package/dist/core/project-init.js.map +7 -0
- package/dist/core/relationship-migration-table.js +6639 -0
- package/dist/core/relationship-migration-table.js.map +7 -0
- package/dist/core/relationship-migration.js +272 -0
- package/dist/core/relationship-migration.js.map +7 -0
- package/dist/core/relationship-prune.js +49 -0
- package/dist/core/relationship-prune.js.map +7 -0
- package/dist/core/relationship-staging.js +161 -0
- package/dist/core/relationship-staging.js.map +7 -0
- package/dist/core/relationships.js +26 -4
- package/dist/core/relationships.js.map +2 -2
- package/dist/core/report-data-model.js +7 -13
- package/dist/core/report-data-model.js.map +2 -2
- package/dist/core/staged-changeset-storage.js +145 -18
- package/dist/core/staged-changeset-storage.js.map +2 -2
- package/dist/core/staged-source-reference.js +28 -0
- package/dist/core/staged-source-reference.js.map +7 -0
- package/dist/core/staging-area.js +166 -24
- package/dist/core/staging-area.js.map +2 -2
- package/dist/core/upgrade-plan.js +117 -0
- package/dist/core/upgrade-plan.js.map +7 -0
- package/dist/core/virtual-projection.js +13 -5
- package/dist/core/virtual-projection.js.map +2 -2
- package/dist/export/archimate-exporter.js +1 -0
- package/dist/export/archimate-exporter.js.map +2 -2
- package/dist/generated/compiled-validators.js +2 -2
- package/dist/generated/compiled-validators.js.map +2 -2
- package/dist/generated/layer-registry.js +16 -16
- package/dist/generated/layer-registry.js.map +2 -2
- package/dist/generated/node-types.js +186 -168
- package/dist/generated/node-types.js.map +2 -2
- package/dist/generated/relationship-index.js +2468 -7913
- package/dist/generated/relationship-index.js.map +2 -2
- package/dist/integrations/claude_code/.claude-plugin/plugin.json +24 -0
- package/dist/integrations/claude_code/agents/dr-architect.md +30 -3
- package/dist/integrations/claude_code/agents/dr-extractor.md +8 -2
- package/dist/integrations/claude_code/commands/dr-analyzer.md +565 -0
- package/dist/integrations/claude_code/commands/dr-changeset.md +2 -1
- package/dist/integrations/claude_code/commands/dr-map.md +20 -1
- package/dist/integrations/claude_code/commands/dr-plan.md +66 -0
- package/dist/integrations/claude_code/commands/dr-relate.md +106 -96
- package/dist/integrations/claude_code/commands/dr-verify.md +45 -2
- package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +14 -0
- package/dist/integrations/claude_code/docs/MCP_SERVER.md +47 -26
- package/dist/integrations/claude_code/docs/QUICK_START.md +37 -8
- package/dist/integrations/claude_code/docs/README.md +68 -2
- package/dist/integrations/claude_code/plugin-agents/dr-advisor.md +255 -0
- package/dist/integrations/claude_code/plugin-agents/dr-architect.md +306 -0
- package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +93 -72
- package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +163 -126
- package/dist/integrations/claude_code/skills/dr_03_product_layer/SKILL.md +161 -126
- package/dist/integrations/claude_code/skills/dr_04_security_layer/SKILL.md +153 -133
- package/dist/integrations/claude_code/skills/dr_05_application_layer/SKILL.md +129 -100
- package/dist/integrations/claude_code/skills/dr_06_technology_layer/SKILL.md +111 -94
- package/dist/integrations/claude_code/skills/dr_07_api_layer/SKILL.md +143 -157
- package/dist/integrations/claude_code/skills/dr_08_data_model_layer/SKILL.md +117 -33
- package/dist/integrations/claude_code/skills/dr_09_dataset_layer/SKILL.md +74 -25
- package/dist/integrations/claude_code/skills/dr_10_ux_layer/SKILL.md +88 -12
- package/dist/integrations/claude_code/skills/dr_11_navigation_layer/SKILL.md +83 -24
- package/dist/integrations/claude_code/skills/dr_12_apm_layer/SKILL.md +57 -12
- package/dist/integrations/claude_code/skills/dr_13_testing_layer/SKILL.md +95 -15
- package/dist/integrations/claude_code/skills/dr_change_planning/SKILL.md +178 -0
- package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +8 -0
- package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +6 -1
- package/dist/integrations/github_copilot/agents/dr-architect.md +3 -1
- package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +182 -102
- package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +266 -148
- package/dist/integrations/github_copilot/skills/dr_03_product_layer/SKILL.md +547 -86
- package/dist/integrations/github_copilot/skills/dr_04_security_layer/SKILL.md +164 -169
- package/dist/integrations/github_copilot/skills/dr_05_application_layer/SKILL.md +420 -150
- package/dist/integrations/github_copilot/skills/dr_06_technology_layer/SKILL.md +331 -138
- package/dist/integrations/github_copilot/skills/dr_07_api_layer/SKILL.md +265 -201
- package/dist/integrations/github_copilot/skills/dr_08_data_model_layer/SKILL.md +181 -58
- package/dist/integrations/github_copilot/skills/dr_09_dataset_layer/SKILL.md +209 -57
- package/dist/integrations/github_copilot/skills/dr_10_ux_layer/SKILL.md +277 -112
- package/dist/integrations/github_copilot/skills/dr_11_navigation_layer/SKILL.md +219 -70
- package/dist/integrations/github_copilot/skills/dr_12_apm_layer/SKILL.md +189 -105
- package/dist/integrations/github_copilot/skills/dr_13_testing_layer/SKILL.md +225 -102
- package/dist/integrations/github_copilot/skills/dr_change_planning/SKILL.md +177 -0
- package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +3 -0
- package/dist/integrations/hash-utils.js.map +2 -2
- package/dist/mcp/api-key-manager.js +14 -1
- package/dist/mcp/api-key-manager.js.map +2 -2
- package/dist/mcp/changeset-only.js +45 -0
- package/dist/mcp/changeset-only.js.map +7 -0
- package/dist/mcp/project-root.js +85 -0
- package/dist/mcp/project-root.js.map +7 -0
- package/dist/mcp/server-instructions.js +27 -0
- package/dist/mcp/server-instructions.js.map +7 -0
- package/dist/mcp/strict-schema.js +52 -0
- package/dist/mcp/strict-schema.js.map +7 -0
- package/dist/mcp/tool-registry.js +55 -5
- package/dist/mcp/tool-registry.js.map +2 -2
- package/dist/mcp/tools/changeset-analysis-tools.js +98 -0
- package/dist/mcp/tools/changeset-analysis-tools.js.map +7 -0
- package/dist/mcp/tools/changeset-commit.js +224 -0
- package/dist/mcp/tools/changeset-commit.js.map +7 -0
- package/dist/mcp/tools/changeset-editing.js +260 -0
- package/dist/mcp/tools/changeset-editing.js.map +7 -0
- package/dist/mcp/tools/changeset-lifecycle.js +83 -0
- package/dist/mcp/tools/changeset-lifecycle.js.map +7 -0
- package/dist/mcp/tools/changeset-shared.js +31 -0
- package/dist/mcp/tools/changeset-shared.js.map +7 -0
- package/dist/mcp/tools/changeset-show.js +17 -1
- package/dist/mcp/tools/changeset-show.js.map +2 -2
- package/dist/mcp/tools/changeset-verify.js +49 -0
- package/dist/mcp/tools/changeset-verify.js.map +7 -0
- package/dist/mcp/tools/codebase-extract.js +836 -0
- package/dist/mcp/tools/codebase-extract.js.map +7 -0
- package/dist/mcp/tools/codebase-index.js +125 -0
- package/dist/mcp/tools/codebase-index.js.map +7 -0
- package/dist/mcp/tools/codebase-shared.js +265 -0
- package/dist/mcp/tools/codebase-shared.js.map +7 -0
- package/dist/mcp/tools/codebase-verify.js +48 -0
- package/dist/mcp/tools/codebase-verify.js.map +7 -0
- package/dist/mcp/tools/index.js +34 -1
- package/dist/mcp/tools/index.js.map +2 -2
- package/dist/mcp/tools/model-add.js +191 -74
- package/dist/mcp/tools/model-add.js.map +2 -2
- package/dist/mcp/tools/model-delete.js +2 -2
- package/dist/mcp/tools/model-delete.js.map +2 -2
- package/dist/mcp/tools/model-search.js +14 -0
- package/dist/mcp/tools/model-search.js.map +2 -2
- package/dist/mcp/tools/model-show.js +29 -2
- package/dist/mcp/tools/model-show.js.map +2 -2
- package/dist/mcp/tools/model-trace.js +93 -30
- package/dist/mcp/tools/model-trace.js.map +2 -2
- package/dist/mcp/tools/model-update.js +46 -26
- package/dist/mcp/tools/model-update.js.map +2 -2
- package/dist/mcp/tools/model-validate.js +46 -4
- package/dist/mcp/tools/model-validate.js.map +2 -2
- package/dist/mcp/tools/project-status-collectors.js +381 -0
- package/dist/mcp/tools/project-status-collectors.js.map +7 -0
- package/dist/mcp/tools/project-status.js +237 -0
- package/dist/mcp/tools/project-status.js.map +7 -0
- package/dist/mcp/tools/project-tools.js +505 -0
- package/dist/mcp/tools/project-tools.js.map +7 -0
- package/dist/mcp/tools/relationship-tools.js +167 -0
- package/dist/mcp/tools/relationship-tools.js.map +7 -0
- package/dist/mcp/tools/review-open.js +210 -0
- package/dist/mcp/tools/review-open.js.map +7 -0
- package/dist/mcp/tools/shared.js +35 -4
- package/dist/mcp/tools/shared.js.map +2 -2
- package/dist/mcp/tools/spec-type.js +90 -0
- package/dist/mcp/tools/spec-type.js.map +7 -0
- package/dist/reports/model-report-orchestrator.js +31 -2
- package/dist/reports/model-report-orchestrator.js.map +2 -2
- package/dist/schemas/bundled/analyzers/cbm.json +1200 -70
- package/dist/schemas/bundled/analyzers/manifest.json +2 -2
- package/dist/schemas/bundled/api.json +1029 -1658
- package/dist/schemas/bundled/apm.json +499 -734
- package/dist/schemas/bundled/application.json +735 -371
- package/dist/schemas/bundled/base.json +3 -220
- package/dist/schemas/bundled/business.json +452 -366
- package/dist/schemas/bundled/data-model.json +395 -411
- package/dist/schemas/bundled/data-store.json +334 -558
- package/dist/schemas/bundled/manifest.json +18 -18
- package/dist/schemas/bundled/motivation.json +349 -368
- package/dist/schemas/bundled/navigation.json +415 -731
- package/dist/schemas/bundled/product.json +325 -159
- package/dist/schemas/bundled/security.json +864 -1232
- package/dist/schemas/bundled/technology.json +574 -703
- package/dist/schemas/bundled/testing.json +865 -1646
- package/dist/schemas/bundled/ux.json +739 -1352
- package/dist/server/schemas.js +8 -0
- package/dist/server/schemas.js.map +2 -2
- package/dist/server/server.js +686 -231
- package/dist/server/server.js.map +3 -3
- package/dist/server/viewer-registry.js +264 -0
- package/dist/server/viewer-registry.js.map +7 -0
- package/dist/server-entry.js +2 -1
- package/dist/server-entry.js.map +2 -2
- package/dist/telemetry/index.js +1 -1
- package/dist/utils/ansi-suppressor.js +6 -8
- package/dist/utils/ansi-suppressor.js.map +2 -2
- package/dist/utils/attribute-patch.js +41 -0
- package/dist/utils/attribute-patch.js.map +7 -0
- package/dist/utils/error-hints.js +29 -0
- package/dist/utils/error-hints.js.map +7 -0
- package/dist/utils/errors.js +9 -3
- package/dist/utils/errors.js.map +2 -2
- package/dist/utils/id-generator.js +5 -2
- package/dist/utils/id-generator.js.map +2 -2
- package/dist/utils/project-paths.js +26 -1
- package/dist/utils/project-paths.js.map +2 -2
- package/dist/utils/source-reference.js +64 -31
- package/dist/utils/source-reference.js.map +2 -2
- package/dist/utils/spec-version.js +2 -2
- package/dist/utils/spec-version.js.map +1 -1
- package/dist/validators/composed-reference-validator.js +5 -27
- package/dist/validators/composed-reference-validator.js.map +2 -2
- package/dist/validators/model-warnings.js +28 -0
- package/dist/validators/model-warnings.js.map +7 -0
- package/dist/validators/reference-validator.js +0 -7
- package/dist/validators/reference-validator.js.map +2 -2
- package/dist/validators/relationship-schema-validator.js +3 -3
- package/dist/validators/relationship-schema-validator.js.map +2 -2
- package/dist/validators/schema-validator.js +27 -9
- package/dist/validators/schema-validator.js.map +2 -2
- package/dist/validators/types.js.map +1 -1
- package/dist/viewer/README.md +6 -6
- package/dist/viewer/assets/main-CUOQGGRA.css +1 -0
- package/dist/viewer/assets/main-DvH3gYrI.js +84 -0
- package/dist/viewer/index.html +2 -2
- package/dist/viewer/manifest.json +10 -10
- package/dist/viewer/version.json +1 -1
- package/package.json +2 -1
- package/dist/viewer/assets/main-B7AOQXXX.js +0 -81
- package/dist/viewer/assets/main-vdrFrG7q.css +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Option } from "commander";
|
|
1
2
|
import { intro, outro, select, isCancel } from "@clack/prompts";
|
|
2
3
|
import ansis from "ansis";
|
|
3
4
|
import { promises as fs } from "fs";
|
|
@@ -8,7 +9,10 @@ import { readSession, writeSession, writeStatus, readIndexMeta } from "../analyz
|
|
|
8
9
|
import { CLIError, ModelNotFoundError, ErrorCategory, categorizeError } from "../utils/errors.js";
|
|
9
10
|
import { findProjectRoot } from "../utils/project-paths.js";
|
|
10
11
|
import { performDiscover } from "./discover-logic.js";
|
|
12
|
+
import { analyzerHomepage, getAnalyzerBackend, resolveAnalyzerName, splitVerifyLayers } from "../analyzers/active-analyzer.js";
|
|
13
|
+
import { finishIndexJob, INDEX_JOB_TIMEOUT_MS, markIndexJobPhase } from "../analyzers/index-job.js";
|
|
11
14
|
import { formatVerifyReport } from "../export/verify-formatters.js";
|
|
15
|
+
import { Model } from "../core/model.js";
|
|
12
16
|
function analyzerCommands(program) {
|
|
13
17
|
const analyzer = program.command("analyzer").description("Manage analyzer discovery and indexing");
|
|
14
18
|
analyzer.command("discover").description("Discover and select an analyzer").option("--json", "Output as JSON").option("--reselect", "Force re-selection even if analyzer already selected").addHelpText("after", `
|
|
@@ -131,11 +135,16 @@ Examples:
|
|
|
131
135
|
throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND, ["Check the analyzer name with `dr analyzer discover`"]);
|
|
132
136
|
const actualProjectRoot = await findProjectRoot();
|
|
133
137
|
let status;
|
|
134
|
-
if (actualProjectRoot
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
if (actualProjectRoot) {
|
|
139
|
+
const model = await Model.load(actualProjectRoot);
|
|
140
|
+
status = await backend.status(actualProjectRoot, { codebaseRoot: model.codebaseRoot });
|
|
141
|
+
} else
|
|
142
|
+
status = {
|
|
143
|
+
detected: await backend.detect(),
|
|
144
|
+
indexed: !1,
|
|
145
|
+
fresh: !1
|
|
146
|
+
};
|
|
147
|
+
if (jsonMode) {
|
|
139
148
|
console.log(JSON.stringify(status, null, 2)), actualProjectRoot && await writeStatus(status, actualProjectRoot, analyzerName);
|
|
140
149
|
return;
|
|
141
150
|
}
|
|
@@ -146,39 +155,43 @@ Examples:
|
|
|
146
155
|
const category = categorizeError(error), cliError = new CLIError(error instanceof Error ? error.message : String(error), category);
|
|
147
156
|
throw error instanceof Error && (cliError.cause = error), cliError;
|
|
148
157
|
}
|
|
149
|
-
}), analyzer.command("index").description("Index the current project with the analyzer").option("--name <n>", "Analyzer name (defaults to active from session.json)").option("--force", "Force re-indexing even if index is fresh").addHelpText("after", `
|
|
158
|
+
}), analyzer.command("index").description("Index the current project with the analyzer").option("--name <n>", "Analyzer name (defaults to active from session.json)").option("--force", "Force re-indexing even if index is fresh").addOption(new Option("--job <id>", "Record the run in .dr/analyzers/index-job.json (set by codebase_index)").hideHelp()).addHelpText("after", `
|
|
150
159
|
Examples:
|
|
151
160
|
$ dr analyzer index # Index with active analyzer
|
|
152
161
|
$ dr analyzer index --force # Force re-index
|
|
153
|
-
$ dr analyzer index --name cbm # Index with specific analyzer
|
|
162
|
+
$ dr analyzer index --name cbm # Index with specific analyzer
|
|
163
|
+
|
|
164
|
+
With codebase-memory-mcp (cbm), each run first adds /documentation-robotics/ and /.dr/ to a
|
|
165
|
+
.cbmignore at the codebase root (creating it if needed, keeping your lines, and leaving alone a
|
|
166
|
+
folder you negate with !), so DR's model, changesets and analyzer state stay out of the index.
|
|
167
|
+
Commit .cbmignore with the code.`).action(async (options) => {
|
|
168
|
+
const jobId = options.job;
|
|
169
|
+
let projectRoot = null;
|
|
154
170
|
try {
|
|
155
|
-
|
|
156
|
-
if (!projectRoot)
|
|
171
|
+
if (projectRoot = await findProjectRoot(), !projectRoot)
|
|
157
172
|
throw new ModelNotFoundError();
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (!session)
|
|
162
|
-
throw new CLIError("No analyzer selected. Run `dr analyzer discover` first.", ErrorCategory.USER);
|
|
163
|
-
analyzerName = session.active_analyzer;
|
|
164
|
-
}
|
|
165
|
-
const registry = AnalyzerRegistry.getInstance();
|
|
166
|
-
await registry.initialize();
|
|
167
|
-
const backend = await registry.getAnalyzer(analyzerName);
|
|
168
|
-
if (!backend)
|
|
169
|
-
throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND, ["Check the analyzer name with `dr analyzer discover`"]);
|
|
173
|
+
const analyzerName = await resolveAnalyzerName(projectRoot, options.name), backend = await getAnalyzerBackend(analyzerName, [
|
|
174
|
+
"Check the analyzer name with `dr analyzer discover`"
|
|
175
|
+
]);
|
|
170
176
|
if (!(await backend.detect()).installed) {
|
|
171
|
-
const homepageUrl =
|
|
177
|
+
const homepageUrl = await analyzerHomepage(analyzerName);
|
|
172
178
|
throw new CLIError(`Analyzer not installed: ${analyzerName}`, ErrorCategory.USER, [
|
|
173
179
|
"Run `dr analyzer discover` to find available analyzers and installation instructions",
|
|
174
180
|
`Visit: ${homepageUrl}`
|
|
175
181
|
]);
|
|
176
182
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
183
|
+
const model = await Model.load(projectRoot);
|
|
184
|
+
jobId && await markIndexJobPhase(projectRoot, jobId, "indexing"), console.log(`Indexing project with ${analyzerName}...`);
|
|
185
|
+
const result = await backend.index(projectRoot, {
|
|
186
|
+
force: options.force,
|
|
187
|
+
codebaseRoot: model.codebaseRoot,
|
|
188
|
+
// A background run has no caller waiting on it: give a large codebase the time it needs.
|
|
189
|
+
...jobId ? { timeoutMs: INDEX_JOB_TIMEOUT_MS } : {}
|
|
190
|
+
});
|
|
191
|
+
jobId && await finishIndexJob(projectRoot, jobId, { result }), console.log(ansis.green("\u2713 Indexing complete")), console.log(` Nodes: ${result.node_count}`), console.log(` Edges: ${result.edge_count}`), console.log(` Git HEAD: ${result.git_head}`);
|
|
180
192
|
} catch (error) {
|
|
181
|
-
if (
|
|
193
|
+
if (jobId && await finishIndexJob(projectRoot ?? process.cwd(), jobId, { error: describeJobError(error) }).catch(() => {
|
|
194
|
+
}), error instanceof CLIError || error instanceof ModelNotFoundError)
|
|
182
195
|
throw error;
|
|
183
196
|
const cliError = new CLIError(error instanceof Error ? error.message : String(error), ErrorCategory.SYSTEM);
|
|
184
197
|
throw error instanceof Error && (cliError.cause = error), cliError;
|
|
@@ -205,9 +218,10 @@ Examples:
|
|
|
205
218
|
const backend = await registry.getAnalyzer(analyzerName);
|
|
206
219
|
if (!backend)
|
|
207
220
|
throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND);
|
|
208
|
-
|
|
221
|
+
const model = await Model.load(projectRoot);
|
|
222
|
+
if (!(await backend.status(projectRoot, { codebaseRoot: model.codebaseRoot })).indexed)
|
|
209
223
|
throw new CLIError("Project not indexed", ErrorCategory.USER, ["Run `dr analyzer index` to index the project first"]);
|
|
210
|
-
const endpoints = await backend.endpoints(projectRoot);
|
|
224
|
+
const endpoints = await backend.endpoints(projectRoot, { codebaseRoot: model.codebaseRoot });
|
|
211
225
|
if (jsonMode) {
|
|
212
226
|
console.log(JSON.stringify(endpoints, null, 2));
|
|
213
227
|
return;
|
|
@@ -252,9 +266,10 @@ Examples:
|
|
|
252
266
|
const backend = await registry.getAnalyzer(analyzerName);
|
|
253
267
|
if (!backend)
|
|
254
268
|
throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND);
|
|
269
|
+
const model = await Model.load(projectRoot);
|
|
255
270
|
if (!await readIndexMeta(projectRoot, analyzerName))
|
|
256
271
|
throw new CLIError("Project not indexed", ErrorCategory.USER, ["Run `dr analyzer index` first"]);
|
|
257
|
-
let services = await backend.services(projectRoot);
|
|
272
|
+
let services = await backend.services(projectRoot, { codebaseRoot: model.codebaseRoot });
|
|
258
273
|
if (options.layer && (services = services.filter((s) => s.suggested_layer === options.layer)), jsonMode) {
|
|
259
274
|
console.log(JSON.stringify(services, null, 2));
|
|
260
275
|
return;
|
|
@@ -298,9 +313,10 @@ Examples:
|
|
|
298
313
|
const backend = await registry.getAnalyzer(analyzerName);
|
|
299
314
|
if (!backend)
|
|
300
315
|
throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND);
|
|
316
|
+
const model = await Model.load(projectRoot);
|
|
301
317
|
if (!await readIndexMeta(projectRoot, analyzerName))
|
|
302
318
|
throw new CLIError("Project not indexed", ErrorCategory.USER, ["Run `dr analyzer index` first"]);
|
|
303
|
-
const datastores = await backend.datastores(projectRoot);
|
|
319
|
+
const datastores = await backend.datastores(projectRoot, { codebaseRoot: model.codebaseRoot });
|
|
304
320
|
if (jsonMode) {
|
|
305
321
|
console.log(JSON.stringify(datastores, null, 2));
|
|
306
322
|
return;
|
|
@@ -348,9 +364,10 @@ Examples:
|
|
|
348
364
|
const backend = await registry.getAnalyzer(analyzerName);
|
|
349
365
|
if (!backend)
|
|
350
366
|
throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND);
|
|
367
|
+
const model = await Model.load(projectRoot);
|
|
351
368
|
if (!await readIndexMeta(projectRoot, analyzerName))
|
|
352
369
|
throw new CLIError("Project not indexed", ErrorCategory.USER, ["Run `dr analyzer index` first"]);
|
|
353
|
-
const callers = await backend.callers(projectRoot, qualifiedName, depth);
|
|
370
|
+
const callers = await backend.callers(projectRoot, qualifiedName, depth, { codebaseRoot: model.codebaseRoot });
|
|
354
371
|
if (jsonMode) {
|
|
355
372
|
console.log(JSON.stringify(callers, null, 2));
|
|
356
373
|
return;
|
|
@@ -394,9 +411,10 @@ Examples:
|
|
|
394
411
|
const backend = await registry.getAnalyzer(analyzerName);
|
|
395
412
|
if (!backend)
|
|
396
413
|
throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND);
|
|
414
|
+
const model = await Model.load(projectRoot);
|
|
397
415
|
if (!await readIndexMeta(projectRoot, analyzerName))
|
|
398
416
|
throw new CLIError("Project not indexed", ErrorCategory.USER, ["Run `dr analyzer index` first"]);
|
|
399
|
-
const callees = await backend.callees(projectRoot, qualifiedName, depth);
|
|
417
|
+
const callees = await backend.callees(projectRoot, qualifiedName, depth, { codebaseRoot: model.codebaseRoot });
|
|
400
418
|
if (jsonMode) {
|
|
401
419
|
console.log(JSON.stringify(callees, null, 2));
|
|
402
420
|
return;
|
|
@@ -441,9 +459,10 @@ Examples:
|
|
|
441
459
|
const backend = await registry.getAnalyzer(analyzerName);
|
|
442
460
|
if (!backend)
|
|
443
461
|
throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND);
|
|
462
|
+
const model = await Model.load(projectRoot);
|
|
444
463
|
if (!await readIndexMeta(projectRoot, analyzerName))
|
|
445
464
|
throw new CLIError("Project not indexed", ErrorCategory.USER, ["Run `dr analyzer index` first"]);
|
|
446
|
-
const result = await backend.query(projectRoot, cypher);
|
|
465
|
+
const result = await backend.query(projectRoot, cypher, { codebaseRoot: model.codebaseRoot });
|
|
447
466
|
options.json, console.log(JSON.stringify(result, null, 2));
|
|
448
467
|
} catch (error) {
|
|
449
468
|
if (error instanceof CLIError || error instanceof ModelNotFoundError)
|
|
@@ -476,11 +495,61 @@ Examples:
|
|
|
476
495
|
const projectRoot = await findProjectRoot();
|
|
477
496
|
if (!projectRoot)
|
|
478
497
|
throw new ModelNotFoundError();
|
|
479
|
-
const
|
|
498
|
+
const { verifiable: apiLayers, unsupported: nonApiLayers } = splitVerifyLayers(options.layer);
|
|
480
499
|
for (const layer of nonApiLayers)
|
|
481
500
|
console.log(ansis.dim(`No verification available for layer '${layer}'`));
|
|
482
501
|
if (apiLayers.length === 0)
|
|
483
502
|
return;
|
|
503
|
+
const analyzerName = await resolveAnalyzerName(projectRoot, options.name), backend = await getAnalyzerBackend(analyzerName), model = await Model.load(projectRoot);
|
|
504
|
+
if (!await readIndexMeta(projectRoot, analyzerName))
|
|
505
|
+
throw new CLIError("Project not indexed", ErrorCategory.USER, ["Run `dr analyzer index` first"]);
|
|
506
|
+
const report = await backend.verify(projectRoot, {
|
|
507
|
+
layers: apiLayers,
|
|
508
|
+
changesetAware: !0,
|
|
509
|
+
codebaseRoot: model.codebaseRoot
|
|
510
|
+
}), formatted = formatVerifyReport(report, { format });
|
|
511
|
+
if (options.output) {
|
|
512
|
+
const outputPath = path.resolve(options.output);
|
|
513
|
+
await fs.writeFile(outputPath, formatted, "utf-8"), console.log(ansis.green(`\u2713 Report written to ${outputPath}`));
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
console.log(formatted);
|
|
517
|
+
} catch (error) {
|
|
518
|
+
if (error instanceof CLIError || error instanceof ModelNotFoundError)
|
|
519
|
+
throw error;
|
|
520
|
+
const cliError = new CLIError(error instanceof Error ? error.message : String(error), categorizeError(error));
|
|
521
|
+
throw error instanceof Error && (cliError.cause = error), cliError;
|
|
522
|
+
}
|
|
523
|
+
}), analyzer.command("classify").description("Classify the indexed project's symbols into model layers and types (Tier 0: rules only)").option("--name <n>", "Analyzer name (defaults to active from session.json)").option("--tier0-only", "Apply only the analyzer's Tier-0 rules: no model calls, no network (required for now)").option("--label <labels>", "Comma-separated analyzer labels to classify (default: Class, Interface, Function, Method, Module, Route and every label a rule names)").option("--file <glob>", "Only symbols in files matching this glob").option("--exclude <regex>", "Also leave out files matching this regular expression (build and vendored paths always are)").option("--limit <n>", "Stop after this many symbols").option("--cards", "Include each symbol's full card (source and graph neighbourhood) in JSON output").option("--output <file>", "Write the JSON report to a file").option("--json", "Output as JSON").addHelpText("after", `
|
|
524
|
+
Tier 0 is the first step of the classification cascade (docs/analyzers/CASCADE_DESIGN.md):
|
|
525
|
+
the analyzer's rules decide a symbol's layer and type, reject it as not a model element,
|
|
526
|
+
or narrow its choices for a later tier. Symbols no rule covers are reported as undecided.
|
|
527
|
+
Nothing is written to the model.
|
|
528
|
+
|
|
529
|
+
Examples:
|
|
530
|
+
$ dr analyzer classify --tier0-only
|
|
531
|
+
$ dr analyzer classify --tier0-only --json > tier0.json
|
|
532
|
+
$ dr analyzer classify --tier0-only --label Class,Method --file "src/main/**"
|
|
533
|
+
$ dr analyzer classify --tier0-only --cards --output tier0-cards.json`).action(async (options) => {
|
|
534
|
+
const jsonMode = options.json ?? program.opts().json;
|
|
535
|
+
try {
|
|
536
|
+
if (!options.tier0Only)
|
|
537
|
+
throw new CLIError("Only Tier-0 classification is available so far: pass --tier0-only", ErrorCategory.USER, ["Model-backed classification (Tier 1) needs the per-project opt-in and is not built yet"]);
|
|
538
|
+
let exclude;
|
|
539
|
+
if (options.exclude !== void 0)
|
|
540
|
+
try {
|
|
541
|
+
exclude = new RegExp(String(options.exclude));
|
|
542
|
+
} catch (e) {
|
|
543
|
+
throw new CLIError(`Invalid --exclude regular expression: ${e instanceof Error ? e.message : String(e)}`, ErrorCategory.USER);
|
|
544
|
+
}
|
|
545
|
+
let limit;
|
|
546
|
+
if (options.limit !== void 0 && (limit = Number(options.limit), !Number.isInteger(limit) || limit < 1))
|
|
547
|
+
throw new CLIError(`--limit must be a positive integer, got '${options.limit}'`, ErrorCategory.USER);
|
|
548
|
+
const labels = options.label ? String(options.label).split(",").map((l) => l.trim()).filter(Boolean) : void 0;
|
|
549
|
+
options.cards && !jsonMode && !options.output && console.error(ansis.yellow("--cards only affects JSON output: add --json or --output <file>"));
|
|
550
|
+
const projectRoot = await findProjectRoot();
|
|
551
|
+
if (!projectRoot)
|
|
552
|
+
throw new ModelNotFoundError();
|
|
484
553
|
let analyzerName = options.name;
|
|
485
554
|
if (!analyzerName) {
|
|
486
555
|
const session = await readSession(projectRoot);
|
|
@@ -493,18 +562,46 @@ Examples:
|
|
|
493
562
|
const backend = await registry.getAnalyzer(analyzerName);
|
|
494
563
|
if (!backend)
|
|
495
564
|
throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND);
|
|
565
|
+
if (!backend.classify)
|
|
566
|
+
throw new CLIError(`The ${analyzerName} analyzer does not support classification`, ErrorCategory.USER);
|
|
496
567
|
if (!await readIndexMeta(projectRoot, analyzerName))
|
|
497
568
|
throw new CLIError("Project not indexed", ErrorCategory.USER, ["Run `dr analyzer index` first"]);
|
|
498
|
-
const report = await backend.
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
569
|
+
const model = await Model.load(projectRoot), showProgress = !jsonMode && !options.output && process.stderr.isTTY, report = await backend.classify(projectRoot, {
|
|
570
|
+
codebaseRoot: model.codebaseRoot,
|
|
571
|
+
labels,
|
|
572
|
+
filePattern: options.file,
|
|
573
|
+
exclude,
|
|
574
|
+
limit,
|
|
575
|
+
includeCards: !!options.cards,
|
|
576
|
+
onProgress: showProgress ? (done, total) => {
|
|
577
|
+
(done % 50 === 0 || done === total) && process.stderr.write(`\r ${done}/${total} symbols`), done === total && process.stderr.write(`
|
|
578
|
+
`);
|
|
579
|
+
} : void 0
|
|
580
|
+
});
|
|
502
581
|
if (options.output) {
|
|
503
582
|
const outputPath = path.resolve(options.output);
|
|
504
|
-
await fs.writeFile(outputPath,
|
|
583
|
+
await fs.writeFile(outputPath, JSON.stringify(report, null, 2) + `
|
|
584
|
+
`, "utf-8"), jsonMode || console.log(ansis.green(`\u2713 Report written to ${outputPath}`));
|
|
585
|
+
}
|
|
586
|
+
if (jsonMode) {
|
|
587
|
+
console.log(JSON.stringify(report, null, 2));
|
|
505
588
|
return;
|
|
506
589
|
}
|
|
507
|
-
|
|
590
|
+
const { summary } = report, pct = (n) => summary.cards ? `${(100 * n / summary.cards).toFixed(0)}%` : "0%";
|
|
591
|
+
console.log(""), console.log(ansis.bold(`Tier-0 classification: ${summary.cards} symbols, ${report.rules} rules`)), console.log(ansis.dim("\u2500".repeat(60))), console.log(` ${ansis.green("decided")} ${String(summary.decided).padStart(6)} ${pct(summary.decided)}`), console.log(` ${ansis.yellow("rejected")} ${String(summary.rejected).padStart(6)} ${pct(summary.rejected)} (not model elements)`), console.log(` ${ansis.cyan("narrowed")} ${String(summary.narrowed).padStart(6)} ${pct(summary.narrowed)} (choices restricted for Tier 1)`), console.log(` ${ansis.dim("undecided")} ${String(summary.undecided).padStart(6)} ${pct(summary.undecided)}`), summary.no_source && console.log(ansis.yellow(` ${summary.no_source} symbol(s) had no source, so rules that read the declaration could not apply`));
|
|
592
|
+
const targets = Object.entries(summary.by_target).sort((a, b) => b[1] - a[1]);
|
|
593
|
+
if (targets.length) {
|
|
594
|
+
console.log(""), console.log(ansis.bold("Decided, by type:"));
|
|
595
|
+
for (const [target, n] of targets)
|
|
596
|
+
console.log(` ${target.padEnd(40)} ${String(n).padStart(6)}`);
|
|
597
|
+
}
|
|
598
|
+
const rules = Object.entries(summary.by_rule).sort((a, b) => b[1] - a[1]);
|
|
599
|
+
if (rules.length) {
|
|
600
|
+
console.log(""), console.log(ansis.bold("Matches, by rule:"));
|
|
601
|
+
for (const [rule, n] of rules)
|
|
602
|
+
console.log(` ${rule.padEnd(40)} ${String(n).padStart(6)}`);
|
|
603
|
+
}
|
|
604
|
+
console.log(ansis.dim("\u2500".repeat(60))), console.log(ansis.dim("Per-symbol outcomes: --json or --output <file>")), console.log("");
|
|
508
605
|
} catch (error) {
|
|
509
606
|
if (error instanceof CLIError || error instanceof ModelNotFoundError)
|
|
510
607
|
throw error;
|
|
@@ -513,6 +610,12 @@ Examples:
|
|
|
513
610
|
}
|
|
514
611
|
});
|
|
515
612
|
}
|
|
613
|
+
function describeJobError(error) {
|
|
614
|
+
const message = error instanceof Error ? error.message : String(error), suggestions = error instanceof CLIError ? error.suggestions ?? [] : [];
|
|
615
|
+
return suggestions.length > 0 ? `${message}
|
|
616
|
+
${suggestions.map((s) => `- ${s}`).join(`
|
|
617
|
+
`)}` : message;
|
|
618
|
+
}
|
|
516
619
|
export {
|
|
517
620
|
analyzerCommands
|
|
518
621
|
};
|