@documentation-robotics/cli 0.1.0 → 0.1.5
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/LICENSE +21 -0
- package/README.md +466 -693
- package/dist/analysis/data-model-analyzer.js +189 -0
- package/dist/analysis/data-model-analyzer.js.map +7 -0
- package/dist/analysis/index.js +3 -0
- package/dist/analysis/index.js.map +7 -0
- package/dist/analysis/relationship-classifier.js +181 -0
- package/dist/analysis/relationship-classifier.js.map +7 -0
- package/dist/analyzers/base-analyzer.js +1 -0
- package/dist/analyzers/base-analyzer.js.map +7 -0
- package/dist/analyzers/call-graph-utils.js +39 -0
- package/dist/analyzers/call-graph-utils.js.map +7 -0
- package/dist/analyzers/cbm-analyzer.js +1205 -0
- package/dist/analyzers/cbm-analyzer.js.map +7 -0
- package/dist/analyzers/heuristic-utils.js +55 -0
- package/dist/analyzers/heuristic-utils.js.map +7 -0
- package/dist/analyzers/mapping-loader.js +146 -0
- package/dist/analyzers/mapping-loader.js.map +7 -0
- package/dist/analyzers/registry.js +124 -0
- package/dist/analyzers/registry.js.map +7 -0
- package/dist/analyzers/session-state.js +176 -0
- package/dist/analyzers/session-state.js.map +7 -0
- package/dist/analyzers/stdio-client.js +206 -0
- package/dist/analyzers/stdio-client.js.map +7 -0
- package/dist/analyzers/types.js +15 -0
- package/dist/analyzers/types.js.map +7 -0
- package/dist/analyzers/verify-engine.js +209 -0
- package/dist/analyzers/verify-engine.js.map +7 -0
- package/dist/analyzers/verify-ignore.js +130 -0
- package/dist/analyzers/verify-ignore.js.map +7 -0
- package/dist/analyzers/version.js +8 -0
- package/dist/analyzers/version.js.map +7 -0
- package/dist/audit/ai/runner.js +41 -0
- package/dist/audit/ai/runner.js.map +7 -0
- package/dist/audit/differential-analyzer.js +183 -0
- package/dist/audit/differential-analyzer.js.map +7 -0
- package/dist/audit/index.js +32 -0
- package/dist/audit/index.js.map +7 -0
- package/dist/audit/nodes/ai/evaluator.js +49 -0
- package/dist/audit/nodes/ai/evaluator.js.map +7 -0
- package/dist/audit/nodes/ai/parser.js +55 -0
- package/dist/audit/nodes/ai/parser.js.map +7 -0
- package/dist/audit/nodes/ai/prompts.js +103 -0
- package/dist/audit/nodes/ai/prompts.js.map +7 -0
- package/dist/audit/nodes/analysis/node-completeness-checker.js +32 -0
- package/dist/audit/nodes/analysis/node-completeness-checker.js.map +7 -0
- package/dist/audit/nodes/analysis/node-definition-analyzer.js +47 -0
- package/dist/audit/nodes/analysis/node-definition-analyzer.js.map +7 -0
- package/dist/audit/nodes/analysis/node-overlap-detector.js +79 -0
- package/dist/audit/nodes/analysis/node-overlap-detector.js.map +7 -0
- package/dist/audit/nodes/model/orchestrator.js +82 -0
- package/dist/audit/nodes/model/orchestrator.js.map +7 -0
- package/dist/audit/nodes/spec/loader.js +116 -0
- package/dist/audit/nodes/spec/loader.js.map +7 -0
- package/dist/audit/nodes/spec/orchestrator.js +68 -0
- package/dist/audit/nodes/spec/orchestrator.js.map +7 -0
- package/dist/audit/nodes/types.js +1 -0
- package/dist/audit/nodes/types.js.map +7 -0
- package/dist/audit/pipeline/index.js +5 -0
- package/dist/audit/pipeline/index.js.map +7 -0
- package/dist/audit/pipeline/pipeline-orchestrator.js +218 -0
- package/dist/audit/pipeline/pipeline-orchestrator.js.map +7 -0
- package/dist/audit/relationships/ai/evaluator.js +235 -0
- package/dist/audit/relationships/ai/evaluator.js.map +7 -0
- package/dist/audit/relationships/ai/parser.js +197 -0
- package/dist/audit/relationships/ai/parser.js.map +7 -0
- package/dist/audit/relationships/ai/prompts.js +274 -0
- package/dist/audit/relationships/ai/prompts.js.map +7 -0
- package/dist/audit/relationships/analysis/balance-assessor.js +115 -0
- package/dist/audit/relationships/analysis/balance-assessor.js.map +7 -0
- package/dist/audit/relationships/analysis/coverage-analyzer.js +99 -0
- package/dist/audit/relationships/analysis/coverage-analyzer.js.map +7 -0
- package/dist/audit/relationships/analysis/duplicate-detector.js +95 -0
- package/dist/audit/relationships/analysis/duplicate-detector.js.map +7 -0
- package/dist/audit/relationships/analysis/gap-analyzer.js +99 -0
- package/dist/audit/relationships/analysis/gap-analyzer.js.map +7 -0
- package/dist/audit/relationships/analysis/layer-templates.js +294 -0
- package/dist/audit/relationships/analysis/layer-templates.js.map +7 -0
- package/dist/audit/relationships/graph/connectivity.js +129 -0
- package/dist/audit/relationships/graph/connectivity.js.map +7 -0
- package/dist/audit/relationships/graph/relationship-graph.js +179 -0
- package/dist/audit/relationships/graph/relationship-graph.js.map +7 -0
- package/dist/audit/relationships/model/balance-assessor.js +49 -0
- package/dist/audit/relationships/model/balance-assessor.js.map +7 -0
- package/dist/audit/relationships/model/coverage-analyzer.js +34 -0
- package/dist/audit/relationships/model/coverage-analyzer.js.map +7 -0
- package/dist/audit/relationships/model/duplicate-detector.js +68 -0
- package/dist/audit/relationships/model/duplicate-detector.js.map +7 -0
- package/dist/audit/relationships/model/gap-analyzer.js +41 -0
- package/dist/audit/relationships/model/gap-analyzer.js.map +7 -0
- package/dist/audit/relationships/model/orchestrator.js +126 -0
- package/dist/audit/relationships/model/orchestrator.js.map +7 -0
- package/dist/audit/relationships/spec/orchestrator.js +157 -0
- package/dist/audit/relationships/spec/orchestrator.js.map +7 -0
- package/dist/audit/reports/index.js +5 -0
- package/dist/audit/reports/index.js.map +7 -0
- package/dist/audit/reports/report-generator.js +118 -0
- package/dist/audit/reports/report-generator.js.map +7 -0
- package/dist/audit/snapshot-storage.js +163 -0
- package/dist/audit/snapshot-storage.js.map +7 -0
- package/dist/audit/types.js +21 -0
- package/dist/audit/types.js.map +7 -0
- package/dist/cli.js +223 -92
- package/dist/cli.js.map +3 -3
- package/dist/coding-agents/agents/claude-code.js +147 -0
- package/dist/coding-agents/agents/claude-code.js.map +7 -0
- package/dist/coding-agents/agents/index.js +5 -0
- package/dist/coding-agents/agents/index.js.map +7 -0
- package/dist/coding-agents/agents/types.js +1 -0
- package/dist/coding-agents/agents/types.js.map +7 -0
- package/dist/coding-agents/base-chat-client.js +45 -0
- package/dist/coding-agents/base-chat-client.js.map +7 -0
- package/dist/coding-agents/chat-utils.js +23 -0
- package/dist/coding-agents/chat-utils.js.map +7 -0
- package/dist/coding-agents/claude-code-client.js +246 -0
- package/dist/coding-agents/claude-code-client.js.map +7 -0
- package/dist/coding-agents/copilot-client.js +209 -0
- package/dist/coding-agents/copilot-client.js.map +7 -0
- package/dist/commands/add.js +95 -33
- package/dist/commands/add.js.map +2 -2
- package/dist/commands/analyzer.js +511 -0
- package/dist/commands/analyzer.js.map +7 -0
- package/dist/commands/audit-diff.js +49 -0
- package/dist/commands/audit-diff.js.map +7 -0
- package/dist/commands/audit-snapshots.js +62 -0
- package/dist/commands/audit-snapshots.js.map +7 -0
- package/dist/commands/audit.js +81 -0
- package/dist/commands/audit.js.map +7 -0
- package/dist/commands/catalog.js +248 -0
- package/dist/commands/catalog.js.map +7 -0
- package/dist/commands/changeset.js +577 -66
- package/dist/commands/changeset.js.map +2 -2
- package/dist/commands/chat.js +106 -83
- package/dist/commands/chat.js.map +2 -2
- package/dist/commands/claude.js +74 -0
- package/dist/commands/claude.js.map +7 -0
- package/dist/commands/conformance.js +71 -68
- package/dist/commands/conformance.js.map +2 -2
- package/dist/commands/copilot.js +75 -0
- package/dist/commands/copilot.js.map +7 -0
- package/dist/commands/delete.js +125 -11
- package/dist/commands/delete.js.map +3 -3
- package/dist/commands/discover-logic.js +44 -0
- package/dist/commands/discover-logic.js.map +7 -0
- package/dist/commands/docs.js +87 -0
- package/dist/commands/docs.js.map +7 -0
- package/dist/commands/element.js +14 -20
- package/dist/commands/element.js.map +2 -2
- package/dist/commands/export.js +13 -3
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/import.js +51 -0
- package/dist/commands/import.js.map +7 -0
- package/dist/commands/info.js +30 -24
- package/dist/commands/info.js.map +2 -2
- package/dist/commands/init.js +27 -11
- package/dist/commands/init.js.map +2 -2
- package/dist/commands/list.js +63 -13
- package/dist/commands/list.js.map +3 -3
- package/dist/commands/relationship.js +225 -37
- package/dist/commands/relationship.js.map +2 -2
- package/dist/commands/report.js +54 -0
- package/dist/commands/report.js.map +7 -0
- package/dist/commands/reports.js +45 -0
- package/dist/commands/reports.js.map +7 -0
- package/dist/commands/schema.js +135 -0
- package/dist/commands/schema.js.map +7 -0
- package/dist/commands/search.js +40 -12
- package/dist/commands/search.js.map +2 -2
- package/dist/commands/show.js +58 -27
- package/dist/commands/show.js.map +2 -2
- package/dist/commands/stats.js +35 -0
- package/dist/commands/stats.js.map +7 -0
- package/dist/commands/trace.js +39 -16
- package/dist/commands/trace.js.map +2 -2
- package/dist/commands/update.js +141 -14
- package/dist/commands/update.js.map +2 -2
- package/dist/commands/upgrade.js +210 -46
- package/dist/commands/upgrade.js.map +3 -3
- package/dist/commands/validate.js +142 -23
- package/dist/commands/validate.js.map +3 -3
- package/dist/commands/version.js +8 -12
- package/dist/commands/version.js.map +2 -2
- package/dist/commands/visualize.js +155 -25
- package/dist/commands/visualize.js.map +2 -2
- package/dist/core/base-snapshot-manager.js +84 -0
- package/dist/core/base-snapshot-manager.js.map +7 -0
- package/dist/core/changeset-exporter.js +305 -0
- package/dist/core/changeset-exporter.js.map +7 -0
- package/dist/core/changeset-validator.js +41 -0
- package/dist/core/changeset-validator.js.map +7 -0
- package/dist/core/changeset.js +88 -173
- package/dist/core/changeset.js.map +2 -2
- package/dist/core/dependency-tracker.js +4 -2
- package/dist/core/dependency-tracker.js.map +2 -2
- package/dist/core/element.js +98 -27
- package/dist/core/element.js.map +2 -2
- package/dist/core/golden-copy-cache.js +290 -0
- package/dist/core/golden-copy-cache.js.map +7 -0
- package/dist/core/graph-model.js +266 -0
- package/dist/core/graph-model.js.map +7 -0
- package/dist/core/layer.js +159 -16
- package/dist/core/layer.js.map +2 -2
- package/dist/core/layers.js +32 -0
- package/dist/core/layers.js.map +7 -0
- package/dist/core/manifest.js +32 -11
- package/dist/core/manifest.js.map +2 -2
- package/dist/core/migration-registry.js +56 -1
- package/dist/core/migration-registry.js.map +2 -2
- package/dist/core/model.js +424 -217
- package/dist/core/model.js.map +3 -3
- package/dist/core/mutation-handler.js +179 -0
- package/dist/core/mutation-handler.js.map +7 -0
- package/dist/core/reference-registry.js +29 -21
- package/dist/core/reference-registry.js.map +2 -2
- package/dist/core/relationship-catalog.js +189 -0
- package/dist/core/relationship-catalog.js.map +7 -0
- package/dist/core/relationship-registry.js.map +2 -2
- package/dist/core/relationships.js.map +1 -1
- package/dist/core/report-data-model.js +285 -0
- package/dist/core/report-data-model.js.map +7 -0
- package/dist/core/spec-data-service.js +185 -0
- package/dist/core/spec-data-service.js.map +7 -0
- package/dist/core/spec-loader-types.js +1 -0
- package/dist/core/spec-loader-types.js.map +7 -0
- package/dist/core/spec-loader.js +234 -0
- package/dist/core/spec-loader.js.map +7 -0
- package/dist/core/staged-changeset-storage.js +282 -0
- package/dist/core/staged-changeset-storage.js.map +7 -0
- package/dist/core/staging-area.js +1002 -0
- package/dist/core/staging-area.js.map +7 -0
- package/dist/core/stats-collector.js +169 -0
- package/dist/core/stats-collector.js.map +7 -0
- package/dist/core/virtual-projection.js +443 -0
- package/dist/core/virtual-projection.js.map +7 -0
- package/dist/export/archimate-exporter.js +99 -60
- package/dist/export/archimate-exporter.js.map +2 -2
- package/dist/export/audit-formatters.js +479 -0
- package/dist/export/audit-formatters.js.map +7 -0
- package/dist/export/diff-formatters.js +99 -0
- package/dist/export/diff-formatters.js.map +7 -0
- package/dist/export/export-manager.js.map +2 -2
- package/dist/export/graphml-exporter.js +44 -27
- package/dist/export/graphml-exporter.js.map +2 -2
- package/dist/export/index.js +4 -0
- package/dist/export/index.js.map +2 -2
- package/dist/export/json-schema-exporter.js +55 -42
- package/dist/export/json-schema-exporter.js.map +2 -2
- package/dist/export/markdown-exporter.js +92 -70
- package/dist/export/markdown-exporter.js.map +2 -2
- package/dist/export/markdown-generator.js +248 -0
- package/dist/export/markdown-generator.js.map +7 -0
- package/dist/export/markdown-utils.js +30 -0
- package/dist/export/markdown-utils.js.map +7 -0
- package/dist/export/mermaid-markdown-exporter.js +37 -0
- package/dist/export/mermaid-markdown-exporter.js.map +7 -0
- package/dist/export/openapi-exporter.js +119 -71
- package/dist/export/openapi-exporter.js.map +2 -2
- package/dist/export/plantuml-exporter.js +104 -39
- package/dist/export/plantuml-exporter.js.map +2 -2
- package/dist/export/report-formatters.js +111 -0
- package/dist/export/report-formatters.js.map +7 -0
- package/dist/export/stats-formatters.js +98 -0
- package/dist/export/stats-formatters.js.map +7 -0
- package/dist/export/types.js +2 -14
- package/dist/export/types.js.map +2 -2
- package/dist/export/verify-formatters.js +153 -0
- package/dist/export/verify-formatters.js.map +7 -0
- package/dist/generated/compiled-validators.js +17 -0
- package/dist/generated/compiled-validators.js.map +7 -0
- package/dist/generated/index.js +31 -0
- package/dist/generated/index.js.map +7 -0
- package/dist/generated/layer-registry.js +190 -0
- package/dist/generated/layer-registry.js.map +7 -0
- package/dist/generated/layer-types.js +7 -0
- package/dist/generated/layer-types.js.map +7 -0
- package/dist/generated/node-types.js +1719 -0
- package/dist/generated/node-types.js.map +7 -0
- package/dist/generated/relationship-index.js +14552 -0
- package/dist/generated/relationship-index.js.map +7 -0
- package/dist/import/archimate-importer.js +166 -0
- package/dist/import/archimate-importer.js.map +7 -0
- package/dist/import/index.js +47 -0
- package/dist/import/index.js.map +7 -0
- package/dist/import/openapi-importer.js +143 -0
- package/dist/import/openapi-importer.js.map +7 -0
- package/dist/import/types.js +1 -0
- package/dist/import/types.js.map +7 -0
- package/dist/integrations/base-manager.js +311 -0
- package/dist/integrations/base-manager.js.map +7 -0
- package/dist/integrations/claude-manager.js +360 -0
- package/dist/integrations/claude-manager.js.map +7 -0
- package/dist/integrations/claude_code/agents/dr-advisor.md +253 -0
- package/dist/integrations/claude_code/agents/dr-architect.md +278 -0
- package/dist/integrations/claude_code/agents/dr-extractor.md +286 -0
- package/dist/integrations/claude_code/commands/dr-changeset.md +657 -0
- package/dist/integrations/claude_code/commands/dr-design.md +373 -0
- package/dist/integrations/claude_code/commands/dr-info.md +132 -0
- package/dist/integrations/claude_code/commands/dr-init.md +251 -0
- package/dist/integrations/claude_code/commands/dr-map.md +936 -0
- package/dist/integrations/claude_code/commands/dr-model.md +493 -0
- package/dist/integrations/claude_code/commands/dr-relate.md +814 -0
- package/dist/integrations/claude_code/commands/dr-sync.md +279 -0
- package/dist/integrations/claude_code/commands/dr-validate.md +654 -0
- package/dist/integrations/claude_code/commands/dr-verify.md +559 -0
- package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +903 -0
- package/dist/integrations/claude_code/docs/QUICK_START.md +271 -0
- package/dist/integrations/claude_code/docs/README.md +347 -0
- package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +550 -0
- package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +620 -0
- package/dist/integrations/claude_code/skills/dr_03_security_layer/SKILL.md +642 -0
- package/dist/integrations/claude_code/skills/dr_04_application_layer/SKILL.md +911 -0
- package/dist/integrations/claude_code/skills/dr_05_technology_layer/SKILL.md +836 -0
- package/dist/integrations/claude_code/skills/dr_06_api_layer/SKILL.md +933 -0
- package/dist/integrations/claude_code/skills/dr_07_data_model_layer/SKILL.md +210 -0
- package/dist/integrations/claude_code/skills/dr_08_dataset_layer/SKILL.md +319 -0
- package/dist/integrations/claude_code/skills/dr_09_ux_layer/SKILL.md +319 -0
- package/dist/integrations/claude_code/skills/dr_10_navigation_layer/SKILL.md +318 -0
- package/dist/integrations/claude_code/skills/dr_11_apm_layer/SKILL.md +273 -0
- package/dist/integrations/claude_code/skills/dr_12_testing_layer/SKILL.md +273 -0
- package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +187 -0
- package/dist/integrations/claude_code/skills/dr_codebase_memory/SKILL.md +590 -0
- package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +295 -0
- package/dist/integrations/copilot-manager.js +328 -0
- package/dist/integrations/copilot-manager.js.map +7 -0
- package/dist/integrations/github_copilot/agents/dr-advisor.md +243 -0
- package/dist/integrations/github_copilot/agents/dr-architect.md +1567 -0
- package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +491 -0
- package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +539 -0
- package/dist/integrations/github_copilot/skills/dr_03_security_layer/SKILL.md +667 -0
- package/dist/integrations/github_copilot/skills/dr_04_application_layer/SKILL.md +670 -0
- package/dist/integrations/github_copilot/skills/dr_05_technology_layer/SKILL.md +660 -0
- package/dist/integrations/github_copilot/skills/dr_06_api_layer/SKILL.md +855 -0
- package/dist/integrations/github_copilot/skills/dr_07_data_model_layer/SKILL.md +171 -0
- package/dist/integrations/github_copilot/skills/dr_08_dataset_layer/SKILL.md +216 -0
- package/dist/integrations/github_copilot/skills/dr_09_ux_layer/SKILL.md +230 -0
- package/dist/integrations/github_copilot/skills/dr_10_navigation_layer/SKILL.md +228 -0
- package/dist/integrations/github_copilot/skills/dr_11_apm_layer/SKILL.md +234 -0
- package/dist/integrations/github_copilot/skills/dr_12_testing_layer/SKILL.md +230 -0
- package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +187 -0
- package/dist/integrations/hash-utils.js +51 -0
- package/dist/integrations/hash-utils.js.map +7 -0
- package/dist/integrations/types.js +16 -0
- package/dist/integrations/types.js.map +7 -0
- package/dist/reports/model-layer-report-generator.js +278 -0
- package/dist/reports/model-layer-report-generator.js.map +7 -0
- package/dist/reports/model-report-data.js +57 -0
- package/dist/reports/model-report-data.js.map +7 -0
- package/dist/reports/model-report-orchestrator.js +103 -0
- package/dist/reports/model-report-orchestrator.js.map +7 -0
- package/dist/schemas/bundled/analyzers/cbm.json +595 -0
- package/dist/schemas/bundled/analyzers/manifest.json +9 -0
- package/dist/schemas/bundled/api.json +3411 -0
- package/dist/schemas/bundled/apm.json +2371 -0
- package/dist/schemas/bundled/application.json +1253 -0
- package/dist/schemas/bundled/base.json +1622 -0
- package/dist/schemas/bundled/business.json +1279 -0
- package/dist/schemas/bundled/data-model.json +1298 -0
- package/dist/schemas/bundled/data-store.json +2025 -0
- package/dist/schemas/bundled/manifest.json +93 -0
- package/dist/schemas/bundled/motivation.json +1360 -0
- package/dist/schemas/bundled/navigation.json +1874 -0
- package/dist/schemas/bundled/security.json +3488 -0
- package/dist/schemas/bundled/technology.json +2067 -0
- package/dist/schemas/bundled/testing.json +3120 -0
- package/dist/schemas/bundled/ux.json +3592 -0
- package/dist/server/schemas.js +202 -0
- package/dist/server/schemas.js.map +7 -0
- package/dist/server/server.js +1336 -252
- package/dist/server/server.js.map +3 -3
- package/dist/server/telemetry-middleware.js +22 -15
- package/dist/server/telemetry-middleware.js.map +2 -2
- package/dist/server-entry.js +65 -0
- package/dist/server-entry.js.map +7 -0
- package/dist/telemetry/config.js +89 -0
- package/dist/telemetry/config.js.map +7 -0
- package/dist/telemetry/console-interceptor.js.map +1 -1
- package/dist/telemetry/detect.js +24 -0
- package/dist/telemetry/detect.js.map +7 -0
- package/dist/telemetry/fetch-otlp-exporter.js +112 -0
- package/dist/telemetry/fetch-otlp-exporter.js.map +7 -0
- package/dist/telemetry/index.js +153 -3
- package/dist/telemetry/index.js.map +2 -2
- package/dist/telemetry/resilient-exporter.js +22 -8
- package/dist/telemetry/resilient-exporter.js.map +2 -2
- package/dist/telemetry/resilient-log-exporter.js +17 -8
- package/dist/telemetry/resilient-log-exporter.js.map +2 -2
- package/dist/telemetry/test-instrumentation.js.map +2 -2
- package/dist/types/index.js +84 -0
- package/dist/types/index.js.map +3 -3
- package/dist/types/source-reference.js +1 -0
- package/dist/types/source-reference.js.map +7 -0
- package/dist/utils/chat-logger.js +292 -0
- package/dist/utils/chat-logger.js.map +7 -0
- package/dist/utils/claude-stream.js +8 -0
- package/dist/utils/claude-stream.js.map +7 -0
- package/dist/utils/date-utils.js +7 -0
- package/dist/utils/date-utils.js.map +7 -0
- package/dist/utils/element-utils.js.map +1 -1
- package/dist/utils/errors.js +88 -15
- package/dist/utils/errors.js.map +3 -3
- package/dist/utils/export-python-annotations.js +82 -0
- package/dist/utils/export-python-annotations.js.map +7 -0
- package/dist/utils/file-io.js +7 -2
- package/dist/utils/file-io.js.map +2 -2
- package/dist/utils/file-lock.js +156 -0
- package/dist/utils/file-lock.js.map +7 -0
- package/dist/utils/id-generator.js +18 -0
- package/dist/utils/id-generator.js.map +7 -0
- package/dist/utils/layer-name-formatter.js +16 -0
- package/dist/utils/layer-name-formatter.js.map +7 -0
- package/dist/utils/markdown-anchor.js +7 -0
- package/dist/utils/markdown-anchor.js.map +7 -0
- package/dist/utils/markdown-link.js +12 -0
- package/dist/utils/markdown-link.js.map +7 -0
- package/dist/utils/markdown-table.js +17 -0
- package/dist/utils/markdown-table.js.map +7 -0
- package/dist/utils/mermaid-utils.js +11 -0
- package/dist/utils/mermaid-utils.js.map +7 -0
- package/dist/utils/project-paths.js.map +2 -2
- package/dist/utils/source-reference.js +52 -0
- package/dist/utils/source-reference.js.map +7 -0
- package/dist/utils/spec-installer.js +40 -53
- package/dist/utils/spec-installer.js.map +2 -2
- package/dist/utils/spec-version.js +5 -1
- package/dist/utils/spec-version.js.map +2 -2
- package/dist/utils/string-utils.js +12 -0
- package/dist/utils/string-utils.js.map +7 -0
- package/dist/utils/table-formatting.js +19 -0
- package/dist/utils/table-formatting.js.map +7 -0
- package/dist/validators/index.js +4 -0
- package/dist/validators/index.js.map +2 -2
- package/dist/validators/naming-validator.js +20 -23
- package/dist/validators/naming-validator.js.map +2 -2
- package/dist/validators/reference-validator.js +23 -38
- package/dist/validators/reference-validator.js.map +2 -2
- package/dist/validators/relationship-schema-validator.js +243 -0
- package/dist/validators/relationship-schema-validator.js.map +7 -0
- package/dist/validators/schema-validator.js +168 -68
- package/dist/validators/schema-validator.js.map +2 -2
- package/dist/validators/semantic-validator.js +36 -60
- package/dist/validators/semantic-validator.js.map +2 -2
- package/dist/validators/types.js.map +2 -2
- package/dist/validators/validation-formatter.js +159 -0
- package/dist/validators/validation-formatter.js.map +7 -0
- package/dist/validators/validator.js +24 -38
- package/dist/validators/validator.js.map +2 -2
- package/dist/viewer/README.md +139 -0
- package/dist/viewer/assets/main-CY0Xufuj.css +1 -0
- package/dist/viewer/assets/main-DtgErnwF.js +81 -0
- package/dist/viewer/assets/vendor-CxKvDp2x.js +17 -0
- package/dist/viewer/favicon.svg +11 -0
- package/dist/viewer/fonts/inter/Inter-Black.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Bold.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-ExtraBold.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Light.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Medium.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Regular.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-SemiBold.woff2 +0 -0
- package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Medium.woff2 +0 -0
- package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
- package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-SemiBold.woff2 +0 -0
- package/dist/viewer/index.html +15 -0
- package/dist/viewer/manifest.json +99 -0
- package/dist/viewer/version.json +1 -0
- package/package.json +37 -13
- package/PYTHON_CLI_PARITY.md +0 -265
- package/PYTHON_CLI_STRUCTURE_UPDATE.md +0 -246
- package/biome.json +0 -42
- package/bunfig.toml +0 -3
- package/dist/ai/claude-client.js +0 -71
- package/dist/ai/claude-client.js.map +0 -7
- package/dist/ai/context-provider.js +0 -129
- package/dist/ai/context-provider.js.map +0 -7
- package/dist/ai/tools.js +0 -231
- package/dist/ai/tools.js.map +0 -7
- package/dist/commands/migrate.js +0 -36
- package/dist/commands/migrate.js.map +0 -7
- package/dist/commands/project.js +0 -74
- package/dist/commands/project.js.map +0 -7
- package/dist/core/active-changeset.js +0 -52
- package/dist/core/active-changeset.js.map +0 -7
- package/dist/core/projection-engine.js +0 -288
- package/dist/core/projection-engine.js.map +0 -7
- package/dist/schemas/bundled/01-motivation-layer.schema.json +0 -942
- package/dist/schemas/bundled/02-business-layer.schema.json +0 -1293
- package/dist/schemas/bundled/03-security-layer.schema.json +0 -2177
- package/dist/schemas/bundled/04-application-layer.schema.json +0 -1328
- package/dist/schemas/bundled/05-technology-layer.schema.json +0 -1465
- package/dist/schemas/bundled/06-api-layer.schema.json +0 -1743
- package/dist/schemas/bundled/07-data-model-layer.schema.json +0 -1253
- package/dist/schemas/bundled/08-datastore-layer.schema.json +0 -892
- package/dist/schemas/bundled/09-ux-layer.schema.json +0 -1506
- package/dist/schemas/bundled/10-navigation-layer.schema.json +0 -843
- package/dist/schemas/bundled/11-apm-observability-layer.schema.json +0 -1430
- package/dist/schemas/bundled/12-testing-layer.schema.json +0 -1091
- package/dist/schemas/bundled/common/layer-extensions.schema.json +0 -266
- package/dist/schemas/bundled/common/predicates.schema.json +0 -493
- package/dist/schemas/bundled/common/relationships.schema.json +0 -791
- package/dist/schemas/bundled/common/source-references.schema.json +0 -71
- package/dist/schemas/bundled/link-registry.json +0 -1839
- package/dist/schemas/bundled/link-registry.schema.json +0 -339
- package/dist/schemas/bundled/relationship-catalog.json +0 -1302
- package/dist/schemas/bundled/relationship-type.schema.json +0 -221
- package/dist/utils/model-path.js +0 -22
- package/dist/utils/model-path.js.map +0 -7
- package/docs/TEST-INSTRUMENTATION.md +0 -405
- package/docs/telemetry.md +0 -427
- package/test-debug.js +0 -33
- package/test-special.mjs +0 -46
- package/test_runner.ts +0 -7
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { BaseChatClient } from "./base-chat-client.js";
|
|
2
|
+
import { spawnSync, spawn } from "child_process";
|
|
3
|
+
import ansis from "ansis";
|
|
4
|
+
import { getChatLogger } from "../utils/chat-logger.js";
|
|
5
|
+
import { getErrorMessage } from "../utils/errors.js";
|
|
6
|
+
import { isTelemetryEnabled, startSpan, endSpan, emitLog, SeverityNumber } from "../telemetry/index.js";
|
|
7
|
+
class ClaudeCodeClient extends BaseChatClient {
|
|
8
|
+
isFirstMessage = !0;
|
|
9
|
+
// Track first message for session management
|
|
10
|
+
/**
|
|
11
|
+
* Check if Claude Code CLI is available
|
|
12
|
+
*/
|
|
13
|
+
async isAvailable() {
|
|
14
|
+
const span = isTelemetryEnabled ? startSpan("claude-code.availability-check") : null;
|
|
15
|
+
try {
|
|
16
|
+
const available = spawnSync("which", ["claude"], {
|
|
17
|
+
stdio: "pipe",
|
|
18
|
+
encoding: "utf-8"
|
|
19
|
+
}).status === 0;
|
|
20
|
+
return isTelemetryEnabled && span && (span.setAttribute("client.available", available), span.setAttribute("client.name", "Claude Code"), span.setStatus({ code: 0 })), available;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
return isTelemetryEnabled && span && (span.recordException(error), span.setAttribute("client.available", !1), span.setAttribute("client.name", "Claude Code"), span.setStatus({
|
|
23
|
+
code: 2,
|
|
24
|
+
message: getErrorMessage(error)
|
|
25
|
+
})), !1;
|
|
26
|
+
} finally {
|
|
27
|
+
endSpan(span);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Send a message to Claude Code CLI and stream the response
|
|
32
|
+
* @param message The user's message
|
|
33
|
+
* @param options Chat options
|
|
34
|
+
*/
|
|
35
|
+
async sendMessage(message, options) {
|
|
36
|
+
const span = isTelemetryEnabled ? startSpan("claude-code.send-message", {
|
|
37
|
+
"message.length": message.length,
|
|
38
|
+
"message.content": message.substring(0, 500),
|
|
39
|
+
// First 500 chars for context
|
|
40
|
+
"client.name": "Claude Code",
|
|
41
|
+
"client.agent": options?.agent,
|
|
42
|
+
"client.withDanger": options?.withDanger === !0,
|
|
43
|
+
"client.isFirstMessage": this.isFirstMessage,
|
|
44
|
+
"options.workingDirectory": options?.workingDirectory,
|
|
45
|
+
"options.sessionId": options?.sessionId,
|
|
46
|
+
"client.workingDirectory": options?.workingDirectory,
|
|
47
|
+
"client.sessionId": options?.sessionId
|
|
48
|
+
}) : null, logger = getChatLogger();
|
|
49
|
+
logger && await logger.logUserMessage(message, {
|
|
50
|
+
client: "Claude Code",
|
|
51
|
+
agent: options?.agent
|
|
52
|
+
}), this.createSession(), this.updateSessionTimestamp();
|
|
53
|
+
const currentIsFirst = this.isFirstMessage;
|
|
54
|
+
return this.isFirstMessage && (this.isFirstMessage = !1), isTelemetryEnabled && span && (span.setAttribute("client.sessionCreated", !0), span.setAttribute("client.internalSessionId", this.getCurrentSession()?.id ?? "none")), new Promise((resolve, reject) => {
|
|
55
|
+
const proc = this.spawnClaudeProcess(message, options, currentIsFirst);
|
|
56
|
+
let buffer = "", assistantOutput = "", eventCount = 0, toolUseCount = 0;
|
|
57
|
+
proc.stdout?.on("data", (data) => {
|
|
58
|
+
const chunk = data.toString();
|
|
59
|
+
buffer += chunk;
|
|
60
|
+
const lines = buffer.split(`
|
|
61
|
+
`);
|
|
62
|
+
buffer = lines.pop() || "";
|
|
63
|
+
for (const line of lines)
|
|
64
|
+
if (line.trim())
|
|
65
|
+
try {
|
|
66
|
+
const event = JSON.parse(line);
|
|
67
|
+
eventCount++;
|
|
68
|
+
const result = this.handleClaudeEvent(event, options?.outputStream);
|
|
69
|
+
result.output && (assistantOutput += result.output), result.usedTool && toolUseCount++;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
isTelemetryEnabled && span && emitLog(SeverityNumber.WARN, "Failed to parse Claude event JSON", {
|
|
72
|
+
"error.message": getErrorMessage(error),
|
|
73
|
+
"event.rawLine": line.substring(0, 200),
|
|
74
|
+
"event.lineLength": line.length
|
|
75
|
+
}), logger && logger.logError(`Failed to parse Claude event: ${getErrorMessage(error)}`, {
|
|
76
|
+
source: "json-parse",
|
|
77
|
+
client: "Claude Code",
|
|
78
|
+
rawLine: line.substring(0, 200)
|
|
79
|
+
});
|
|
80
|
+
const outStream = options?.outputStream !== null ? options?.outputStream ?? process.stdout : null;
|
|
81
|
+
outStream && outStream.write(line + `
|
|
82
|
+
`), assistantOutput += line + `
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
}), proc.stderr?.on("data", (data) => {
|
|
86
|
+
const stderrText = data.toString().trim();
|
|
87
|
+
if (!stderrText)
|
|
88
|
+
return;
|
|
89
|
+
const isError = /\b(error|failed|exception|fatal|critical)\b/i.test(stderrText), isWarning = /\b(warning|warn|deprecated)\b/i.test(stderrText);
|
|
90
|
+
if (isTelemetryEnabled && span) {
|
|
91
|
+
const severity = isError ? SeverityNumber.ERROR : isWarning ? SeverityNumber.WARN : SeverityNumber.DEBUG;
|
|
92
|
+
emitLog(severity, "Claude Code stderr output", {
|
|
93
|
+
"stderr.source": "claude-cli",
|
|
94
|
+
"stderr.text": stderrText.substring(0, 500),
|
|
95
|
+
"stderr.isError": isError,
|
|
96
|
+
"stderr.isWarning": isWarning
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (logger && (isError ? logger.logError(stderrText, {
|
|
100
|
+
source: "stderr",
|
|
101
|
+
client: "Claude Code"
|
|
102
|
+
}) : logger.logEvent("stderr_output", {
|
|
103
|
+
text: stderrText.substring(0, 500),
|
|
104
|
+
isWarning,
|
|
105
|
+
client: "Claude Code"
|
|
106
|
+
})), isError || isWarning) {
|
|
107
|
+
const prefix = isError ? "[ERROR]" : "[WARNING]";
|
|
108
|
+
process.stderr.write(`${ansis.yellow(prefix)} ${stderrText}
|
|
109
|
+
`);
|
|
110
|
+
}
|
|
111
|
+
}), proc.on("error", (error) => {
|
|
112
|
+
const errorContext = {
|
|
113
|
+
"error.message": error.message,
|
|
114
|
+
"error.stack": error.stack,
|
|
115
|
+
"error.code": error.code,
|
|
116
|
+
// ENOENT, EACCES, etc.
|
|
117
|
+
"process.command": "claude",
|
|
118
|
+
"process.args": JSON.stringify(this.getProcessArgs(options)),
|
|
119
|
+
"process.sessionId": options?.sessionId,
|
|
120
|
+
"process.agent": options?.agent,
|
|
121
|
+
"process.workingDirectory": options?.workingDirectory || process.cwd(),
|
|
122
|
+
"message.length": message.length,
|
|
123
|
+
"message.preview": message.substring(0, 100)
|
|
124
|
+
};
|
|
125
|
+
isTelemetryEnabled && span && (emitLog(SeverityNumber.ERROR, "Claude Code process error", errorContext), span.recordException(error)), logger && logger.logError(`Claude process failed to spawn or encountered error: ${error.message}`, {
|
|
126
|
+
source: "process",
|
|
127
|
+
client: "Claude Code",
|
|
128
|
+
...errorContext
|
|
129
|
+
}), console.error("[ClaudeCodeClient] Process error:", error.message), console.error("[ClaudeCodeClient] Command:", "claude", this.getProcessArgs(options).join(" ")), error.code === "ENOENT" ? console.error("[ClaudeCodeClient] Claude CLI not found - ensure it is installed and in PATH") : error.code === "EACCES" && console.error("[ClaudeCodeClient] Permission denied - check Claude CLI executable permissions"), endSpan(span), reject(error);
|
|
130
|
+
}), proc.on("close", (exitCode) => {
|
|
131
|
+
if (buffer.trim())
|
|
132
|
+
try {
|
|
133
|
+
const event = JSON.parse(buffer);
|
|
134
|
+
eventCount++;
|
|
135
|
+
const result = this.handleClaudeEvent(event, options?.outputStream);
|
|
136
|
+
result.output && (assistantOutput += result.output), result.usedTool && toolUseCount++;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
isTelemetryEnabled && span && emitLog(SeverityNumber.WARN, "Failed to parse remaining buffer as JSON", {
|
|
139
|
+
"error.message": getErrorMessage(error),
|
|
140
|
+
"buffer.content": buffer.substring(0, 200),
|
|
141
|
+
"buffer.length": buffer.length
|
|
142
|
+
}), logger && logger.logError(`Failed to parse remaining buffer: ${getErrorMessage(error)}`, {
|
|
143
|
+
source: "json-parse-buffer",
|
|
144
|
+
client: "Claude Code",
|
|
145
|
+
bufferContent: buffer.substring(0, 200)
|
|
146
|
+
});
|
|
147
|
+
const outStream = options?.outputStream !== null ? options?.outputStream ?? process.stdout : null;
|
|
148
|
+
outStream && outStream.write(buffer), assistantOutput += buffer;
|
|
149
|
+
}
|
|
150
|
+
if (isTelemetryEnabled && span && (span.setAttribute("client.eventCount", eventCount), span.setAttribute("client.toolUseCount", toolUseCount), span.setAttribute("client.outputLength", assistantOutput.length), span.setAttribute("client.exitCode", exitCode || 0), span.setAttribute("response.content", assistantOutput.substring(0, 1e3)), span.setAttribute("response.preview", assistantOutput.substring(0, 200))), exitCode === 0)
|
|
151
|
+
logger && assistantOutput.trim() && logger.logAssistantMessage(assistantOutput, {
|
|
152
|
+
client: "Claude Code"
|
|
153
|
+
}), isTelemetryEnabled && span && span.setStatus({ code: 0 }), endSpan(span), resolve(assistantOutput);
|
|
154
|
+
else {
|
|
155
|
+
const errorMsg = `Claude process exited with code ${exitCode}`;
|
|
156
|
+
isTelemetryEnabled && span && (emitLog(SeverityNumber.ERROR, "Claude Code process exited with error", {
|
|
157
|
+
"process.exitCode": exitCode
|
|
158
|
+
}), span.setStatus({ code: 2, message: errorMsg })), logger && logger.logError(errorMsg, {
|
|
159
|
+
exitCode,
|
|
160
|
+
client: "Claude Code"
|
|
161
|
+
}), endSpan(span), reject(new Error(errorMsg));
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Handle a Claude Code event from the JSON stream
|
|
168
|
+
* @param event The Claude event to handle
|
|
169
|
+
* @param outputStream Stream for text output. null = suppress, undefined = stdout.
|
|
170
|
+
* @returns Object with output text and tool use flag
|
|
171
|
+
*/
|
|
172
|
+
handleClaudeEvent(event, outputStream) {
|
|
173
|
+
let output = "", usedTool = !1;
|
|
174
|
+
if (event.type === "assistant") {
|
|
175
|
+
const content = event.message?.content || [];
|
|
176
|
+
for (const block of content)
|
|
177
|
+
if (block.type === "text") {
|
|
178
|
+
const text = block.text || "";
|
|
179
|
+
outputStream !== null && (outputStream ?? process.stdout).write(text), output += text;
|
|
180
|
+
} else block.type === "tool_use" && (usedTool = !0, process.stderr.write(ansis.dim(`
|
|
181
|
+
[Using tool: ${block.name}]
|
|
182
|
+
`)));
|
|
183
|
+
}
|
|
184
|
+
return { output, usedTool };
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Get the process arguments that would be used for spawning
|
|
188
|
+
* @param options Chat options
|
|
189
|
+
* @param isFirstMessage Whether this is the first message in the chat session
|
|
190
|
+
* @returns Array of command line arguments
|
|
191
|
+
*/
|
|
192
|
+
getProcessArgs(options, isFirstMessage = !0) {
|
|
193
|
+
const args = ["--print"];
|
|
194
|
+
return options?.withDanger && args.push("--dangerously-skip-permissions"), args.push("--verbose", "--output-format", "stream-json"), isFirstMessage && options?.sessionId ? args.push("--session-id", options.sessionId) : !isFirstMessage && options?.sessionId && args.push("--resume", options.sessionId), options?.agent && args.unshift("--agent", options.agent), args;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Spawn the Claude Code CLI process
|
|
198
|
+
* @param message The message to send
|
|
199
|
+
* @param options Chat options
|
|
200
|
+
* @param isFirstMessage Whether this is the first message in the chat session
|
|
201
|
+
* @returns The spawned child process
|
|
202
|
+
*/
|
|
203
|
+
spawnClaudeProcess(message, options, isFirstMessage = !0) {
|
|
204
|
+
const span = isTelemetryEnabled ? startSpan("claude-code.spawn-process") : null;
|
|
205
|
+
try {
|
|
206
|
+
const args = this.getProcessArgs(options, isFirstMessage), cwd = options?.workingDirectory || process.cwd();
|
|
207
|
+
isTelemetryEnabled && span && (span.setAttribute("process.command", "claude"), span.setAttribute("process.args", args.join(" ")), span.setAttribute("process.argCount", args.length), span.setAttribute("process.isFirstMessage", isFirstMessage), span.setAttribute("process.hasResume", args.includes("--resume")), span.setAttribute("process.hasSessionId", args.includes("--session-id")), span.setAttribute("process.hasAgent", !!options?.agent), span.setAttribute("process.agent", options?.agent), span.setAttribute("process.withDanger", options?.withDanger === !0), span.setAttribute("process.workingDirectory", cwd), span.setAttribute("process.messageLength", message.length));
|
|
208
|
+
const logger = getChatLogger();
|
|
209
|
+
logger && logger.logCommand("claude", args, {
|
|
210
|
+
client: "Claude Code",
|
|
211
|
+
workingDirectory: cwd,
|
|
212
|
+
agent: options?.agent,
|
|
213
|
+
withDanger: options?.withDanger || !1,
|
|
214
|
+
messageLength: message.length,
|
|
215
|
+
hasVerboseFlag: args.includes("--verbose"),
|
|
216
|
+
hasOutputFormat: args.includes("--output-format"),
|
|
217
|
+
sessionId: options?.sessionId
|
|
218
|
+
});
|
|
219
|
+
const env = { ...process.env };
|
|
220
|
+
delete env.CLAUDECODE;
|
|
221
|
+
const proc = spawn("claude", args, {
|
|
222
|
+
cwd,
|
|
223
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
224
|
+
env
|
|
225
|
+
});
|
|
226
|
+
return proc.stdin?.write(message), proc.stdin?.end(), isTelemetryEnabled && span && (span.setAttribute("process.spawned", !0), span.setAttribute("process.pid", proc.pid), span.setStatus({ code: 0 })), proc;
|
|
227
|
+
} catch (error) {
|
|
228
|
+
throw isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
229
|
+
code: 2,
|
|
230
|
+
message: getErrorMessage(error)
|
|
231
|
+
})), error;
|
|
232
|
+
} finally {
|
|
233
|
+
endSpan(span);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Get the name of this client
|
|
238
|
+
*/
|
|
239
|
+
getClientName() {
|
|
240
|
+
return "Claude Code";
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
export {
|
|
244
|
+
ClaudeCodeClient
|
|
245
|
+
};
|
|
246
|
+
//# sourceMappingURL=claude-code-client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/coding-agents/claude-code-client.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Claude Code CLI Client\n *\n * Implements chat functionality using Claude Code CLI subprocess.\n * Uses structured JSON streaming output for reliable parsing.\n *\n * Key features:\n * - Availability detection via `which claude`\n * - JSON event stream parsing\n * - Agent support (dr-architect)\n * - Tool use detection and display\n * - Session management per process invocation\n */\n\nimport { BaseChatClient, ChatOptions } from \"./base-chat-client.js\";\nimport { spawnSync, spawn, ChildProcess } from \"child_process\";\nimport ansis from \"ansis\";\nimport { getChatLogger } from \"../utils/chat-logger.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport {\n isTelemetryEnabled,\n startSpan,\n endSpan,\n emitLog,\n SeverityNumber,\n} from \"../telemetry/index.js\";\n\n/**\n * Claude Code CLI event types\n */\ninterface ClaudeEvent {\n type: string;\n message?: {\n content?: Array<{\n type: string;\n text?: string;\n name?: string;\n }>;\n };\n}\n\n/**\n * Claude Code CLI Client\n */\nexport class ClaudeCodeClient extends BaseChatClient {\n private isFirstMessage: boolean = true; // Track first message for session management\n\n /**\n * Check if Claude Code CLI is available\n */\n async isAvailable(): Promise<boolean> {\n const span = isTelemetryEnabled ? startSpan(\"claude-code.availability-check\") : null;\n\n try {\n const result = spawnSync(\"which\", [\"claude\"], {\n stdio: \"pipe\",\n encoding: \"utf-8\",\n });\n const available = result.status === 0;\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"client.available\", available);\n (span as any).setAttribute(\"client.name\", \"Claude Code\");\n (span as any).setStatus({ code: 0 });\n }\n\n return available;\n } catch (error) {\n if (isTelemetryEnabled && span) {\n (span as any).recordException(error as Error);\n (span as any).setAttribute(\"client.available\", false);\n (span as any).setAttribute(\"client.name\", \"Claude Code\");\n (span as any).setStatus({\n code: 2,\n message: getErrorMessage(error),\n });\n }\n return false;\n } finally {\n endSpan(span);\n }\n }\n\n /**\n * Send a message to Claude Code CLI and stream the response\n * @param message The user's message\n * @param options Chat options\n */\n async sendMessage(message: string, options?: ChatOptions): Promise<string> {\n const span = isTelemetryEnabled\n ? startSpan(\"claude-code.send-message\", {\n \"message.length\": message.length,\n \"message.content\": message.substring(0, 500), // First 500 chars for context\n \"client.name\": \"Claude Code\",\n \"client.agent\": options?.agent,\n \"client.withDanger\": options?.withDanger === true,\n \"client.isFirstMessage\": this.isFirstMessage,\n \"options.workingDirectory\": options?.workingDirectory,\n \"options.sessionId\": options?.sessionId,\n \"client.workingDirectory\": options?.workingDirectory,\n \"client.sessionId\": options?.sessionId,\n })\n : null;\n\n // Log the user message\n const logger = getChatLogger();\n if (logger) {\n await logger.logUserMessage(message, {\n client: \"Claude Code\",\n agent: options?.agent,\n });\n }\n\n // Create NEW internal session for this message invocation\n // The sessionId in options (if provided) is passed to Claude CLI subprocess\n // to maintain conversation continuity at the Claude CLI level, not internally\n this.createSession();\n this.updateSessionTimestamp();\n\n // Capture isFirstMessage state before spawning, then mark subsequent messages as not-first\n const currentIsFirst = this.isFirstMessage;\n if (this.isFirstMessage) {\n this.isFirstMessage = false;\n }\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"client.sessionCreated\", true);\n (span as any).setAttribute(\n \"client.internalSessionId\",\n this.getCurrentSession()?.id ?? \"none\"\n );\n }\n\n return new Promise((resolve, reject) => {\n const proc = this.spawnClaudeProcess(message, options, currentIsFirst);\n\n let buffer = \"\";\n let assistantOutput = \"\";\n let eventCount = 0;\n let toolUseCount = 0;\n\n // Handle stdout - JSON event stream\n proc.stdout?.on(\"data\", (data: Buffer) => {\n const chunk = data.toString();\n buffer += chunk;\n\n // Process complete lines (each line is a JSON event)\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n try {\n const event: ClaudeEvent = JSON.parse(line);\n eventCount++;\n const result = this.handleClaudeEvent(event, options?.outputStream);\n if (result.output) {\n assistantOutput += result.output;\n }\n if (result.usedTool) {\n toolUseCount++;\n }\n } catch (error) {\n // Log JSON parse failure - this indicates a protocol mismatch or CLI bug\n if (isTelemetryEnabled && span) {\n emitLog(SeverityNumber.WARN, \"Failed to parse Claude event JSON\", {\n \"error.message\": getErrorMessage(error),\n \"event.rawLine\": line.substring(0, 200),\n \"event.lineLength\": line.length,\n });\n }\n if (logger) {\n void logger.logError(\n `Failed to parse Claude event: ${getErrorMessage(error)}`,\n {\n source: \"json-parse\",\n client: \"Claude Code\",\n rawLine: line.substring(0, 200),\n }\n );\n }\n\n // Non-JSON line \u2014 route through the same output stream as text content\n const outStream = options?.outputStream !== null\n ? (options?.outputStream ?? process.stdout)\n : null;\n if (outStream) {\n outStream.write(line + \"\\n\");\n }\n assistantOutput += line + \"\\n\";\n }\n }\n });\n\n // Handle stderr - always log for debugging, with severity detection\n proc.stderr?.on(\"data\", (data: Buffer) => {\n const stderrText = data.toString().trim();\n if (!stderrText) return; // Skip empty lines\n\n // Determine severity based on content patterns\n const isError = /\\b(error|failed|exception|fatal|critical)\\b/i.test(stderrText);\n const isWarning = /\\b(warning|warn|deprecated)\\b/i.test(stderrText);\n\n // Always log to telemetry and ChatLogger for debugging\n if (isTelemetryEnabled && span) {\n const severity = isError\n ? SeverityNumber.ERROR\n : isWarning\n ? SeverityNumber.WARN\n : SeverityNumber.DEBUG;\n emitLog(severity, \"Claude Code stderr output\", {\n \"stderr.source\": \"claude-cli\",\n \"stderr.text\": stderrText.substring(0, 500),\n \"stderr.isError\": isError,\n \"stderr.isWarning\": isWarning,\n });\n }\n\n if (logger) {\n if (isError) {\n void logger.logError(stderrText, {\n source: \"stderr\",\n client: \"Claude Code\",\n });\n } else {\n // Log non-errors as events for complete session history\n void logger.logEvent(\"stderr_output\", {\n text: stderrText.substring(0, 500),\n isWarning,\n client: \"Claude Code\",\n });\n }\n }\n\n // Display errors and warnings to user\n if (isError || isWarning) {\n const prefix = isError ? \"[ERROR]\" : \"[WARNING]\";\n process.stderr.write(`${ansis.yellow(prefix)} ${stderrText}\\n`);\n }\n });\n\n // Handle errors\n proc.on(\"error\", (error) => {\n const errorContext = {\n \"error.message\": error.message,\n \"error.stack\": error.stack,\n \"error.code\": (error as any).code, // ENOENT, EACCES, etc.\n \"process.command\": \"claude\",\n \"process.args\": JSON.stringify(this.getProcessArgs(options)),\n \"process.sessionId\": options?.sessionId,\n \"process.agent\": options?.agent,\n \"process.workingDirectory\": options?.workingDirectory || process.cwd(),\n \"message.length\": message.length,\n \"message.preview\": message.substring(0, 100),\n };\n\n if (isTelemetryEnabled && span) {\n emitLog(SeverityNumber.ERROR, \"Claude Code process error\", errorContext);\n (span as any).recordException(error);\n }\n if (logger) {\n void logger.logError(\n `Claude process failed to spawn or encountered error: ${error.message}`,\n {\n source: \"process\",\n client: \"Claude Code\",\n ...errorContext,\n }\n );\n }\n\n // Log to console for immediate visibility\n console.error(\"[ClaudeCodeClient] Process error:\", error.message);\n console.error(\n \"[ClaudeCodeClient] Command:\",\n \"claude\",\n this.getProcessArgs(options).join(\" \")\n );\n if ((error as any).code === \"ENOENT\") {\n console.error(\n \"[ClaudeCodeClient] Claude CLI not found - ensure it is installed and in PATH\"\n );\n } else if ((error as any).code === \"EACCES\") {\n console.error(\n \"[ClaudeCodeClient] Permission denied - check Claude CLI executable permissions\"\n );\n }\n\n endSpan(span);\n reject(error);\n });\n\n // Handle process exit\n proc.on(\"close\", (exitCode) => {\n // Print any remaining buffer\n if (buffer.trim()) {\n try {\n const event: ClaudeEvent = JSON.parse(buffer);\n eventCount++;\n const result = this.handleClaudeEvent(event, options?.outputStream);\n if (result.output) {\n assistantOutput += result.output;\n }\n if (result.usedTool) {\n toolUseCount++;\n }\n } catch (error) {\n // Log JSON parse failure for remaining buffer\n if (isTelemetryEnabled && span) {\n emitLog(SeverityNumber.WARN, \"Failed to parse remaining buffer as JSON\", {\n \"error.message\": getErrorMessage(error),\n \"buffer.content\": buffer.substring(0, 200),\n \"buffer.length\": buffer.length,\n });\n }\n if (logger) {\n void logger.logError(\n `Failed to parse remaining buffer: ${getErrorMessage(error)}`,\n {\n source: \"json-parse-buffer\",\n client: \"Claude Code\",\n bufferContent: buffer.substring(0, 200),\n }\n );\n }\n\n const outStream = options?.outputStream !== null\n ? (options?.outputStream ?? process.stdout)\n : null;\n if (outStream) {\n outStream.write(buffer);\n }\n assistantOutput += buffer;\n }\n }\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"client.eventCount\", eventCount);\n (span as any).setAttribute(\"client.toolUseCount\", toolUseCount);\n (span as any).setAttribute(\"client.outputLength\", assistantOutput.length);\n (span as any).setAttribute(\"client.exitCode\", exitCode || 0);\n (span as any).setAttribute(\"response.content\", assistantOutput.substring(0, 1000)); // First 1000 chars\n (span as any).setAttribute(\"response.preview\", assistantOutput.substring(0, 200)); // Short preview\n }\n\n if (exitCode === 0) {\n // Log assistant message if we got output\n if (logger && assistantOutput.trim()) {\n void logger.logAssistantMessage(assistantOutput, {\n client: \"Claude Code\",\n });\n }\n if (isTelemetryEnabled && span) {\n (span as any).setStatus({ code: 0 });\n }\n endSpan(span);\n resolve(assistantOutput);\n } else {\n const errorMsg = `Claude process exited with code ${exitCode}`;\n if (isTelemetryEnabled && span) {\n emitLog(SeverityNumber.ERROR, \"Claude Code process exited with error\", {\n \"process.exitCode\": exitCode,\n });\n (span as any).setStatus({ code: 2, message: errorMsg });\n }\n if (logger) {\n void logger.logError(errorMsg, {\n exitCode,\n client: \"Claude Code\",\n });\n }\n endSpan(span);\n reject(new Error(errorMsg));\n }\n });\n });\n }\n\n /**\n * Handle a Claude Code event from the JSON stream\n * @param event The Claude event to handle\n * @param outputStream Stream for text output. null = suppress, undefined = stdout.\n * @returns Object with output text and tool use flag\n */\n private handleClaudeEvent(\n event: ClaudeEvent,\n outputStream?: NodeJS.WriteStream | null\n ): { output: string; usedTool: boolean } {\n let output = \"\";\n let usedTool = false;\n\n if (event.type === \"assistant\") {\n const content = event.message?.content || [];\n for (const block of content) {\n if (block.type === \"text\") {\n const text = block.text || \"\";\n if (outputStream !== null) {\n (outputStream ?? process.stdout).write(text);\n }\n output += text;\n } else if (block.type === \"tool_use\") {\n usedTool = true;\n // Tool notifications are always progress indicators \u2014 always stderr.\n // Not added to output: they are display-only and would corrupt JSON parsing.\n process.stderr.write(ansis.dim(`\\n[Using tool: ${block.name}]\\n`));\n }\n }\n }\n\n return { output, usedTool };\n }\n\n /**\n * Get the process arguments that would be used for spawning\n * @param options Chat options\n * @param isFirstMessage Whether this is the first message in the chat session\n * @returns Array of command line arguments\n */\n private getProcessArgs(options?: ChatOptions, isFirstMessage: boolean = true): string[] {\n const args = [\"--print\"];\n\n // Add dangerously-skip-permissions flag if withDanger is enabled\n if (options?.withDanger) {\n args.push(\"--dangerously-skip-permissions\");\n }\n\n args.push(\"--verbose\", \"--output-format\", \"stream-json\");\n\n // Session management:\n // - First message: Start with our session ID for traceability\n // - Subsequent messages: Resume that specific session\n if (isFirstMessage && options?.sessionId) {\n args.push(\"--session-id\", options.sessionId);\n } else if (!isFirstMessage && options?.sessionId) {\n args.push(\"--resume\", options.sessionId);\n }\n\n // Add agent if specified\n if (options?.agent) {\n args.unshift(\"--agent\", options.agent);\n }\n\n return args;\n }\n\n /**\n * Spawn the Claude Code CLI process\n * @param message The message to send\n * @param options Chat options\n * @param isFirstMessage Whether this is the first message in the chat session\n * @returns The spawned child process\n */\n private spawnClaudeProcess(\n message: string,\n options?: ChatOptions,\n isFirstMessage: boolean = true\n ): ChildProcess {\n const span = isTelemetryEnabled ? startSpan(\"claude-code.spawn-process\") : null;\n\n try {\n const args = this.getProcessArgs(options, isFirstMessage);\n const cwd = options?.workingDirectory || process.cwd();\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"process.command\", \"claude\");\n (span as any).setAttribute(\"process.args\", args.join(\" \"));\n (span as any).setAttribute(\"process.argCount\", args.length);\n (span as any).setAttribute(\"process.isFirstMessage\", isFirstMessage);\n (span as any).setAttribute(\"process.hasResume\", args.includes(\"--resume\"));\n (span as any).setAttribute(\"process.hasSessionId\", args.includes(\"--session-id\"));\n (span as any).setAttribute(\"process.hasAgent\", !!options?.agent);\n (span as any).setAttribute(\"process.agent\", options?.agent);\n (span as any).setAttribute(\"process.withDanger\", options?.withDanger === true);\n (span as any).setAttribute(\"process.workingDirectory\", cwd);\n (span as any).setAttribute(\"process.messageLength\", message.length);\n }\n\n // Log the command that's being executed\n const logger = getChatLogger();\n if (logger) {\n void logger.logCommand(\"claude\", args, {\n client: \"Claude Code\",\n workingDirectory: cwd,\n agent: options?.agent,\n withDanger: options?.withDanger || false,\n messageLength: message.length,\n hasVerboseFlag: args.includes(\"--verbose\"),\n hasOutputFormat: args.includes(\"--output-format\"),\n sessionId: options?.sessionId,\n });\n }\n\n // Strip CLAUDECODE from the environment so Claude doesn't refuse to run\n // inside an existing Claude Code session (nested session protection).\n const env = { ...process.env };\n delete env.CLAUDECODE;\n\n const proc = spawn(\"claude\", args, {\n cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env,\n });\n\n // Send message via stdin\n proc.stdin?.write(message);\n proc.stdin?.end();\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"process.spawned\", true);\n (span as any).setAttribute(\"process.pid\", proc.pid);\n (span as any).setStatus({ code: 0 });\n }\n\n return proc;\n } catch (error) {\n if (isTelemetryEnabled && span) {\n (span as any).recordException(error as Error);\n (span as any).setStatus({\n code: 2,\n message: getErrorMessage(error),\n });\n }\n throw error;\n } finally {\n endSpan(span);\n }\n }\n\n /**\n * Get the name of this client\n */\n getClientName(): string {\n return \"Claude Code\";\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { BaseChatClient } from "./base-chat-client.js";
|
|
2
|
+
import { spawnSync, spawn } from "child_process";
|
|
3
|
+
import ansis from "ansis";
|
|
4
|
+
import { getChatLogger } from "../utils/chat-logger.js";
|
|
5
|
+
import { getErrorMessage } from "../utils/errors.js";
|
|
6
|
+
import { isTelemetryEnabled, startSpan, endSpan, emitLog, SeverityNumber } from "../telemetry/index.js";
|
|
7
|
+
class CopilotOutputParser {
|
|
8
|
+
inCodeBlock = !1;
|
|
9
|
+
codeBlockLanguage = "";
|
|
10
|
+
/**
|
|
11
|
+
* Parse a line of output from Copilot
|
|
12
|
+
* @param line The line to parse
|
|
13
|
+
* @returns Formatted output string or null if line should be skipped
|
|
14
|
+
*/
|
|
15
|
+
parseLine(line) {
|
|
16
|
+
const codeBlockMatch = line.match(/^```(\w*)$/);
|
|
17
|
+
return codeBlockMatch ? (this.inCodeBlock = !this.inCodeBlock, this.inCodeBlock ? (this.codeBlockLanguage = codeBlockMatch[1] || "", ansis.dim(`
|
|
18
|
+
[Code block: ${this.codeBlockLanguage || "text"}]
|
|
19
|
+
`)) : (this.codeBlockLanguage = "", ansis.dim(`
|
|
20
|
+
[End code block]
|
|
21
|
+
`))) : line.match(/^(Note:|Warning:|Error:|Info:)/i) ? ansis.yellow(line) : line.match(/^(Running|Executing|Searching|Analyzing):/i) ? ansis.dim(line) : line;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Reset parser state
|
|
25
|
+
*/
|
|
26
|
+
reset() {
|
|
27
|
+
this.inCodeBlock = !1, this.codeBlockLanguage = "";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
class CopilotClient extends BaseChatClient {
|
|
31
|
+
parser = new CopilotOutputParser();
|
|
32
|
+
copilotCommand = null;
|
|
33
|
+
isFirstMessage = !0;
|
|
34
|
+
/**
|
|
35
|
+
* Check if GitHub Copilot CLI is available
|
|
36
|
+
* Only supports standalone `copilot` npm package (@github/copilot)
|
|
37
|
+
*/
|
|
38
|
+
async isAvailable() {
|
|
39
|
+
const span = isTelemetryEnabled ? startSpan("copilot.availability-check") : null;
|
|
40
|
+
try {
|
|
41
|
+
if (this.copilotCommand !== null)
|
|
42
|
+
return isTelemetryEnabled && span && (span.setAttribute("client.available", !0), span.setAttribute("client.name", "GitHub Copilot"), span.setAttribute("client.cached", !0), span.setAttribute("client.variant", this.copilotCommand), span.setStatus({ code: 0 })), !0;
|
|
43
|
+
try {
|
|
44
|
+
if (spawnSync("copilot", ["--version"], {
|
|
45
|
+
stdio: "pipe",
|
|
46
|
+
encoding: "utf-8"
|
|
47
|
+
}).status === 0)
|
|
48
|
+
return this.copilotCommand = "copilot", isTelemetryEnabled && span && (span.setAttribute("client.available", !0), span.setAttribute("client.name", "GitHub Copilot"), span.setAttribute("client.cached", !1), span.setAttribute("client.variant", "copilot"), span.setStatus({ code: 0 })), !0;
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
return isTelemetryEnabled && span && (span.setAttribute("client.available", !1), span.setAttribute("client.name", "GitHub Copilot"), span.setStatus({ code: 0 })), !1;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return isTelemetryEnabled && span && (span.recordException(error), span.setAttribute("client.available", !1), span.setAttribute("client.name", "GitHub Copilot"), span.setStatus({
|
|
54
|
+
code: 2,
|
|
55
|
+
message: getErrorMessage(error)
|
|
56
|
+
})), !1;
|
|
57
|
+
} finally {
|
|
58
|
+
endSpan(span);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Send a message to GitHub Copilot and stream the response
|
|
63
|
+
* @param message The user's message
|
|
64
|
+
* @param options Chat options
|
|
65
|
+
*/
|
|
66
|
+
async sendMessage(message, options) {
|
|
67
|
+
const span = isTelemetryEnabled ? startSpan("copilot.send-message", {
|
|
68
|
+
"message.length": message.length,
|
|
69
|
+
"message.content": message.substring(0, 500),
|
|
70
|
+
// First 500 chars for context
|
|
71
|
+
"client.name": "GitHub Copilot",
|
|
72
|
+
"client.agent": options?.agent,
|
|
73
|
+
"client.withDanger": options?.withDanger === !0,
|
|
74
|
+
"options.workingDirectory": options?.workingDirectory,
|
|
75
|
+
"options.sessionId": options?.sessionId,
|
|
76
|
+
"client.workingDirectory": options?.workingDirectory,
|
|
77
|
+
"client.sessionId": options?.sessionId,
|
|
78
|
+
"client.isFirstMessage": this.isFirstMessage
|
|
79
|
+
}) : null;
|
|
80
|
+
if (!this.copilotCommand && !await this.isAvailable())
|
|
81
|
+
throw new Error("GitHub Copilot CLI is not available");
|
|
82
|
+
const logger = getChatLogger();
|
|
83
|
+
logger && await logger.logUserMessage(message, {
|
|
84
|
+
client: "GitHub Copilot",
|
|
85
|
+
agent: options?.agent
|
|
86
|
+
});
|
|
87
|
+
const hadExistingSession = !!this.currentSession;
|
|
88
|
+
return this.currentSession ? this.updateSessionTimestamp() : this.createSession(), isTelemetryEnabled && span && (span.setAttribute("client.hadExistingSession", hadExistingSession), span.setAttribute("client.internalSessionId", this.getCurrentSession()?.id ?? "none"), span.setAttribute("client.variant", this.copilotCommand)), new Promise((resolve, reject) => {
|
|
89
|
+
const proc = this.spawnCopilotProcess(message, options);
|
|
90
|
+
let buffer = "", assistantOutput = "", lineCount = 0;
|
|
91
|
+
this.parser.reset(), proc.stdout?.on("data", (data) => {
|
|
92
|
+
const chunk = data.toString();
|
|
93
|
+
buffer += chunk, assistantOutput += chunk;
|
|
94
|
+
const lines = buffer.split(`
|
|
95
|
+
`);
|
|
96
|
+
buffer = lines.pop() || "";
|
|
97
|
+
for (const line of lines) {
|
|
98
|
+
if (lineCount++, !line.trim()) {
|
|
99
|
+
process.stdout.write(`
|
|
100
|
+
`);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const parsed = this.parser.parseLine(line);
|
|
104
|
+
parsed !== null && process.stdout.write(parsed + `
|
|
105
|
+
`);
|
|
106
|
+
}
|
|
107
|
+
}), proc.stderr?.on("data", (data) => {
|
|
108
|
+
const errorText = data.toString();
|
|
109
|
+
(errorText.includes("error") || errorText.includes("Error") || errorText.includes("not authenticated")) && (process.stderr.write(ansis.red(errorText)), isTelemetryEnabled && span && emitLog(SeverityNumber.ERROR, "Copilot stderr error", {
|
|
110
|
+
"error.source": "stderr",
|
|
111
|
+
"error.text": errorText.substring(0, 500),
|
|
112
|
+
"error.isAuthError": errorText.includes("not authenticated")
|
|
113
|
+
}), logger && logger.logError(errorText, {
|
|
114
|
+
source: "stderr",
|
|
115
|
+
client: "GitHub Copilot"
|
|
116
|
+
}));
|
|
117
|
+
}), proc.on("error", (error) => {
|
|
118
|
+
isTelemetryEnabled && span && (emitLog(SeverityNumber.ERROR, "Copilot process error", {
|
|
119
|
+
"error.message": error.message,
|
|
120
|
+
"error.stack": error.stack,
|
|
121
|
+
"error.code": error.code,
|
|
122
|
+
// ENOENT, EACCES, etc.
|
|
123
|
+
"process.command": this.copilotCommand === "copilot" ? "copilot" : "gh copilot",
|
|
124
|
+
"message.length": message.length,
|
|
125
|
+
"message.preview": message.substring(0, 200)
|
|
126
|
+
}), span.recordException(error), span.setStatus({ code: 2, message: error.message })), logger && logger.logError(error.message, {
|
|
127
|
+
source: "process",
|
|
128
|
+
client: "GitHub Copilot",
|
|
129
|
+
stack: error.stack,
|
|
130
|
+
errorCode: error.code
|
|
131
|
+
}), endSpan(span), reject(error);
|
|
132
|
+
}), proc.on("close", (exitCode) => {
|
|
133
|
+
if (buffer.trim()) {
|
|
134
|
+
const parsed = this.parser.parseLine(buffer);
|
|
135
|
+
parsed !== null && process.stdout.write(parsed);
|
|
136
|
+
}
|
|
137
|
+
if (isTelemetryEnabled && span && (span.setAttribute("client.lineCount", lineCount), span.setAttribute("client.outputLength", assistantOutput.length), span.setAttribute("client.exitCode", exitCode || 0), span.setAttribute("response.content", assistantOutput.substring(0, 1e3)), span.setAttribute("response.preview", assistantOutput.substring(0, 200))), exitCode === 0)
|
|
138
|
+
logger && assistantOutput.trim() && logger.logAssistantMessage(assistantOutput, {
|
|
139
|
+
client: "GitHub Copilot"
|
|
140
|
+
}), isTelemetryEnabled && span && span.setStatus({ code: 0 }), endSpan(span), resolve(assistantOutput);
|
|
141
|
+
else {
|
|
142
|
+
const errorMsg = `Copilot process exited with code ${exitCode}`;
|
|
143
|
+
isTelemetryEnabled && span && (emitLog(SeverityNumber.ERROR, "Copilot process exited with error", {
|
|
144
|
+
"process.exitCode": exitCode
|
|
145
|
+
}), span.setStatus({ code: 2, message: errorMsg })), logger && logger.logError(errorMsg, {
|
|
146
|
+
exitCode,
|
|
147
|
+
client: "GitHub Copilot"
|
|
148
|
+
}), endSpan(span), reject(new Error(errorMsg));
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Spawn the GitHub Copilot CLI process
|
|
155
|
+
* @param message The message to send
|
|
156
|
+
* @param options Chat options
|
|
157
|
+
* @returns The spawned child process
|
|
158
|
+
*/
|
|
159
|
+
spawnCopilotProcess(message, options) {
|
|
160
|
+
const span = isTelemetryEnabled ? startSpan("copilot.spawn-process") : null;
|
|
161
|
+
try {
|
|
162
|
+
const args = [], cwd = options?.workingDirectory || process.cwd(), isFirst = this.isFirstMessage;
|
|
163
|
+
if (isFirst ? (args.push("--prompt", message), this.isFirstMessage = !1) : args.push("--continue", "--prompt", message), isFirst && options?.agent && args.push("--agent", options.agent), options?.withDanger)
|
|
164
|
+
try {
|
|
165
|
+
const helpResult = spawnSync(this.copilotCommand === "copilot" ? "copilot" : "gh", this.copilotCommand === "copilot" ? ["--help"] : ["copilot", "--help"], { stdio: "pipe", encoding: "utf-8", timeout: 1e3 });
|
|
166
|
+
helpResult.stdout?.includes("--allow-all-tools") || helpResult.stdout?.includes("allow-all-tools") ? (args.push("--allow-all-tools"), isTelemetryEnabled && span && span.setAttribute("process.allowAllToolsSupported", !0)) : (isTelemetryEnabled && span && (span.setAttribute("process.allowAllToolsSupported", !1), emitLog(SeverityNumber.WARN, "GitHub Copilot --allow-all-tools flag not available", {
|
|
167
|
+
"copilot.variant": this.copilotCommand,
|
|
168
|
+
withDanger: !0
|
|
169
|
+
})), console.warn(ansis.yellow("Warning: --allow-all-tools flag not supported by your copilot version")));
|
|
170
|
+
} catch {
|
|
171
|
+
args.push("--allow-all-tools"), isTelemetryEnabled && span && span.setAttribute("process.allowAllToolsCheckFailed", !0);
|
|
172
|
+
}
|
|
173
|
+
const command = "copilot";
|
|
174
|
+
isTelemetryEnabled && span && (span.setAttribute("process.command", command), span.setAttribute("process.args", args.join(" ")), span.setAttribute("process.argCount", args.length), span.setAttribute("process.isFirstMessage", isFirst), span.setAttribute("process.hasContinue", args.includes("--continue")), span.setAttribute("process.hasAgent", !!options?.agent), span.setAttribute("process.agent", options?.agent), span.setAttribute("process.withDanger", options?.withDanger === !0), span.setAttribute("process.workingDirectory", cwd), span.setAttribute("process.messageLength", message.length), span.setAttribute("process.variant", this.copilotCommand));
|
|
175
|
+
const logger = getChatLogger();
|
|
176
|
+
logger && logger.logCommand(command, args, {
|
|
177
|
+
client: "GitHub Copilot",
|
|
178
|
+
workingDirectory: cwd,
|
|
179
|
+
withDanger: options?.withDanger || !1,
|
|
180
|
+
copilotVariant: this.copilotCommand,
|
|
181
|
+
messageLength: message.length,
|
|
182
|
+
hasAgent: !!options?.agent,
|
|
183
|
+
isFirstMessage: isFirst
|
|
184
|
+
});
|
|
185
|
+
const proc = spawn(command, args, {
|
|
186
|
+
cwd,
|
|
187
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
188
|
+
});
|
|
189
|
+
return isTelemetryEnabled && span && (span.setAttribute("process.spawned", !0), span.setAttribute("process.pid", proc.pid), span.setStatus({ code: 0 })), proc;
|
|
190
|
+
} catch (error) {
|
|
191
|
+
throw isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
192
|
+
code: 2,
|
|
193
|
+
message: getErrorMessage(error)
|
|
194
|
+
})), error;
|
|
195
|
+
} finally {
|
|
196
|
+
endSpan(span);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get the name of this client
|
|
201
|
+
*/
|
|
202
|
+
getClientName() {
|
|
203
|
+
return "GitHub Copilot";
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
export {
|
|
207
|
+
CopilotClient
|
|
208
|
+
};
|
|
209
|
+
//# sourceMappingURL=copilot-client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/coding-agents/copilot-client.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * GitHub Copilot CLI Client\n *\n * Implements chat functionality using GitHub Copilot CLI subprocess.\n * Supports both `gh copilot` (GitHub CLI extension) and `@github/copilot` (npm package).\n *\n * Key features:\n * - Availability detection for both CLI variants\n * - Plain text/markdown output parsing (heuristic)\n * - Session management using command-line flags\n * - Code block detection\n * - System message detection\n */\n\nimport { BaseChatClient, ChatOptions } from \"./base-chat-client.js\";\nimport { spawnSync, spawn, ChildProcess } from \"child_process\";\nimport ansis from \"ansis\";\nimport { getChatLogger } from \"../utils/chat-logger.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport {\n isTelemetryEnabled,\n startSpan,\n endSpan,\n emitLog,\n SeverityNumber,\n} from \"../telemetry/index.js\";\n\n/**\n * Output parser for GitHub Copilot plain text responses\n * Uses heuristics to detect code blocks, system messages, and tool invocations\n */\nclass CopilotOutputParser {\n private inCodeBlock = false;\n private codeBlockLanguage = \"\";\n\n /**\n * Parse a line of output from Copilot\n * @param line The line to parse\n * @returns Formatted output string or null if line should be skipped\n */\n parseLine(line: string): string | null {\n // Detect code block start/end (markdown fences)\n const codeBlockMatch = line.match(/^```(\\w*)$/);\n if (codeBlockMatch) {\n this.inCodeBlock = !this.inCodeBlock;\n if (this.inCodeBlock) {\n this.codeBlockLanguage = codeBlockMatch[1] || \"\";\n return ansis.dim(`\\n[Code block: ${this.codeBlockLanguage || \"text\"}]\\n`);\n } else {\n this.codeBlockLanguage = \"\";\n return ansis.dim(\"\\n[End code block]\\n\");\n }\n }\n\n // Detect system messages (lines starting with special markers)\n if (line.match(/^(Note:|Warning:|Error:|Info:)/i)) {\n return ansis.yellow(line);\n }\n\n // Detect potential tool invocation patterns\n if (line.match(/^(Running|Executing|Searching|Analyzing):/i)) {\n return ansis.dim(line);\n }\n\n // Return line as-is\n return line;\n }\n\n /**\n * Reset parser state\n */\n reset(): void {\n this.inCodeBlock = false;\n this.codeBlockLanguage = \"\";\n }\n}\n\n/**\n * GitHub Copilot CLI Client\n */\nexport class CopilotClient extends BaseChatClient {\n private parser = new CopilotOutputParser();\n private copilotCommand: \"copilot\" | null = null;\n private isFirstMessage = true;\n\n /**\n * Check if GitHub Copilot CLI is available\n * Only supports standalone `copilot` npm package (@github/copilot)\n */\n async isAvailable(): Promise<boolean> {\n const span = isTelemetryEnabled ? startSpan(\"copilot.availability-check\") : null;\n\n try {\n // Return cached result if already detected\n if (this.copilotCommand !== null) {\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"client.available\", true);\n (span as any).setAttribute(\"client.name\", \"GitHub Copilot\");\n (span as any).setAttribute(\"client.cached\", true);\n (span as any).setAttribute(\"client.variant\", this.copilotCommand);\n (span as any).setStatus({ code: 0 });\n }\n return true;\n }\n\n // Check for standalone copilot command (npm package)\n try {\n const copilotResult = spawnSync(\"copilot\", [\"--version\"], {\n stdio: \"pipe\",\n encoding: \"utf-8\",\n });\n if (copilotResult.status === 0) {\n this.copilotCommand = \"copilot\";\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"client.available\", true);\n (span as any).setAttribute(\"client.name\", \"GitHub Copilot\");\n (span as any).setAttribute(\"client.cached\", false);\n (span as any).setAttribute(\"client.variant\", \"copilot\");\n (span as any).setStatus({ code: 0 });\n }\n return true;\n }\n } catch {\n // standalone copilot not available\n }\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"client.available\", false);\n (span as any).setAttribute(\"client.name\", \"GitHub Copilot\");\n (span as any).setStatus({ code: 0 });\n }\n\n return false;\n } catch (error) {\n if (isTelemetryEnabled && span) {\n (span as any).recordException(error as Error);\n (span as any).setAttribute(\"client.available\", false);\n (span as any).setAttribute(\"client.name\", \"GitHub Copilot\");\n (span as any).setStatus({\n code: 2,\n message: getErrorMessage(error),\n });\n }\n return false;\n } finally {\n endSpan(span);\n }\n }\n\n /**\n * Send a message to GitHub Copilot and stream the response\n * @param message The user's message\n * @param options Chat options\n */\n async sendMessage(message: string, options?: ChatOptions): Promise<string> {\n const span = isTelemetryEnabled\n ? startSpan(\"copilot.send-message\", {\n \"message.length\": message.length,\n \"message.content\": message.substring(0, 500), // First 500 chars for context\n \"client.name\": \"GitHub Copilot\",\n \"client.agent\": options?.agent,\n \"client.withDanger\": options?.withDanger === true,\n \"options.workingDirectory\": options?.workingDirectory,\n \"options.sessionId\": options?.sessionId,\n \"client.workingDirectory\": options?.workingDirectory,\n \"client.sessionId\": options?.sessionId,\n \"client.isFirstMessage\": this.isFirstMessage,\n })\n : null;\n\n // Ensure we have determined which command to use\n if (!this.copilotCommand) {\n const available = await this.isAvailable();\n if (!available) {\n throw new Error(\"GitHub Copilot CLI is not available\");\n }\n }\n\n // Log the user message\n const logger = getChatLogger();\n if (logger) {\n await logger.logUserMessage(message, {\n client: \"GitHub Copilot\",\n agent: options?.agent,\n });\n }\n\n // Create or continue session\n const hadExistingSession = !!this.currentSession;\n if (!this.currentSession) {\n this.createSession();\n } else {\n this.updateSessionTimestamp();\n }\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"client.hadExistingSession\", hadExistingSession);\n (span as any).setAttribute(\n \"client.internalSessionId\",\n this.getCurrentSession()?.id ?? \"none\"\n );\n (span as any).setAttribute(\"client.variant\", this.copilotCommand);\n }\n\n return new Promise((resolve, reject) => {\n const proc = this.spawnCopilotProcess(message, options);\n\n let buffer = \"\";\n let assistantOutput = \"\";\n let lineCount = 0;\n this.parser.reset();\n\n // Handle stdout\n proc.stdout?.on(\"data\", (data: Buffer) => {\n const chunk = data.toString();\n buffer += chunk;\n assistantOutput += chunk;\n\n // Process complete lines\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n lineCount++;\n if (!line.trim()) {\n process.stdout.write(\"\\n\");\n continue;\n }\n\n const parsed = this.parser.parseLine(line);\n if (parsed !== null) {\n process.stdout.write(parsed + \"\\n\");\n }\n }\n });\n\n // Handle stderr (usually authentication prompts or errors)\n proc.stderr?.on(\"data\", (data: Buffer) => {\n const errorText = data.toString();\n // Only show errors that are relevant to the user\n if (\n errorText.includes(\"error\") ||\n errorText.includes(\"Error\") ||\n errorText.includes(\"not authenticated\")\n ) {\n process.stderr.write(ansis.red(errorText));\n\n if (isTelemetryEnabled && span) {\n emitLog(SeverityNumber.ERROR, \"Copilot stderr error\", {\n \"error.source\": \"stderr\",\n \"error.text\": errorText.substring(0, 500),\n \"error.isAuthError\": errorText.includes(\"not authenticated\"),\n });\n }\n\n // Log error\n if (logger) {\n void logger.logError(errorText, {\n source: \"stderr\",\n client: \"GitHub Copilot\",\n });\n }\n }\n });\n\n // Handle errors\n proc.on(\"error\", (error) => {\n if (isTelemetryEnabled && span) {\n emitLog(SeverityNumber.ERROR, \"Copilot process error\", {\n \"error.message\": error.message,\n \"error.stack\": error.stack,\n \"error.code\": (error as any).code, // ENOENT, EACCES, etc.\n \"process.command\": this.copilotCommand === \"copilot\" ? \"copilot\" : \"gh copilot\",\n \"message.length\": message.length,\n \"message.preview\": message.substring(0, 200),\n });\n (span as any).recordException(error);\n (span as any).setStatus({ code: 2, message: error.message });\n }\n if (logger) {\n void logger.logError(error.message, {\n source: \"process\",\n client: \"GitHub Copilot\",\n stack: error.stack,\n errorCode: (error as any).code,\n });\n }\n endSpan(span);\n reject(error);\n });\n\n // Handle process exit\n proc.on(\"close\", (exitCode) => {\n // Print any remaining buffer\n if (buffer.trim()) {\n const parsed = this.parser.parseLine(buffer);\n if (parsed !== null) {\n process.stdout.write(parsed);\n }\n }\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"client.lineCount\", lineCount);\n (span as any).setAttribute(\"client.outputLength\", assistantOutput.length);\n (span as any).setAttribute(\"client.exitCode\", exitCode || 0);\n (span as any).setAttribute(\"response.content\", assistantOutput.substring(0, 1000)); // First 1000 chars\n (span as any).setAttribute(\"response.preview\", assistantOutput.substring(0, 200)); // Short preview\n }\n\n if (exitCode === 0) {\n // Log assistant message if we got output\n if (logger && assistantOutput.trim()) {\n void logger.logAssistantMessage(assistantOutput, {\n client: \"GitHub Copilot\",\n });\n }\n if (isTelemetryEnabled && span) {\n (span as any).setStatus({ code: 0 });\n }\n endSpan(span);\n resolve(assistantOutput);\n } else {\n const errorMsg = `Copilot process exited with code ${exitCode}`;\n if (isTelemetryEnabled && span) {\n emitLog(SeverityNumber.ERROR, \"Copilot process exited with error\", {\n \"process.exitCode\": exitCode,\n });\n (span as any).setStatus({ code: 2, message: errorMsg });\n }\n if (logger) {\n void logger.logError(errorMsg, {\n exitCode,\n client: \"GitHub Copilot\",\n });\n }\n endSpan(span);\n reject(new Error(errorMsg));\n }\n });\n });\n }\n\n /**\n * Spawn the GitHub Copilot CLI process\n * @param message The message to send\n * @param options Chat options\n * @returns The spawned child process\n */\n private spawnCopilotProcess(message: string, options?: ChatOptions): ChildProcess {\n const span = isTelemetryEnabled ? startSpan(\"copilot.spawn-process\") : null;\n\n try {\n const args: string[] = [];\n const cwd = options?.workingDirectory || process.cwd();\n\n const isFirst = this.isFirstMessage;\n\n // For first message: copilot --prompt \"message\" --agent \"dr-architect\" --allow-all-tools\n // For subsequent messages: copilot --continue --prompt \"message\" --allow-all-tools\n if (isFirst) {\n args.push(\"--prompt\", message);\n this.isFirstMessage = false;\n } else {\n args.push(\"--continue\", \"--prompt\", message);\n }\n\n // Add agent if specified (only on first message, agent persists in session)\n if (isFirst && options?.agent) {\n args.push(\"--agent\", options.agent);\n }\n\n // Add allow-all-tools flag if withDanger is enabled (required for non-interactive)\n // Note: This flag may not be available in all copilot versions\n if (options?.withDanger) {\n try {\n // Check if flag is supported by testing with --help\n const helpResult = spawnSync(\n this.copilotCommand === \"copilot\" ? \"copilot\" : \"gh\",\n this.copilotCommand === \"copilot\" ? [\"--help\"] : [\"copilot\", \"--help\"],\n { stdio: \"pipe\", encoding: \"utf-8\", timeout: 1000 }\n );\n if (\n helpResult.stdout?.includes(\"--allow-all-tools\") ||\n helpResult.stdout?.includes(\"allow-all-tools\")\n ) {\n args.push(\"--allow-all-tools\");\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"process.allowAllToolsSupported\", true);\n }\n } else {\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"process.allowAllToolsSupported\", false);\n emitLog(SeverityNumber.WARN, \"GitHub Copilot --allow-all-tools flag not available\", {\n \"copilot.variant\": this.copilotCommand,\n withDanger: true,\n });\n }\n console.warn(\n ansis.yellow(\"Warning: --allow-all-tools flag not supported by your copilot version\")\n );\n }\n } catch (error) {\n // If check fails, try adding the flag anyway\n args.push(\"--allow-all-tools\");\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"process.allowAllToolsCheckFailed\", true);\n }\n }\n }\n\n const command = \"copilot\";\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"process.command\", command);\n (span as any).setAttribute(\"process.args\", args.join(\" \"));\n (span as any).setAttribute(\"process.argCount\", args.length);\n (span as any).setAttribute(\"process.isFirstMessage\", isFirst);\n (span as any).setAttribute(\"process.hasContinue\", args.includes(\"--continue\"));\n (span as any).setAttribute(\"process.hasAgent\", !!options?.agent);\n (span as any).setAttribute(\"process.agent\", options?.agent);\n (span as any).setAttribute(\"process.withDanger\", options?.withDanger === true);\n (span as any).setAttribute(\"process.workingDirectory\", cwd);\n (span as any).setAttribute(\"process.messageLength\", message.length);\n (span as any).setAttribute(\"process.variant\", this.copilotCommand);\n }\n\n // Log the command that's being executed\n const logger = getChatLogger();\n if (logger) {\n void logger.logCommand(command, args, {\n client: \"GitHub Copilot\",\n workingDirectory: cwd,\n withDanger: options?.withDanger || false,\n copilotVariant: this.copilotCommand,\n messageLength: message.length,\n hasAgent: !!options?.agent,\n isFirstMessage: isFirst,\n });\n }\n\n const proc = spawn(command, args, {\n cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"process.spawned\", true);\n (span as any).setAttribute(\"process.pid\", proc.pid);\n (span as any).setStatus({ code: 0 });\n }\n\n return proc;\n } catch (error) {\n if (isTelemetryEnabled && span) {\n (span as any).recordException(error as Error);\n (span as any).setStatus({\n code: 2,\n message: getErrorMessage(error),\n });\n }\n throw error;\n } finally {\n endSpan(span);\n }\n }\n\n /**\n * Get the name of this client\n */\n getClientName(): string {\n return \"GitHub Copilot\";\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|