@lssm/bundle.contractspec-workspace 1.41.0 → 1.42.1
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 +5 -2
- package/dist/_virtual/rolldown_runtime.js +36 -1
- package/dist/adapters/ai.d.ts +12 -0
- package/dist/adapters/ai.d.ts.map +1 -0
- package/dist/adapters/ai.js +83 -1
- package/dist/adapters/ai.js.map +1 -0
- package/dist/adapters/factory.d.ts +29 -0
- package/dist/adapters/factory.d.ts.map +1 -0
- package/dist/adapters/factory.js +37 -1
- package/dist/adapters/factory.js.map +1 -0
- package/dist/adapters/fs.d.ts +11 -0
- package/dist/adapters/fs.d.ts.map +1 -0
- package/dist/adapters/fs.js +131 -1
- package/dist/adapters/fs.js.map +1 -0
- package/dist/adapters/git.d.ts +11 -0
- package/dist/adapters/git.d.ts.map +1 -0
- package/dist/adapters/git.js +55 -1
- package/dist/adapters/git.js.map +1 -0
- package/dist/adapters/index.d.ts +7 -0
- package/dist/adapters/index.js +7 -1
- package/dist/adapters/logger.d.ts +18 -0
- package/dist/adapters/logger.d.ts.map +1 -0
- package/dist/adapters/logger.js +81 -1
- package/dist/adapters/logger.js.map +1 -0
- package/dist/adapters/watcher.d.ts +11 -0
- package/dist/adapters/watcher.d.ts.map +1 -0
- package/dist/adapters/watcher.js +74 -1
- package/dist/adapters/watcher.js.map +1 -0
- package/dist/adapters/workspace.d.ts +148 -0
- package/dist/adapters/workspace.d.ts.map +1 -0
- package/dist/adapters/workspace.js +275 -2
- package/dist/adapters/workspace.js.map +1 -0
- package/dist/ai/agents/claude-code-agent.d.ts +22 -0
- package/dist/ai/agents/claude-code-agent.d.ts.map +1 -0
- package/dist/ai/agents/claude-code-agent.js +147 -9
- package/dist/ai/agents/claude-code-agent.js.map +1 -0
- package/dist/ai/agents/cursor-agent.d.ts +68 -0
- package/dist/ai/agents/cursor-agent.d.ts.map +1 -0
- package/dist/ai/agents/cursor-agent.js +285 -17
- package/dist/ai/agents/cursor-agent.js.map +1 -0
- package/dist/ai/agents/index.js +5 -1
- package/dist/ai/agents/openai-codex-agent.d.ts +22 -0
- package/dist/ai/agents/openai-codex-agent.d.ts.map +1 -0
- package/dist/ai/agents/openai-codex-agent.js +141 -8
- package/dist/ai/agents/openai-codex-agent.js.map +1 -0
- package/dist/ai/agents/orchestrator.d.ts +50 -0
- package/dist/ai/agents/orchestrator.d.ts.map +1 -0
- package/dist/ai/agents/orchestrator.js +143 -1
- package/dist/ai/agents/orchestrator.js.map +1 -0
- package/dist/ai/agents/simple-agent.d.ts +17 -0
- package/dist/ai/agents/simple-agent.d.ts.map +1 -0
- package/dist/ai/agents/simple-agent.js +81 -4
- package/dist/ai/agents/simple-agent.js.map +1 -0
- package/dist/ai/agents/types.d.ts +36 -0
- package/dist/ai/agents/types.d.ts.map +1 -0
- package/dist/ai/client.d.ts +83 -0
- package/dist/ai/client.d.ts.map +1 -0
- package/dist/ai/client.js +163 -1
- package/dist/ai/client.js.map +1 -0
- package/dist/ai/index.d.ts +17 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +28 -1
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/prompts/code-generation.d.ts +26 -0
- package/dist/ai/prompts/code-generation.d.ts.map +1 -0
- package/dist/ai/prompts/code-generation.js +56 -13
- package/dist/ai/prompts/code-generation.js.map +1 -0
- package/dist/ai/prompts/index.d.ts +10 -0
- package/dist/ai/prompts/index.d.ts.map +1 -0
- package/dist/ai/prompts/index.js +13 -1
- package/dist/ai/prompts/index.js.map +1 -0
- package/dist/ai/prompts/spec-creation.d.ts +29 -0
- package/dist/ai/prompts/spec-creation.d.ts.map +1 -0
- package/dist/ai/prompts/spec-creation.js +62 -20
- package/dist/ai/prompts/spec-creation.js.map +1 -0
- package/dist/ai/providers.d.ts +29 -0
- package/dist/ai/providers.d.ts.map +1 -0
- package/dist/ai/providers.js +39 -1
- package/dist/ai/providers.js.map +1 -0
- package/dist/formatters/index.d.ts +11 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +19 -1
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/json.d.ts +89 -0
- package/dist/formatters/json.d.ts.map +1 -0
- package/dist/formatters/json.js +72 -1
- package/dist/formatters/json.js.map +1 -0
- package/dist/formatters/sarif.d.ts +101 -0
- package/dist/formatters/sarif.d.ts.map +1 -0
- package/dist/formatters/sarif.js +163 -1
- package/dist/formatters/sarif.js.map +1 -0
- package/dist/formatters/text.d.ts +35 -0
- package/dist/formatters/text.d.ts.map +1 -0
- package/dist/formatters/text.js +209 -2
- package/dist/formatters/text.js.map +1 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +204 -1
- package/dist/index.js.map +1 -0
- package/dist/ports/ai.d.ts +59 -0
- package/dist/ports/ai.d.ts.map +1 -0
- package/dist/ports/fs.d.ts +81 -0
- package/dist/ports/fs.d.ts.map +1 -0
- package/dist/ports/git.d.ts +33 -0
- package/dist/ports/git.d.ts.map +1 -0
- package/dist/ports/index.d.ts +5 -0
- package/dist/ports/logger.d.ts +88 -0
- package/dist/ports/logger.d.ts.map +1 -0
- package/dist/ports/watcher.d.ts +52 -0
- package/dist/ports/watcher.d.ts.map +1 -0
- package/dist/services/agent-guide/adapters/claude-code.d.ts +35 -0
- package/dist/services/agent-guide/adapters/claude-code.d.ts.map +1 -0
- package/dist/services/agent-guide/adapters/claude-code.js +144 -3
- package/dist/services/agent-guide/adapters/claude-code.js.map +1 -0
- package/dist/services/agent-guide/adapters/cursor-cli.d.ts +39 -0
- package/dist/services/agent-guide/adapters/cursor-cli.d.ts.map +1 -0
- package/dist/services/agent-guide/adapters/cursor-cli.js +135 -3
- package/dist/services/agent-guide/adapters/cursor-cli.js.map +1 -0
- package/dist/services/agent-guide/adapters/generic-mcp.d.ts +53 -0
- package/dist/services/agent-guide/adapters/generic-mcp.d.ts.map +1 -0
- package/dist/services/agent-guide/adapters/generic-mcp.js +159 -3
- package/dist/services/agent-guide/adapters/generic-mcp.js.map +1 -0
- package/dist/services/agent-guide/adapters/index.d.ts +23 -0
- package/dist/services/agent-guide/adapters/index.d.ts.map +1 -0
- package/dist/services/agent-guide/adapters/index.js +31 -1
- package/dist/services/agent-guide/adapters/index.js.map +1 -0
- package/dist/services/agent-guide/agent-guide-service.d.ts +56 -0
- package/dist/services/agent-guide/agent-guide-service.d.ts.map +1 -0
- package/dist/services/agent-guide/agent-guide-service.js +147 -1
- package/dist/services/agent-guide/agent-guide-service.js.map +1 -0
- package/dist/services/agent-guide/index.d.ts +6 -0
- package/dist/services/agent-guide/index.js +5 -1
- package/dist/services/agent-guide/types.d.ts +58 -0
- package/dist/services/agent-guide/types.d.ts.map +1 -0
- package/dist/services/build.d.ts +59 -0
- package/dist/services/build.d.ts.map +1 -0
- package/dist/services/build.js +140 -1
- package/dist/services/build.js.map +1 -0
- package/dist/services/ci-check/ci-check-service.d.ts +16 -0
- package/dist/services/ci-check/ci-check-service.d.ts.map +1 -0
- package/dist/services/ci-check/ci-check-service.js +392 -1
- package/dist/services/ci-check/ci-check-service.js.map +1 -0
- package/dist/services/ci-check/index.d.ts +2 -0
- package/dist/services/ci-check/index.js +2 -1
- package/dist/services/ci-check/types.d.ts +143 -0
- package/dist/services/ci-check/types.d.ts.map +1 -0
- package/dist/services/ci-check/types.js +29 -1
- package/dist/services/ci-check/types.js.map +1 -0
- package/dist/services/clean.d.ts +41 -0
- package/dist/services/clean.d.ts.map +1 -0
- package/dist/services/clean.js +72 -1
- package/dist/services/clean.js.map +1 -0
- package/dist/services/config.d.ts +26 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/config.js +77 -1
- package/dist/services/config.js.map +1 -0
- package/dist/services/deps.d.ts +53 -0
- package/dist/services/deps.d.ts.map +1 -0
- package/dist/services/deps.js +62 -1
- package/dist/services/deps.js.map +1 -0
- package/dist/services/diff.d.ts +34 -0
- package/dist/services/diff.d.ts.map +1 -0
- package/dist/services/diff.js +34 -1
- package/dist/services/diff.js.map +1 -0
- package/dist/services/doctor/checks/ai.js +119 -2
- package/dist/services/doctor/checks/ai.js.map +1 -0
- package/dist/services/doctor/checks/cli.js +147 -1
- package/dist/services/doctor/checks/cli.js.map +1 -0
- package/dist/services/doctor/checks/config.js +171 -1
- package/dist/services/doctor/checks/config.js.map +1 -0
- package/dist/services/doctor/checks/deps.js +247 -1
- package/dist/services/doctor/checks/deps.js.map +1 -0
- package/dist/services/doctor/checks/index.js +6 -1
- package/dist/services/doctor/checks/mcp.js +145 -1
- package/dist/services/doctor/checks/mcp.js.map +1 -0
- package/dist/services/doctor/checks/workspace.js +244 -1
- package/dist/services/doctor/checks/workspace.js.map +1 -0
- package/dist/services/doctor/doctor-service.d.ts +24 -0
- package/dist/services/doctor/doctor-service.d.ts.map +1 -0
- package/dist/services/doctor/doctor-service.js +116 -2
- package/dist/services/doctor/doctor-service.js.map +1 -0
- package/dist/services/doctor/index.d.ts +2 -0
- package/dist/services/doctor/index.js +2 -1
- package/dist/services/doctor/types.d.ts +118 -0
- package/dist/services/doctor/types.d.ts.map +1 -0
- package/dist/services/doctor/types.js +27 -1
- package/dist/services/doctor/types.js.map +1 -0
- package/dist/services/impact/formatters.d.ts +27 -0
- package/dist/services/impact/formatters.d.ts.map +1 -0
- package/dist/services/impact/formatters.js +111 -0
- package/dist/services/impact/formatters.js.map +1 -0
- package/dist/services/impact/impact-detection-service.d.ts +22 -0
- package/dist/services/impact/impact-detection-service.d.ts.map +1 -0
- package/dist/services/impact/impact-detection-service.js +96 -0
- package/dist/services/impact/impact-detection-service.js.map +1 -0
- package/dist/services/impact/index.d.ts +11 -0
- package/dist/services/impact/index.d.ts.map +1 -0
- package/dist/services/impact/index.js +16 -0
- package/dist/services/impact/index.js.map +1 -0
- package/dist/services/impact/types.d.ts +58 -0
- package/dist/services/impact/types.d.ts.map +1 -0
- package/dist/services/implementation/discovery.d.ts +30 -0
- package/dist/services/implementation/discovery.d.ts.map +1 -0
- package/dist/services/implementation/discovery.js +144 -2
- package/dist/services/implementation/discovery.js.map +1 -0
- package/dist/services/implementation/index.d.ts +3 -0
- package/dist/services/implementation/index.js +2 -1
- package/dist/services/implementation/resolver.d.ts +44 -0
- package/dist/services/implementation/resolver.d.ts.map +1 -0
- package/dist/services/implementation/resolver.js +224 -1
- package/dist/services/implementation/resolver.js.map +1 -0
- package/dist/services/implementation/types.d.ts +79 -0
- package/dist/services/implementation/types.d.ts.map +1 -0
- package/dist/services/index.d.ts +60 -0
- package/dist/services/index.js +57 -1
- package/dist/services/integrity-diagram.d.ts +36 -0
- package/dist/services/integrity-diagram.d.ts.map +1 -0
- package/dist/services/integrity-diagram.js +275 -6
- package/dist/services/integrity-diagram.js.map +1 -0
- package/dist/services/integrity.d.ts +134 -0
- package/dist/services/integrity.d.ts.map +1 -0
- package/dist/services/integrity.js +272 -1
- package/dist/services/integrity.js.map +1 -0
- package/dist/services/list.d.ts +31 -0
- package/dist/services/list.d.ts.map +1 -0
- package/dist/services/list.js +36 -1
- package/dist/services/list.js.map +1 -0
- package/dist/services/openapi/export-service.d.ts +53 -0
- package/dist/services/openapi/export-service.d.ts.map +1 -0
- package/dist/services/openapi/export-service.js +50 -2
- package/dist/services/openapi/export-service.js.map +1 -0
- package/dist/services/openapi/import-service.d.ts +17 -0
- package/dist/services/openapi/import-service.d.ts.map +1 -0
- package/dist/services/openapi/import-service.js +74 -1
- package/dist/services/openapi/import-service.js.map +1 -0
- package/dist/services/openapi/index.d.ts +5 -0
- package/dist/services/openapi/index.js +4 -1
- package/dist/services/openapi/sync-service.d.ts +17 -0
- package/dist/services/openapi/sync-service.d.ts.map +1 -0
- package/dist/services/openapi/sync-service.js +120 -1
- package/dist/services/openapi/sync-service.js.map +1 -0
- package/dist/services/openapi/types.d.ts +162 -0
- package/dist/services/openapi/types.d.ts.map +1 -0
- package/dist/services/openapi/validate-service.d.ts +16 -0
- package/dist/services/openapi/validate-service.d.ts.map +1 -0
- package/dist/services/openapi/validate-service.js +130 -1
- package/dist/services/openapi/validate-service.js.map +1 -0
- package/dist/services/quickstart/dependencies.d.ts +31 -0
- package/dist/services/quickstart/dependencies.d.ts.map +1 -0
- package/dist/services/quickstart/dependencies.js +57 -0
- package/dist/services/quickstart/dependencies.js.map +1 -0
- package/dist/services/quickstart/index.js +2 -0
- package/dist/services/quickstart/quickstart-service.d.ts +20 -0
- package/dist/services/quickstart/quickstart-service.d.ts.map +1 -0
- package/dist/services/quickstart/quickstart-service.js +196 -0
- package/dist/services/quickstart/quickstart-service.js.map +1 -0
- package/dist/services/quickstart/types.d.ts +81 -0
- package/dist/services/quickstart/types.d.ts.map +1 -0
- package/dist/services/regenerator.d.ts +18 -0
- package/dist/services/regenerator.d.ts.map +1 -0
- package/dist/services/regenerator.js +23 -1
- package/dist/services/regenerator.js.map +1 -0
- package/dist/services/registry.d.ts +53 -0
- package/dist/services/registry.d.ts.map +1 -0
- package/dist/services/registry.js +74 -1
- package/dist/services/registry.js.map +1 -0
- package/dist/services/setup/config-generators.d.ts +42 -0
- package/dist/services/setup/config-generators.d.ts.map +1 -0
- package/dist/services/setup/config-generators.js +114 -26
- package/dist/services/setup/config-generators.js.map +1 -0
- package/dist/services/setup/file-merger.d.ts +27 -0
- package/dist/services/setup/file-merger.d.ts.map +1 -0
- package/dist/services/setup/file-merger.js +61 -2
- package/dist/services/setup/file-merger.js.map +1 -0
- package/dist/services/setup/index.js +4 -1
- package/dist/services/setup/setup-service.d.ts +12 -0
- package/dist/services/setup/setup-service.d.ts.map +1 -0
- package/dist/services/setup/setup-service.js +96 -1
- package/dist/services/setup/setup-service.js.map +1 -0
- package/dist/services/setup/targets/agents-md.js +47 -1
- package/dist/services/setup/targets/agents-md.js.map +1 -0
- package/dist/services/setup/targets/cli-config.js +60 -1
- package/dist/services/setup/targets/cli-config.js.map +1 -0
- package/dist/services/setup/targets/cursor-rules.js +48 -1
- package/dist/services/setup/targets/cursor-rules.js.map +1 -0
- package/dist/services/setup/targets/mcp-claude.js +60 -1
- package/dist/services/setup/targets/mcp-claude.js.map +1 -0
- package/dist/services/setup/targets/mcp-cursor.js +59 -1
- package/dist/services/setup/targets/mcp-cursor.js.map +1 -0
- package/dist/services/setup/targets/vscode-settings.js +63 -1
- package/dist/services/setup/targets/vscode-settings.js.map +1 -0
- package/dist/services/setup/types.d.ts +85 -0
- package/dist/services/setup/types.d.ts.map +1 -0
- package/dist/services/setup/types.js +27 -1
- package/dist/services/setup/types.js.map +1 -0
- package/dist/services/sync.d.ts +41 -0
- package/dist/services/sync.d.ts.map +1 -0
- package/dist/services/sync.js +63 -1
- package/dist/services/sync.js.map +1 -0
- package/dist/services/test.d.ts +15 -0
- package/dist/services/test.d.ts.map +1 -0
- package/dist/services/test.js +30 -1
- package/dist/services/test.js.map +1 -0
- package/dist/services/validate-implementation.d.ts +32 -0
- package/dist/services/validate-implementation.d.ts.map +1 -0
- package/dist/services/validate-implementation.js +70 -1
- package/dist/services/validate-implementation.js.map +1 -0
- package/dist/services/validate.d.ts +41 -0
- package/dist/services/validate.d.ts.map +1 -0
- package/dist/services/validate.js +48 -1
- package/dist/services/validate.js.map +1 -0
- package/dist/services/verification-cache/adapters/filesystem.d.ts +46 -0
- package/dist/services/verification-cache/adapters/filesystem.d.ts.map +1 -0
- package/dist/services/verification-cache/adapters/filesystem.js +120 -1
- package/dist/services/verification-cache/adapters/filesystem.js.map +1 -0
- package/dist/services/verification-cache/adapters/in-memory.d.ts +27 -0
- package/dist/services/verification-cache/adapters/in-memory.d.ts.map +1 -0
- package/dist/services/verification-cache/adapters/in-memory.js +46 -1
- package/dist/services/verification-cache/adapters/in-memory.js.map +1 -0
- package/dist/services/verification-cache/adapters/index.d.ts +3 -0
- package/dist/services/verification-cache/adapters/index.js +3 -1
- package/dist/services/verification-cache/adapters/workspace-state.d.ts +49 -0
- package/dist/services/verification-cache/adapters/workspace-state.d.ts.map +1 -0
- package/dist/services/verification-cache/adapters/workspace-state.js +91 -1
- package/dist/services/verification-cache/adapters/workspace-state.js.map +1 -0
- package/dist/services/verification-cache/cache-service.d.ts +70 -0
- package/dist/services/verification-cache/cache-service.d.ts.map +1 -0
- package/dist/services/verification-cache/cache-service.js +256 -1
- package/dist/services/verification-cache/cache-service.js.map +1 -0
- package/dist/services/verification-cache/index.d.ts +6 -0
- package/dist/services/verification-cache/index.js +6 -1
- package/dist/services/verification-cache/types.d.ts +124 -0
- package/dist/services/verification-cache/types.d.ts.map +1 -0
- package/dist/services/verification-cache/types.js +16 -1
- package/dist/services/verification-cache/types.js.map +1 -0
- package/dist/services/verify/ai-verifier.d.ts +25 -0
- package/dist/services/verify/ai-verifier.d.ts.map +1 -0
- package/dist/services/verify/ai-verifier.js +336 -9
- package/dist/services/verify/ai-verifier.js.map +1 -0
- package/dist/services/verify/behavior-verifier.d.ts +12 -0
- package/dist/services/verify/behavior-verifier.d.ts.map +1 -0
- package/dist/services/verify/behavior-verifier.js +186 -1
- package/dist/services/verify/behavior-verifier.js.map +1 -0
- package/dist/services/verify/index.d.ts +5 -0
- package/dist/services/verify/index.js +4 -1
- package/dist/services/verify/structure-verifier.d.ts +12 -0
- package/dist/services/verify/structure-verifier.d.ts.map +1 -0
- package/dist/services/verify/structure-verifier.js +196 -2
- package/dist/services/verify/structure-verifier.js.map +1 -0
- package/dist/services/verify/types.d.ts +137 -0
- package/dist/services/verify/types.d.ts.map +1 -0
- package/dist/services/verify/verify-service.d.ts +60 -0
- package/dist/services/verify/verify-service.d.ts.map +1 -0
- package/dist/services/verify/verify-service.js +204 -3
- package/dist/services/verify/verify-service.js.map +1 -0
- package/dist/services/watch.d.ts +25 -0
- package/dist/services/watch.d.ts.map +1 -0
- package/dist/services/watch.js +32 -1
- package/dist/services/watch.js.map +1 -0
- package/dist/services/workspace-info.d.ts +62 -0
- package/dist/services/workspace-info.d.ts.map +1 -0
- package/dist/services/workspace-info.js +103 -2
- package/dist/services/workspace-info.js.map +1 -0
- package/dist/templates/app-config.template.d.ts +7 -0
- package/dist/templates/app-config.template.d.ts.map +1 -0
- package/dist/templates/app-config.template.js +102 -28
- package/dist/templates/app-config.template.js.map +1 -0
- package/dist/templates/data-view.template.d.ts +7 -0
- package/dist/templates/data-view.template.d.ts.map +1 -0
- package/dist/templates/data-view.template.js +43 -27
- package/dist/templates/data-view.template.js.map +1 -0
- package/dist/templates/event.template.d.ts +11 -0
- package/dist/templates/event.template.d.ts.map +1 -0
- package/dist/templates/event.template.js +30 -14
- package/dist/templates/event.template.js.map +1 -0
- package/dist/templates/experiment.template.d.ts +7 -0
- package/dist/templates/experiment.template.d.ts.map +1 -0
- package/dist/templates/experiment.template.js +78 -51
- package/dist/templates/experiment.template.js.map +1 -0
- package/dist/templates/handler.template.d.ts +16 -0
- package/dist/templates/handler.template.d.ts.map +1 -0
- package/dist/templates/handler.template.js +54 -17
- package/dist/templates/handler.template.js.map +1 -0
- package/dist/templates/index.d.ts +21 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +37 -1
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/integration.template.d.ts +7 -0
- package/dist/templates/integration.template.d.ts.map +1 -0
- package/dist/templates/integration.template.js +135 -50
- package/dist/templates/integration.template.js.map +1 -0
- package/dist/templates/knowledge.template.d.ts +7 -0
- package/dist/templates/knowledge.template.d.ts.map +1 -0
- package/dist/templates/knowledge.template.js +63 -21
- package/dist/templates/knowledge.template.js.map +1 -0
- package/dist/templates/migration.template.d.ts +7 -0
- package/dist/templates/migration.template.d.ts.map +1 -0
- package/dist/templates/migration.template.js +51 -26
- package/dist/templates/migration.template.js.map +1 -0
- package/dist/templates/operation.template.d.ts +11 -0
- package/dist/templates/operation.template.d.ts.map +1 -0
- package/dist/templates/operation.template.js +45 -28
- package/dist/templates/operation.template.js.map +1 -0
- package/dist/templates/presentation.template.d.ts +11 -0
- package/dist/templates/presentation.template.d.ts.map +1 -0
- package/dist/templates/presentation.template.js +47 -20
- package/dist/templates/presentation.template.js.map +1 -0
- package/dist/templates/telemetry.template.d.ts +7 -0
- package/dist/templates/telemetry.template.d.ts.map +1 -0
- package/dist/templates/telemetry.template.js +75 -53
- package/dist/templates/telemetry.template.js.map +1 -0
- package/dist/templates/workflow-runner.template.d.ts +16 -0
- package/dist/templates/workflow-runner.template.d.ts.map +1 -0
- package/dist/templates/workflow-runner.template.js +13 -6
- package/dist/templates/workflow-runner.template.js.map +1 -0
- package/dist/templates/workflow.template.d.ts +7 -0
- package/dist/templates/workflow.template.d.ts.map +1 -0
- package/dist/templates/workflow.template.js +52 -24
- package/dist/templates/workflow.template.js.map +1 -0
- package/dist/types/config.d.ts +34 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types.d.ts +324 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +28 -15
- package/dist/node_modules/@ai-sdk/anthropic/dist/index.js +0 -1
- package/dist/node_modules/@ai-sdk/openai/dist/index.js +0 -11
- package/dist/node_modules/@ai-sdk/provider/dist/index.js +0 -3
- package/dist/node_modules/@ai-sdk/provider-utils/dist/index.js +0 -5
- package/dist/node_modules/chalk/source/index.js +0 -2
- package/dist/node_modules/chalk/source/utilities.js +0 -4
- package/dist/node_modules/chalk/source/vendor/ansi-styles/index.js +0 -1
- package/dist/node_modules/chalk/source/vendor/supports-color/browser.js +0 -1
- package/dist/node_modules/cli-cursor/index.js +0 -1
- package/dist/node_modules/cli-spinners/index.js +0 -1
- package/dist/node_modules/cli-spinners/spinners.js +0 -1
- package/dist/node_modules/eventsource-parser/dist/index.js +0 -5
- package/dist/node_modules/eventsource-parser/dist/stream.js +0 -1
- package/dist/node_modules/get-east-asian-width/index.js +0 -1
- package/dist/node_modules/get-east-asian-width/lookup.js +0 -1
- package/dist/node_modules/is-interactive/index.js +0 -1
- package/dist/node_modules/is-unicode-supported/index.js +0 -1
- package/dist/node_modules/log-symbols/browser-symbols.js +0 -1
- package/dist/node_modules/mimic-function/index.js +0 -1
- package/dist/node_modules/onetime/index.js +0 -1
- package/dist/node_modules/ora/index.js +0 -6
- package/dist/node_modules/restore-cursor/index.js +0 -1
- package/dist/node_modules/signal-exit/dist/mjs/index.js +0 -1
- package/dist/node_modules/signal-exit/dist/mjs/signals.js +0 -1
- package/dist/node_modules/stdin-discarder/index.js +0 -1
- package/dist/node_modules/string-width/index.js +0 -1
- package/dist/node_modules/strip-ansi/index.js +0 -1
- package/dist/node_modules/strip-ansi/node_modules/ansi-regex/index.js +0 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { FsAdapter } from "../ports/fs.js";
|
|
2
|
+
import { LoggerAdapter } from "../ports/logger.js";
|
|
3
|
+
|
|
4
|
+
//#region src/services/clean.d.ts
|
|
5
|
+
|
|
6
|
+
interface CleanOptions {
|
|
7
|
+
/**
|
|
8
|
+
* When true, only remove known build artifact directories and known generated
|
|
9
|
+
* suffixes (safe-by-default).
|
|
10
|
+
*/
|
|
11
|
+
generatedOnly?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Skip deletions; just report.
|
|
14
|
+
*/
|
|
15
|
+
dryRun?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Only delete files older than this many days.
|
|
18
|
+
*/
|
|
19
|
+
olderThanDays?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Output directory used for generated artifacts (handlers/components/forms).
|
|
22
|
+
*/
|
|
23
|
+
outputDir?: string;
|
|
24
|
+
}
|
|
25
|
+
interface CleanResult {
|
|
26
|
+
removed: {
|
|
27
|
+
path: string;
|
|
28
|
+
size: number;
|
|
29
|
+
}[];
|
|
30
|
+
skipped: {
|
|
31
|
+
path: string;
|
|
32
|
+
reason: string;
|
|
33
|
+
}[];
|
|
34
|
+
}
|
|
35
|
+
declare function cleanArtifacts(adapters: {
|
|
36
|
+
fs: FsAdapter;
|
|
37
|
+
logger: LoggerAdapter;
|
|
38
|
+
}, options?: CleanOptions): Promise<CleanResult>;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { CleanOptions, CleanResult, cleanArtifacts };
|
|
41
|
+
//# sourceMappingURL=clean.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.d.ts","names":[],"sources":["../../src/services/clean.ts"],"sourcesContent":[],"mappings":";;;;;AAmCkB,UA1BD,YAAA,CA0BC;EAAmB;;;;EAE3B,aAAA,CAAA,EAAA,OAAA;;;;;;;;;;;;;;UARO,WAAA;;;;;;;;;;iBAKK,cAAA;MACJ;UAAmB;aAC1B,eACR,QAAQ"}
|
package/dist/services/clean.js
CHANGED
|
@@ -1 +1,72 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/services/clean.ts
|
|
2
|
+
async function cleanArtifacts(adapters, options = {}) {
|
|
3
|
+
const { fs, logger } = adapters;
|
|
4
|
+
const outputDir = (options.outputDir ?? "./src").replace(/\\/g, "/");
|
|
5
|
+
const basePatterns = [
|
|
6
|
+
"generated/**",
|
|
7
|
+
"dist/**",
|
|
8
|
+
".turbo/**"
|
|
9
|
+
];
|
|
10
|
+
const outputDirPatterns = [
|
|
11
|
+
`${outputDir}/handlers/**/*.handler.ts`,
|
|
12
|
+
`${outputDir}/handlers/**/*.handler.test.ts`,
|
|
13
|
+
`${outputDir}/components/**/*.tsx`,
|
|
14
|
+
`${outputDir}/components/**/*.test.tsx`,
|
|
15
|
+
`${outputDir}/forms/**/*.form.tsx`,
|
|
16
|
+
`${outputDir}/forms/**/*.form.test.tsx`,
|
|
17
|
+
`${outputDir}/**/*.runner.ts`,
|
|
18
|
+
`${outputDir}/**/*.renderer.tsx`
|
|
19
|
+
];
|
|
20
|
+
const patterns = options.generatedOnly ? [...basePatterns, ...outputDirPatterns] : [
|
|
21
|
+
...basePatterns,
|
|
22
|
+
"**/*.generated.ts",
|
|
23
|
+
"**/*.generated.js",
|
|
24
|
+
"**/*.generated.d.ts",
|
|
25
|
+
...outputDirPatterns
|
|
26
|
+
];
|
|
27
|
+
const candidates = await fs.glob({
|
|
28
|
+
patterns,
|
|
29
|
+
ignore: ["node_modules/**"]
|
|
30
|
+
});
|
|
31
|
+
const removed = [];
|
|
32
|
+
const skipped = [];
|
|
33
|
+
for (const p of candidates) try {
|
|
34
|
+
const st = await fs.stat(p);
|
|
35
|
+
const ageDays = (Date.now() - st.mtime.getTime()) / (1e3 * 60 * 60 * 24);
|
|
36
|
+
if (typeof options.olderThanDays === "number" && ageDays < options.olderThanDays) {
|
|
37
|
+
skipped.push({
|
|
38
|
+
path: p,
|
|
39
|
+
reason: `younger_than_${options.olderThanDays}_days`
|
|
40
|
+
});
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (options.dryRun) logger.info("[dry-run] clean would remove", {
|
|
44
|
+
path: p,
|
|
45
|
+
size: st.size
|
|
46
|
+
});
|
|
47
|
+
else {
|
|
48
|
+
await fs.remove(p);
|
|
49
|
+
logger.info("clean.removed", {
|
|
50
|
+
path: p,
|
|
51
|
+
size: st.size
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
removed.push({
|
|
55
|
+
path: p,
|
|
56
|
+
size: st.size
|
|
57
|
+
});
|
|
58
|
+
} catch (error) {
|
|
59
|
+
skipped.push({
|
|
60
|
+
path: p,
|
|
61
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
removed,
|
|
66
|
+
skipped
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
export { cleanArtifacts };
|
|
72
|
+
//# sourceMappingURL=clean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.js","names":["removed: { path: string; size: number }[]","skipped: { path: string; reason: string }[]"],"sources":["../../src/services/clean.ts"],"sourcesContent":["/**\n * Clean service.\n *\n * Safe-by-default cleanup of generated artifacts.\n */\n\nimport type { FsAdapter } from '../ports/fs';\nimport type { LoggerAdapter } from '../ports/logger';\n\nexport interface CleanOptions {\n /**\n * When true, only remove known build artifact directories and known generated\n * suffixes (safe-by-default).\n */\n generatedOnly?: boolean;\n /**\n * Skip deletions; just report.\n */\n dryRun?: boolean;\n /**\n * Only delete files older than this many days.\n */\n olderThanDays?: number;\n /**\n * Output directory used for generated artifacts (handlers/components/forms).\n */\n outputDir?: string;\n}\n\nexport interface CleanResult {\n removed: { path: string; size: number }[];\n skipped: { path: string; reason: string }[];\n}\n\nexport async function cleanArtifacts(\n adapters: { fs: FsAdapter; logger: LoggerAdapter },\n options: CleanOptions = {}\n): Promise<CleanResult> {\n const { fs, logger } = adapters;\n const outputDir = (options.outputDir ?? './src').replace(/\\\\/g, '/');\n\n const basePatterns = ['generated/**', 'dist/**', '.turbo/**'];\n\n const outputDirPatterns = [\n `${outputDir}/handlers/**/*.handler.ts`,\n `${outputDir}/handlers/**/*.handler.test.ts`,\n `${outputDir}/components/**/*.tsx`,\n `${outputDir}/components/**/*.test.tsx`,\n `${outputDir}/forms/**/*.form.tsx`,\n `${outputDir}/forms/**/*.form.test.tsx`,\n `${outputDir}/**/*.runner.ts`,\n `${outputDir}/**/*.renderer.tsx`,\n ];\n\n const patterns = options.generatedOnly\n ? [...basePatterns, ...outputDirPatterns]\n : [\n ...basePatterns,\n '**/*.generated.ts',\n '**/*.generated.js',\n '**/*.generated.d.ts',\n ...outputDirPatterns,\n ];\n\n const candidates = await fs.glob({\n patterns,\n ignore: ['node_modules/**'],\n });\n\n const removed: { path: string; size: number }[] = [];\n const skipped: { path: string; reason: string }[] = [];\n\n for (const p of candidates) {\n try {\n const st = await fs.stat(p);\n const ageDays = (Date.now() - st.mtime.getTime()) / (1000 * 60 * 60 * 24);\n if (\n typeof options.olderThanDays === 'number' &&\n ageDays < options.olderThanDays\n ) {\n skipped.push({\n path: p,\n reason: `younger_than_${options.olderThanDays}_days`,\n });\n continue;\n }\n\n if (options.dryRun) {\n logger.info('[dry-run] clean would remove', { path: p, size: st.size });\n } else {\n await fs.remove(p);\n logger.info('clean.removed', { path: p, size: st.size });\n }\n removed.push({ path: p, size: st.size });\n } catch (error) {\n skipped.push({\n path: p,\n reason: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return { removed, skipped };\n}\n"],"mappings":";AAkCA,eAAsB,eACpB,UACA,UAAwB,EAAE,EACJ;CACtB,MAAM,EAAE,IAAI,WAAW;CACvB,MAAM,aAAa,QAAQ,aAAa,SAAS,QAAQ,OAAO,IAAI;CAEpE,MAAM,eAAe;EAAC;EAAgB;EAAW;EAAY;CAE7D,MAAM,oBAAoB;EACxB,GAAG,UAAU;EACb,GAAG,UAAU;EACb,GAAG,UAAU;EACb,GAAG,UAAU;EACb,GAAG,UAAU;EACb,GAAG,UAAU;EACb,GAAG,UAAU;EACb,GAAG,UAAU;EACd;CAED,MAAM,WAAW,QAAQ,gBACrB,CAAC,GAAG,cAAc,GAAG,kBAAkB,GACvC;EACE,GAAG;EACH;EACA;EACA;EACA,GAAG;EACJ;CAEL,MAAM,aAAa,MAAM,GAAG,KAAK;EAC/B;EACA,QAAQ,CAAC,kBAAkB;EAC5B,CAAC;CAEF,MAAMA,UAA4C,EAAE;CACpD,MAAMC,UAA8C,EAAE;AAEtD,MAAK,MAAM,KAAK,WACd,KAAI;EACF,MAAM,KAAK,MAAM,GAAG,KAAK,EAAE;EAC3B,MAAM,WAAW,KAAK,KAAK,GAAG,GAAG,MAAM,SAAS,KAAK,MAAO,KAAK,KAAK;AACtE,MACE,OAAO,QAAQ,kBAAkB,YACjC,UAAU,QAAQ,eAClB;AACA,WAAQ,KAAK;IACX,MAAM;IACN,QAAQ,gBAAgB,QAAQ,cAAc;IAC/C,CAAC;AACF;;AAGF,MAAI,QAAQ,OACV,QAAO,KAAK,gCAAgC;GAAE,MAAM;GAAG,MAAM,GAAG;GAAM,CAAC;OAClE;AACL,SAAM,GAAG,OAAO,EAAE;AAClB,UAAO,KAAK,iBAAiB;IAAE,MAAM;IAAG,MAAM,GAAG;IAAM,CAAC;;AAE1D,UAAQ,KAAK;GAAE,MAAM;GAAG,MAAM,GAAG;GAAM,CAAC;UACjC,OAAO;AACd,UAAQ,KAAK;GACX,MAAM;GACN,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAC/D,CAAC;;AAIN,QAAO;EAAE;EAAS;EAAS"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FsAdapter } from "../ports/fs.js";
|
|
2
|
+
import { WorkspaceConfig } from "@lssm/module.contractspec-workspace";
|
|
3
|
+
|
|
4
|
+
//#region src/services/config.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Load workspace configuration from .contractsrc.json.
|
|
8
|
+
*/
|
|
9
|
+
declare function loadWorkspaceConfig(fs: FsAdapter, cwd?: string): Promise<WorkspaceConfig>;
|
|
10
|
+
/**
|
|
11
|
+
* Merge config with CLI options and environment variables.
|
|
12
|
+
*/
|
|
13
|
+
declare function mergeWorkspaceConfig(config: WorkspaceConfig, options: {
|
|
14
|
+
provider?: string;
|
|
15
|
+
model?: string;
|
|
16
|
+
agentMode?: string;
|
|
17
|
+
endpoint?: string;
|
|
18
|
+
outputDir?: string;
|
|
19
|
+
}): WorkspaceConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Get API key for the configured provider.
|
|
22
|
+
*/
|
|
23
|
+
declare function getApiKey(provider: WorkspaceConfig['aiProvider']): string | undefined;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { getApiKey, loadWorkspaceConfig, mergeWorkspaceConfig };
|
|
26
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","names":[],"sources":["../../src/services/config.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAoCU,iBAHY,mBAAA,CAGZ,EAAA,EAFJ,SAEI,EAAA,GAAA,CAAA,EAAA,MAAA,CAAA,EAAP,OAAO,CAAC,eAAD,CAAA;AAoBV;AA0CA;;iBA1CgB,oBAAA,SACN;;;;;;IAQP;;;;iBAiCa,SAAA,WACJ"}
|
package/dist/services/config.js
CHANGED
|
@@ -1 +1,77 @@
|
|
|
1
|
-
import{DEFAULT_WORKSPACE_CONFIG
|
|
1
|
+
import { DEFAULT_WORKSPACE_CONFIG } from "@lssm/module.contractspec-workspace";
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/services/config.ts
|
|
5
|
+
/**
|
|
6
|
+
* Workspace configuration service.
|
|
7
|
+
*/
|
|
8
|
+
const ConfigSchema = z.object({
|
|
9
|
+
aiProvider: z.enum([
|
|
10
|
+
"claude",
|
|
11
|
+
"openai",
|
|
12
|
+
"ollama",
|
|
13
|
+
"custom"
|
|
14
|
+
]).default("claude"),
|
|
15
|
+
aiModel: z.string().optional(),
|
|
16
|
+
agentMode: z.enum([
|
|
17
|
+
"simple",
|
|
18
|
+
"cursor",
|
|
19
|
+
"claude-code",
|
|
20
|
+
"openai-codex"
|
|
21
|
+
]).default("simple"),
|
|
22
|
+
customEndpoint: z.string().url().nullable().optional(),
|
|
23
|
+
customApiKey: z.string().nullable().optional(),
|
|
24
|
+
outputDir: z.string().default("./src"),
|
|
25
|
+
conventions: z.object({
|
|
26
|
+
operations: z.string().default("interactions/commands|queries"),
|
|
27
|
+
events: z.string().default("events"),
|
|
28
|
+
presentations: z.string().default("presentations"),
|
|
29
|
+
forms: z.string().default("forms")
|
|
30
|
+
}),
|
|
31
|
+
defaultOwners: z.array(z.string()).default([]),
|
|
32
|
+
defaultTags: z.array(z.string()).default([])
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Load workspace configuration from .contractsrc.json.
|
|
36
|
+
*/
|
|
37
|
+
async function loadWorkspaceConfig(fs, cwd) {
|
|
38
|
+
const configPath = fs.join(cwd ?? ".", ".contractsrc.json");
|
|
39
|
+
if (!await fs.exists(configPath)) return DEFAULT_WORKSPACE_CONFIG;
|
|
40
|
+
try {
|
|
41
|
+
const content = await fs.readFile(configPath);
|
|
42
|
+
const parsed = JSON.parse(content);
|
|
43
|
+
return ConfigSchema.parse(parsed);
|
|
44
|
+
} catch {
|
|
45
|
+
return DEFAULT_WORKSPACE_CONFIG;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Merge config with CLI options and environment variables.
|
|
50
|
+
*/
|
|
51
|
+
function mergeWorkspaceConfig(config, options) {
|
|
52
|
+
return {
|
|
53
|
+
...config,
|
|
54
|
+
aiProvider: options.provider ?? process.env["CONTRACTSPEC_AI_PROVIDER"] ?? config.aiProvider,
|
|
55
|
+
aiModel: options.model ?? process.env["CONTRACTSPEC_AI_MODEL"] ?? config.aiModel,
|
|
56
|
+
agentMode: options.agentMode ?? process.env["CONTRACTSPEC_AGENT_MODE"] ?? config.agentMode,
|
|
57
|
+
customEndpoint: options.endpoint ?? process.env["CONTRACTSPEC_LLM_ENDPOINT"] ?? config.customEndpoint ?? void 0,
|
|
58
|
+
customApiKey: process.env["CONTRACTSPEC_LLM_API_KEY"] ?? config.customApiKey ?? void 0,
|
|
59
|
+
outputDir: options.outputDir ?? config.outputDir
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get API key for the configured provider.
|
|
64
|
+
*/
|
|
65
|
+
function getApiKey(provider) {
|
|
66
|
+
switch (provider) {
|
|
67
|
+
case "claude": return process.env["ANTHROPIC_API_KEY"];
|
|
68
|
+
case "openai": return process.env["OPENAI_API_KEY"];
|
|
69
|
+
case "custom": return process.env["CONTRACTSPEC_LLM_API_KEY"];
|
|
70
|
+
case "ollama": return;
|
|
71
|
+
default: return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
export { getApiKey, loadWorkspaceConfig, mergeWorkspaceConfig };
|
|
77
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../../src/services/config.ts"],"sourcesContent":["/**\n * Workspace configuration service.\n */\n\nimport * as z from 'zod';\nimport type { WorkspaceConfig } from '@lssm/module.contractspec-workspace';\nimport { DEFAULT_WORKSPACE_CONFIG } from '@lssm/module.contractspec-workspace';\nimport type { FsAdapter } from '../ports/fs';\n\nconst ConfigSchema = z.object({\n aiProvider: z\n .enum(['claude', 'openai', 'ollama', 'custom'])\n .default('claude'),\n aiModel: z.string().optional(),\n agentMode: z\n .enum(['simple', 'cursor', 'claude-code', 'openai-codex'])\n .default('simple'),\n customEndpoint: z.string().url().nullable().optional(),\n customApiKey: z.string().nullable().optional(),\n outputDir: z.string().default('./src'),\n conventions: z.object({\n operations: z.string().default('interactions/commands|queries'),\n events: z.string().default('events'),\n presentations: z.string().default('presentations'),\n forms: z.string().default('forms'),\n }),\n defaultOwners: z.array(z.string()).default([]),\n defaultTags: z.array(z.string()).default([]),\n});\n\n/**\n * Load workspace configuration from .contractsrc.json.\n */\nexport async function loadWorkspaceConfig(\n fs: FsAdapter,\n cwd?: string\n): Promise<WorkspaceConfig> {\n const configPath = fs.join(cwd ?? '.', '.contractsrc.json');\n\n const exists = await fs.exists(configPath);\n if (!exists) {\n return DEFAULT_WORKSPACE_CONFIG;\n }\n\n try {\n const content = await fs.readFile(configPath);\n const parsed = JSON.parse(content);\n return ConfigSchema.parse(parsed) as WorkspaceConfig;\n } catch {\n return DEFAULT_WORKSPACE_CONFIG;\n }\n}\n\n/**\n * Merge config with CLI options and environment variables.\n */\nexport function mergeWorkspaceConfig(\n config: WorkspaceConfig,\n options: {\n provider?: string;\n model?: string;\n agentMode?: string;\n endpoint?: string;\n outputDir?: string;\n }\n): WorkspaceConfig {\n return {\n ...config,\n aiProvider:\n (options.provider as WorkspaceConfig['aiProvider']) ??\n (process.env[\n 'CONTRACTSPEC_AI_PROVIDER'\n ] as WorkspaceConfig['aiProvider']) ??\n config.aiProvider,\n aiModel:\n options.model ?? process.env['CONTRACTSPEC_AI_MODEL'] ?? config.aiModel,\n agentMode:\n (options.agentMode as WorkspaceConfig['agentMode']) ??\n (process.env[\n 'CONTRACTSPEC_AGENT_MODE'\n ] as WorkspaceConfig['agentMode']) ??\n config.agentMode,\n customEndpoint:\n options.endpoint ??\n process.env['CONTRACTSPEC_LLM_ENDPOINT'] ??\n config.customEndpoint ??\n undefined,\n customApiKey:\n process.env['CONTRACTSPEC_LLM_API_KEY'] ??\n config.customApiKey ??\n undefined,\n outputDir: options.outputDir ?? config.outputDir,\n };\n}\n\n/**\n * Get API key for the configured provider.\n */\nexport function getApiKey(\n provider: WorkspaceConfig['aiProvider']\n): string | undefined {\n switch (provider) {\n case 'claude':\n return process.env['ANTHROPIC_API_KEY'];\n case 'openai':\n return process.env['OPENAI_API_KEY'];\n case 'custom':\n return process.env['CONTRACTSPEC_LLM_API_KEY'];\n case 'ollama':\n return undefined; // Ollama doesn't need API key for local\n default:\n return undefined;\n }\n}\n"],"mappings":";;;;;;;AASA,MAAM,eAAe,EAAE,OAAO;CAC5B,YAAY,EACT,KAAK;EAAC;EAAU;EAAU;EAAU;EAAS,CAAC,CAC9C,QAAQ,SAAS;CACpB,SAAS,EAAE,QAAQ,CAAC,UAAU;CAC9B,WAAW,EACR,KAAK;EAAC;EAAU;EAAU;EAAe;EAAe,CAAC,CACzD,QAAQ,SAAS;CACpB,gBAAgB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU;CACtD,cAAc,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU;CAC9C,WAAW,EAAE,QAAQ,CAAC,QAAQ,QAAQ;CACtC,aAAa,EAAE,OAAO;EACpB,YAAY,EAAE,QAAQ,CAAC,QAAQ,gCAAgC;EAC/D,QAAQ,EAAE,QAAQ,CAAC,QAAQ,SAAS;EACpC,eAAe,EAAE,QAAQ,CAAC,QAAQ,gBAAgB;EAClD,OAAO,EAAE,QAAQ,CAAC,QAAQ,QAAQ;EACnC,CAAC;CACF,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;CAC9C,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;CAC7C,CAAC;;;;AAKF,eAAsB,oBACpB,IACA,KAC0B;CAC1B,MAAM,aAAa,GAAG,KAAK,OAAO,KAAK,oBAAoB;AAG3D,KAAI,CADW,MAAM,GAAG,OAAO,WAAW,CAExC,QAAO;AAGT,KAAI;EACF,MAAM,UAAU,MAAM,GAAG,SAAS,WAAW;EAC7C,MAAM,SAAS,KAAK,MAAM,QAAQ;AAClC,SAAO,aAAa,MAAM,OAAO;SAC3B;AACN,SAAO;;;;;;AAOX,SAAgB,qBACd,QACA,SAOiB;AACjB,QAAO;EACL,GAAG;EACH,YACG,QAAQ,YACR,QAAQ,IACP,+BAEF,OAAO;EACT,SACE,QAAQ,SAAS,QAAQ,IAAI,4BAA4B,OAAO;EAClE,WACG,QAAQ,aACR,QAAQ,IACP,8BAEF,OAAO;EACT,gBACE,QAAQ,YACR,QAAQ,IAAI,gCACZ,OAAO,kBACP;EACF,cACE,QAAQ,IAAI,+BACZ,OAAO,gBACP;EACF,WAAW,QAAQ,aAAa,OAAO;EACxC;;;;;AAMH,SAAgB,UACd,UACoB;AACpB,SAAQ,UAAR;EACE,KAAK,SACH,QAAO,QAAQ,IAAI;EACrB,KAAK,SACH,QAAO,QAAQ,IAAI;EACrB,KAAK,SACH,QAAO,QAAQ,IAAI;EACrB,KAAK,SACH;EACF,QACE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { FsAdapter } from "../ports/fs.js";
|
|
2
|
+
import { ContractGraph, ContractNode } from "@lssm/module.contractspec-workspace";
|
|
3
|
+
|
|
4
|
+
//#region src/services/deps.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Options for dependency analysis.
|
|
8
|
+
*/
|
|
9
|
+
interface AnalyzeDepsOptions {
|
|
10
|
+
/**
|
|
11
|
+
* File pattern to search.
|
|
12
|
+
*/
|
|
13
|
+
pattern?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Result of dependency analysis.
|
|
17
|
+
*/
|
|
18
|
+
interface AnalyzeDepsResult {
|
|
19
|
+
graph: ContractGraph;
|
|
20
|
+
total: number;
|
|
21
|
+
cycles: string[][];
|
|
22
|
+
missing: {
|
|
23
|
+
contract: string;
|
|
24
|
+
missing: string[];
|
|
25
|
+
}[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Analyze contract dependencies.
|
|
29
|
+
*/
|
|
30
|
+
declare function analyzeDeps(adapters: {
|
|
31
|
+
fs: FsAdapter;
|
|
32
|
+
}, options?: AnalyzeDepsOptions): Promise<AnalyzeDepsResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Get contract node by name.
|
|
35
|
+
*/
|
|
36
|
+
declare function getContractNode(graph: ContractGraph, name: string): ContractNode | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Export graph as DOT format.
|
|
39
|
+
*/
|
|
40
|
+
declare function exportGraphAsDot(graph: ContractGraph): string;
|
|
41
|
+
/**
|
|
42
|
+
* Get graph statistics.
|
|
43
|
+
*/
|
|
44
|
+
declare function getGraphStats(graph: ContractGraph): {
|
|
45
|
+
total: number;
|
|
46
|
+
withDeps: number;
|
|
47
|
+
withoutDeps: number;
|
|
48
|
+
used: number;
|
|
49
|
+
unused: number;
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
export { AnalyzeDepsOptions, AnalyzeDepsResult, analyzeDeps, exportGraphAsDot, getContractNode, getGraphStats };
|
|
53
|
+
//# sourceMappingURL=deps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps.d.ts","names":[],"sources":["../../src/services/deps.ts"],"sourcesContent":[],"mappings":";;;;;AA8BA;AAUA;;AAEW,UAtBM,kBAAA,CAsBN;EACA;;;EA4CK,OAAA,CAAA,EAAA,MAAA;AAUhB;AAOA;;;UA1EiB,iBAAA;SACR;;;;;;;;;;;iBASa,WAAA;MACJ;aACP,qBACR,QAAQ;;;;iBA4CK,eAAA,QACP,8BAEN;;;;iBAOa,gBAAA,QAAwB;;;;iBAOxB,aAAA,QAAqB"}
|
package/dist/services/deps.js
CHANGED
|
@@ -1 +1,62 @@
|
|
|
1
|
-
import{addContractNode
|
|
1
|
+
import { addContractNode, buildReverseEdges, createContractGraph, detectCycles, findMissingDependencies, parseImportedSpecNames, toDot } from "@lssm/module.contractspec-workspace";
|
|
2
|
+
|
|
3
|
+
//#region src/services/deps.ts
|
|
4
|
+
/**
|
|
5
|
+
* Dependency analysis service.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Analyze contract dependencies.
|
|
9
|
+
*/
|
|
10
|
+
async function analyzeDeps(adapters, options = {}) {
|
|
11
|
+
const { fs } = adapters;
|
|
12
|
+
const files = await fs.glob({ pattern: options.pattern });
|
|
13
|
+
const graph = createContractGraph();
|
|
14
|
+
for (const file of files) {
|
|
15
|
+
const content = await fs.readFile(file);
|
|
16
|
+
const relativePath = fs.relative(".", file);
|
|
17
|
+
const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
|
|
18
|
+
addContractNode(graph, (nameMatch?.[1] ? nameMatch[1] : fs.basename(file).replace(/\.[jt]s$/, "").replace(/\.(contracts|contract|operation|operations|event|presentation|workflow|data-view|migration|telemetry|experiment|app-config|integration|knowledge)$/, "")) || "unknown", relativePath, parseImportedSpecNames(content, file));
|
|
19
|
+
}
|
|
20
|
+
buildReverseEdges(graph);
|
|
21
|
+
const cycles = detectCycles(graph);
|
|
22
|
+
const missing = findMissingDependencies(graph);
|
|
23
|
+
return {
|
|
24
|
+
graph,
|
|
25
|
+
total: graph.size,
|
|
26
|
+
cycles,
|
|
27
|
+
missing
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get contract node by name.
|
|
32
|
+
*/
|
|
33
|
+
function getContractNode(graph, name) {
|
|
34
|
+
return graph.get(name);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Export graph as DOT format.
|
|
38
|
+
*/
|
|
39
|
+
function exportGraphAsDot(graph) {
|
|
40
|
+
return toDot(graph);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get graph statistics.
|
|
44
|
+
*/
|
|
45
|
+
function getGraphStats(graph) {
|
|
46
|
+
const all = Array.from(graph.values());
|
|
47
|
+
const withDeps = all.filter((c) => c.dependencies.length > 0);
|
|
48
|
+
const withoutDeps = all.filter((c) => c.dependencies.length === 0);
|
|
49
|
+
const used = all.filter((c) => c.dependents.length > 0);
|
|
50
|
+
const unused = all.filter((c) => c.dependents.length === 0);
|
|
51
|
+
return {
|
|
52
|
+
total: graph.size,
|
|
53
|
+
withDeps: withDeps.length,
|
|
54
|
+
withoutDeps: withoutDeps.length,
|
|
55
|
+
used: used.length,
|
|
56
|
+
unused: unused.length
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { analyzeDeps, exportGraphAsDot, getContractNode, getGraphStats };
|
|
62
|
+
//# sourceMappingURL=deps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps.js","names":[],"sources":["../../src/services/deps.ts"],"sourcesContent":["/**\n * Dependency analysis service.\n */\n\nimport {\n addContractNode,\n buildReverseEdges,\n type ContractGraph,\n type ContractNode,\n createContractGraph,\n detectCycles,\n findMissingDependencies,\n parseImportedSpecNames,\n toDot,\n} from '@lssm/module.contractspec-workspace';\nimport type { FsAdapter } from '../ports/fs';\n\n/**\n * Options for dependency analysis.\n */\nexport interface AnalyzeDepsOptions {\n /**\n * File pattern to search.\n */\n pattern?: string;\n}\n\n/**\n * Result of dependency analysis.\n */\nexport interface AnalyzeDepsResult {\n graph: ContractGraph;\n total: number;\n cycles: string[][];\n missing: { contract: string; missing: string[] }[];\n}\n\n/**\n * Analyze contract dependencies.\n */\nexport async function analyzeDeps(\n adapters: { fs: FsAdapter },\n options: AnalyzeDepsOptions = {}\n): Promise<AnalyzeDepsResult> {\n const { fs } = adapters;\n\n const files = await fs.glob({ pattern: options.pattern });\n const graph = createContractGraph();\n\n for (const file of files) {\n const content = await fs.readFile(file);\n const relativePath = fs.relative('.', file);\n\n // Prefer explicit meta.name if present; otherwise fall back to filename stem\n const nameMatch = content.match(/name:\\s*['\"]([^'\"]+)['\"]/);\n const inferredName = nameMatch?.[1]\n ? nameMatch[1]\n : fs\n .basename(file)\n .replace(/\\.[jt]s$/, '')\n .replace(\n /\\.(contracts|contract|operation|operations|event|presentation|workflow|data-view|migration|telemetry|experiment|app-config|integration|knowledge)$/,\n ''\n );\n\n const finalName = inferredName || 'unknown';\n const dependencies = parseImportedSpecNames(content, file);\n\n addContractNode(graph, finalName, relativePath, dependencies);\n }\n\n buildReverseEdges(graph);\n\n const cycles = detectCycles(graph);\n const missing = findMissingDependencies(graph);\n\n return {\n graph,\n total: graph.size,\n cycles,\n missing,\n };\n}\n\n/**\n * Get contract node by name.\n */\nexport function getContractNode(\n graph: ContractGraph,\n name: string\n): ContractNode | undefined {\n return graph.get(name);\n}\n\n/**\n * Export graph as DOT format.\n */\nexport function exportGraphAsDot(graph: ContractGraph): string {\n return toDot(graph);\n}\n\n/**\n * Get graph statistics.\n */\nexport function getGraphStats(graph: ContractGraph): {\n total: number;\n withDeps: number;\n withoutDeps: number;\n used: number;\n unused: number;\n} {\n const all = Array.from(graph.values());\n const withDeps = all.filter((c) => c.dependencies.length > 0);\n const withoutDeps = all.filter((c) => c.dependencies.length === 0);\n const used = all.filter((c) => c.dependents.length > 0);\n const unused = all.filter((c) => c.dependents.length === 0);\n\n return {\n total: graph.size,\n withDeps: withDeps.length,\n withoutDeps: withoutDeps.length,\n used: used.length,\n unused: unused.length,\n };\n}\n"],"mappings":";;;;;;;;;AAwCA,eAAsB,YACpB,UACA,UAA8B,EAAE,EACJ;CAC5B,MAAM,EAAE,OAAO;CAEf,MAAM,QAAQ,MAAM,GAAG,KAAK,EAAE,SAAS,QAAQ,SAAS,CAAC;CACzD,MAAM,QAAQ,qBAAqB;AAEnC,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,UAAU,MAAM,GAAG,SAAS,KAAK;EACvC,MAAM,eAAe,GAAG,SAAS,KAAK,KAAK;EAG3C,MAAM,YAAY,QAAQ,MAAM,2BAA2B;AAc3D,kBAAgB,QAbK,YAAY,KAC7B,UAAU,KACV,GACG,SAAS,KAAK,CACd,QAAQ,YAAY,GAAG,CACvB,QACC,sJACA,GACD,KAE2B,WAGA,cAFb,uBAAuB,SAAS,KAAK,CAEG;;AAG/D,mBAAkB,MAAM;CAExB,MAAM,SAAS,aAAa,MAAM;CAClC,MAAM,UAAU,wBAAwB,MAAM;AAE9C,QAAO;EACL;EACA,OAAO,MAAM;EACb;EACA;EACD;;;;;AAMH,SAAgB,gBACd,OACA,MAC0B;AAC1B,QAAO,MAAM,IAAI,KAAK;;;;;AAMxB,SAAgB,iBAAiB,OAA8B;AAC7D,QAAO,MAAM,MAAM;;;;;AAMrB,SAAgB,cAAc,OAM5B;CACA,MAAM,MAAM,MAAM,KAAK,MAAM,QAAQ,CAAC;CACtC,MAAM,WAAW,IAAI,QAAQ,MAAM,EAAE,aAAa,SAAS,EAAE;CAC7D,MAAM,cAAc,IAAI,QAAQ,MAAM,EAAE,aAAa,WAAW,EAAE;CAClE,MAAM,OAAO,IAAI,QAAQ,MAAM,EAAE,WAAW,SAAS,EAAE;CACvD,MAAM,SAAS,IAAI,QAAQ,MAAM,EAAE,WAAW,WAAW,EAAE;AAE3D,QAAO;EACL,OAAO,MAAM;EACb,UAAU,SAAS;EACnB,aAAa,YAAY;EACzB,MAAM,KAAK;EACX,QAAQ,OAAO;EAChB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { FsAdapter } from "../ports/fs.js";
|
|
2
|
+
import { GitAdapter } from "../ports/git.js";
|
|
3
|
+
import { SemanticDiffItem, SemanticDiffOptions } from "@lssm/module.contractspec-workspace";
|
|
4
|
+
|
|
5
|
+
//#region src/services/diff.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for comparing specs.
|
|
9
|
+
*/
|
|
10
|
+
interface CompareSpecsOptions extends SemanticDiffOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Git ref to compare against (branch, tag, commit).
|
|
13
|
+
* If provided, spec2 is loaded from this ref instead of filesystem.
|
|
14
|
+
*/
|
|
15
|
+
baseline?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Result of spec comparison.
|
|
19
|
+
*/
|
|
20
|
+
interface CompareSpecsResult {
|
|
21
|
+
spec1: string;
|
|
22
|
+
spec2: string;
|
|
23
|
+
differences: SemanticDiffItem[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Compare two spec files semantically.
|
|
27
|
+
*/
|
|
28
|
+
declare function compareSpecs(spec1Path: string, spec2Path: string, adapters: {
|
|
29
|
+
fs: FsAdapter;
|
|
30
|
+
git: GitAdapter;
|
|
31
|
+
}, options?: CompareSpecsOptions): Promise<CompareSpecsResult>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { CompareSpecsOptions, CompareSpecsResult, compareSpecs };
|
|
34
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","names":[],"sources":["../../src/services/diff.ts"],"sourcesContent":[],"mappings":";;;;;;AA0BA;AASA;;AAGkC,UAvBjB,mBAAA,SAA4B,mBAuBX,CAAA;EACvB;;;;;;;;;UAbM,kBAAA;;;eAGF;;;;;iBAMO,YAAA;MAGJ;OAAgB;aACvB,sBACR,QAAQ"}
|
package/dist/services/diff.js
CHANGED
|
@@ -1 +1,34 @@
|
|
|
1
|
-
import{computeSemanticDiff
|
|
1
|
+
import { computeSemanticDiff } from "@lssm/module.contractspec-workspace";
|
|
2
|
+
|
|
3
|
+
//#region src/services/diff.ts
|
|
4
|
+
/**
|
|
5
|
+
* Diff service.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Compare two spec files semantically.
|
|
9
|
+
*/
|
|
10
|
+
async function compareSpecs(spec1Path, spec2Path, adapters, options = {}) {
|
|
11
|
+
const { fs, git } = adapters;
|
|
12
|
+
if (!await fs.exists(spec1Path)) throw new Error(`Spec file not found: ${spec1Path}`);
|
|
13
|
+
const spec1Code = await fs.readFile(spec1Path);
|
|
14
|
+
let spec2Code;
|
|
15
|
+
let spec2Label;
|
|
16
|
+
if (options.baseline) {
|
|
17
|
+
spec2Code = await git.showFile(options.baseline, spec1Path);
|
|
18
|
+
spec2Label = `${options.baseline}:${spec1Path}`;
|
|
19
|
+
} else {
|
|
20
|
+
if (!await fs.exists(spec2Path)) throw new Error(`Spec file not found: ${spec2Path}`);
|
|
21
|
+
spec2Code = await fs.readFile(spec2Path);
|
|
22
|
+
spec2Label = spec2Path;
|
|
23
|
+
}
|
|
24
|
+
const differences = computeSemanticDiff(spec1Code, spec1Path, spec2Code, spec2Label, { breakingOnly: options.breakingOnly });
|
|
25
|
+
return {
|
|
26
|
+
spec1: spec1Path,
|
|
27
|
+
spec2: spec2Label,
|
|
28
|
+
differences
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { compareSpecs };
|
|
34
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","names":["spec2Code: string","spec2Label: string"],"sources":["../../src/services/diff.ts"],"sourcesContent":["/**\n * Diff service.\n */\n\nimport {\n computeSemanticDiff,\n type SemanticDiffItem,\n type SemanticDiffOptions,\n} from '@lssm/module.contractspec-workspace';\nimport type { FsAdapter } from '../ports/fs';\nimport type { GitAdapter } from '../ports/git';\n\n/**\n * Options for comparing specs.\n */\nexport interface CompareSpecsOptions extends SemanticDiffOptions {\n /**\n * Git ref to compare against (branch, tag, commit).\n * If provided, spec2 is loaded from this ref instead of filesystem.\n */\n baseline?: string;\n}\n\n/**\n * Result of spec comparison.\n */\nexport interface CompareSpecsResult {\n spec1: string;\n spec2: string;\n differences: SemanticDiffItem[];\n}\n\n/**\n * Compare two spec files semantically.\n */\nexport async function compareSpecs(\n spec1Path: string,\n spec2Path: string,\n adapters: { fs: FsAdapter; git: GitAdapter },\n options: CompareSpecsOptions = {}\n): Promise<CompareSpecsResult> {\n const { fs, git } = adapters;\n\n // Load first spec from filesystem\n const exists1 = await fs.exists(spec1Path);\n if (!exists1) {\n throw new Error(`Spec file not found: ${spec1Path}`);\n }\n const spec1Code = await fs.readFile(spec1Path);\n\n // Load second spec either from git baseline or filesystem\n let spec2Code: string;\n let spec2Label: string;\n\n if (options.baseline) {\n spec2Code = await git.showFile(options.baseline, spec1Path);\n spec2Label = `${options.baseline}:${spec1Path}`;\n } else {\n const exists2 = await fs.exists(spec2Path);\n if (!exists2) {\n throw new Error(`Spec file not found: ${spec2Path}`);\n }\n spec2Code = await fs.readFile(spec2Path);\n spec2Label = spec2Path;\n }\n\n // Compute semantic diff\n const differences = computeSemanticDiff(\n spec1Code,\n spec1Path,\n spec2Code,\n spec2Label,\n { breakingOnly: options.breakingOnly }\n );\n\n return {\n spec1: spec1Path,\n spec2: spec2Label,\n differences,\n };\n}\n"],"mappings":";;;;;;;;;AAmCA,eAAsB,aACpB,WACA,WACA,UACA,UAA+B,EAAE,EACJ;CAC7B,MAAM,EAAE,IAAI,QAAQ;AAIpB,KAAI,CADY,MAAM,GAAG,OAAO,UAAU,CAExC,OAAM,IAAI,MAAM,wBAAwB,YAAY;CAEtD,MAAM,YAAY,MAAM,GAAG,SAAS,UAAU;CAG9C,IAAIA;CACJ,IAAIC;AAEJ,KAAI,QAAQ,UAAU;AACpB,cAAY,MAAM,IAAI,SAAS,QAAQ,UAAU,UAAU;AAC3D,eAAa,GAAG,QAAQ,SAAS,GAAG;QAC/B;AAEL,MAAI,CADY,MAAM,GAAG,OAAO,UAAU,CAExC,OAAM,IAAI,MAAM,wBAAwB,YAAY;AAEtD,cAAY,MAAM,GAAG,SAAS,UAAU;AACxC,eAAa;;CAIf,MAAM,cAAc,oBAClB,WACA,WACA,WACA,YACA,EAAE,cAAc,QAAQ,cAAc,CACvC;AAED,QAAO;EACL,OAAO;EACP,OAAO;EACP;EACD"}
|
|
@@ -1,2 +1,119 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/services/doctor/checks/ai.ts
|
|
2
|
+
/**
|
|
3
|
+
* Run AI provider-related health checks.
|
|
4
|
+
*/
|
|
5
|
+
async function runAiChecks(fs, ctx, prompts) {
|
|
6
|
+
const results = [];
|
|
7
|
+
const providerResult = await checkAiProvider(fs, ctx);
|
|
8
|
+
results.push(providerResult);
|
|
9
|
+
if (providerResult.status === "pass") results.push(await checkApiKey(fs, ctx, prompts));
|
|
10
|
+
return results;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check which AI provider is configured.
|
|
14
|
+
*/
|
|
15
|
+
async function checkAiProvider(fs, ctx) {
|
|
16
|
+
const configPath = fs.join(ctx.workspaceRoot, ".contractsrc.json");
|
|
17
|
+
try {
|
|
18
|
+
if (!await fs.exists(configPath)) return {
|
|
19
|
+
category: "ai",
|
|
20
|
+
name: "AI Provider",
|
|
21
|
+
status: "skip",
|
|
22
|
+
message: "No config file found"
|
|
23
|
+
};
|
|
24
|
+
const content = await fs.readFile(configPath);
|
|
25
|
+
const config = JSON.parse(content);
|
|
26
|
+
return {
|
|
27
|
+
category: "ai",
|
|
28
|
+
name: "AI Provider",
|
|
29
|
+
status: "pass",
|
|
30
|
+
message: `Provider: ${config.aiProvider ?? "claude"}, Model: ${config.aiModel ?? "default"}`
|
|
31
|
+
};
|
|
32
|
+
} catch {
|
|
33
|
+
return {
|
|
34
|
+
category: "ai",
|
|
35
|
+
name: "AI Provider",
|
|
36
|
+
status: "skip",
|
|
37
|
+
message: "Could not read AI config"
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if API key is set for the configured provider.
|
|
43
|
+
*/
|
|
44
|
+
async function checkApiKey(fs, ctx, prompts) {
|
|
45
|
+
const configPath = fs.join(ctx.workspaceRoot, ".contractsrc.json");
|
|
46
|
+
try {
|
|
47
|
+
const content = await fs.readFile(configPath);
|
|
48
|
+
const provider = JSON.parse(content).aiProvider ?? "claude";
|
|
49
|
+
const envVar = {
|
|
50
|
+
claude: "ANTHROPIC_API_KEY",
|
|
51
|
+
openai: "OPENAI_API_KEY",
|
|
52
|
+
ollama: "",
|
|
53
|
+
custom: "CONTRACTSPEC_LLM_API_KEY"
|
|
54
|
+
}[provider];
|
|
55
|
+
if (!envVar) return {
|
|
56
|
+
category: "ai",
|
|
57
|
+
name: "API Key",
|
|
58
|
+
status: "pass",
|
|
59
|
+
message: `${provider} does not require an API key`
|
|
60
|
+
};
|
|
61
|
+
if (!!process.env[envVar]) return {
|
|
62
|
+
category: "ai",
|
|
63
|
+
name: "API Key",
|
|
64
|
+
status: "pass",
|
|
65
|
+
message: `${envVar} is set`
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
category: "ai",
|
|
69
|
+
name: "API Key",
|
|
70
|
+
status: "warn",
|
|
71
|
+
message: `${envVar} not set`,
|
|
72
|
+
details: `Set ${envVar} in your environment to use AI features`,
|
|
73
|
+
fix: prompts ? {
|
|
74
|
+
description: `Set ${envVar} environment variable`,
|
|
75
|
+
apply: async () => {
|
|
76
|
+
const key = await prompts.input(`Enter your ${provider} API key:`, { password: true });
|
|
77
|
+
if (!key) return {
|
|
78
|
+
success: false,
|
|
79
|
+
message: "No API key provided"
|
|
80
|
+
};
|
|
81
|
+
const envPath = fs.join(ctx.workspaceRoot, ".env");
|
|
82
|
+
try {
|
|
83
|
+
let envContent = "";
|
|
84
|
+
if (await fs.exists(envPath)) {
|
|
85
|
+
envContent = await fs.readFile(envPath);
|
|
86
|
+
if (envContent.includes(`${envVar}=`)) return {
|
|
87
|
+
success: false,
|
|
88
|
+
message: `${envVar} already in .env, update manually`
|
|
89
|
+
};
|
|
90
|
+
envContent += "\n";
|
|
91
|
+
}
|
|
92
|
+
envContent += `${envVar}=${key}\n`;
|
|
93
|
+
await fs.writeFile(envPath, envContent);
|
|
94
|
+
return {
|
|
95
|
+
success: true,
|
|
96
|
+
message: `Added ${envVar} to .env (restart required)`
|
|
97
|
+
};
|
|
98
|
+
} catch (error) {
|
|
99
|
+
return {
|
|
100
|
+
success: false,
|
|
101
|
+
message: `Failed: ${error instanceof Error ? error.message : String(error)}`
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} : void 0
|
|
106
|
+
};
|
|
107
|
+
} catch {
|
|
108
|
+
return {
|
|
109
|
+
category: "ai",
|
|
110
|
+
name: "API Key",
|
|
111
|
+
status: "skip",
|
|
112
|
+
message: "Could not check API key"
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
export { runAiChecks };
|
|
119
|
+
//# sourceMappingURL=ai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.js","names":["results: CheckResult[]"],"sources":["../../../../src/services/doctor/checks/ai.ts"],"sourcesContent":["/**\n * AI provider health checks.\n */\n\nimport type { FsAdapter } from '../../../ports/fs';\nimport type {\n CheckResult,\n CheckContext,\n DoctorPromptCallbacks,\n FixResult,\n} from '../types';\n\n/**\n * Run AI provider-related health checks.\n */\nexport async function runAiChecks(\n fs: FsAdapter,\n ctx: CheckContext,\n prompts?: DoctorPromptCallbacks\n): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n // Check configured AI provider\n const providerResult = await checkAiProvider(fs, ctx);\n results.push(providerResult);\n\n // Check API key based on provider\n if (providerResult.status === 'pass') {\n results.push(await checkApiKey(fs, ctx, prompts));\n }\n\n return results;\n}\n\n/**\n * Check which AI provider is configured.\n */\nasync function checkAiProvider(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n try {\n const exists = await fs.exists(configPath);\n if (!exists) {\n return {\n category: 'ai',\n name: 'AI Provider',\n status: 'skip',\n message: 'No config file found',\n };\n }\n\n const content = await fs.readFile(configPath);\n const config = JSON.parse(content) as {\n aiProvider?: string;\n aiModel?: string;\n };\n\n const provider = config.aiProvider ?? 'claude';\n const model = config.aiModel ?? 'default';\n\n return {\n category: 'ai',\n name: 'AI Provider',\n status: 'pass',\n message: `Provider: ${provider}, Model: ${model}`,\n };\n } catch {\n return {\n category: 'ai',\n name: 'AI Provider',\n status: 'skip',\n message: 'Could not read AI config',\n };\n }\n}\n\n/**\n * Check if API key is set for the configured provider.\n */\nasync function checkApiKey(\n fs: FsAdapter,\n ctx: CheckContext,\n prompts?: DoctorPromptCallbacks\n): Promise<CheckResult> {\n const configPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n\n try {\n const content = await fs.readFile(configPath);\n const config = JSON.parse(content) as { aiProvider?: string };\n\n const provider = config.aiProvider ?? 'claude';\n\n // Map provider to env var\n const envVarMap: Record<string, string> = {\n claude: 'ANTHROPIC_API_KEY',\n openai: 'OPENAI_API_KEY',\n ollama: '', // Ollama doesn't need API key\n custom: 'CONTRACTSPEC_LLM_API_KEY',\n };\n\n const envVar = envVarMap[provider];\n\n // Ollama doesn't need an API key\n if (!envVar) {\n return {\n category: 'ai',\n name: 'API Key',\n status: 'pass',\n message: `${provider} does not require an API key`,\n };\n }\n\n const hasKey = !!process.env[envVar];\n\n if (hasKey) {\n return {\n category: 'ai',\n name: 'API Key',\n status: 'pass',\n message: `${envVar} is set`,\n };\n }\n\n return {\n category: 'ai',\n name: 'API Key',\n status: 'warn',\n message: `${envVar} not set`,\n details: `Set ${envVar} in your environment to use AI features`,\n fix: prompts\n ? {\n description: `Set ${envVar} environment variable`,\n apply: async (): Promise<FixResult> => {\n const key = await prompts.input(\n `Enter your ${provider} API key:`,\n { password: true }\n );\n\n if (!key) {\n return { success: false, message: 'No API key provided' };\n }\n\n // We can't actually set env vars permanently, but we can create a .env file\n const envPath = fs.join(ctx.workspaceRoot, '.env');\n try {\n let envContent = '';\n if (await fs.exists(envPath)) {\n envContent = await fs.readFile(envPath);\n // Check if var already exists\n if (envContent.includes(`${envVar}=`)) {\n return {\n success: false,\n message: `${envVar} already in .env, update manually`,\n };\n }\n envContent += '\\n';\n }\n\n envContent += `${envVar}=${key}\\n`;\n await fs.writeFile(envPath, envContent);\n\n return {\n success: true,\n message: `Added ${envVar} to .env (restart required)`,\n };\n } catch (error) {\n const msg =\n error instanceof Error ? error.message : String(error);\n return { success: false, message: `Failed: ${msg}` };\n }\n },\n }\n : undefined,\n };\n } catch {\n return {\n category: 'ai',\n name: 'API Key',\n status: 'skip',\n message: 'Could not check API key',\n };\n }\n}\n"],"mappings":";;;;AAeA,eAAsB,YACpB,IACA,KACA,SACwB;CACxB,MAAMA,UAAyB,EAAE;CAGjC,MAAM,iBAAiB,MAAM,gBAAgB,IAAI,IAAI;AACrD,SAAQ,KAAK,eAAe;AAG5B,KAAI,eAAe,WAAW,OAC5B,SAAQ,KAAK,MAAM,YAAY,IAAI,KAAK,QAAQ,CAAC;AAGnD,QAAO;;;;;AAMT,eAAe,gBACb,IACA,KACsB;CACtB,MAAM,aAAa,GAAG,KAAK,IAAI,eAAe,oBAAoB;AAElE,KAAI;AAEF,MAAI,CADW,MAAM,GAAG,OAAO,WAAW,CAExC,QAAO;GACL,UAAU;GACV,MAAM;GACN,QAAQ;GACR,SAAS;GACV;EAGH,MAAM,UAAU,MAAM,GAAG,SAAS,WAAW;EAC7C,MAAM,SAAS,KAAK,MAAM,QAAQ;AAQlC,SAAO;GACL,UAAU;GACV,MAAM;GACN,QAAQ;GACR,SAAS,aAPM,OAAO,cAAc,SAOL,WANnB,OAAO,WAAW;GAO/B;SACK;AACN,SAAO;GACL,UAAU;GACV,MAAM;GACN,QAAQ;GACR,SAAS;GACV;;;;;;AAOL,eAAe,YACb,IACA,KACA,SACsB;CACtB,MAAM,aAAa,GAAG,KAAK,IAAI,eAAe,oBAAoB;AAElE,KAAI;EACF,MAAM,UAAU,MAAM,GAAG,SAAS,WAAW;EAG7C,MAAM,WAFS,KAAK,MAAM,QAAQ,CAEV,cAAc;EAUtC,MAAM,SAPoC;GACxC,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACT,CAEwB;AAGzB,MAAI,CAAC,OACH,QAAO;GACL,UAAU;GACV,MAAM;GACN,QAAQ;GACR,SAAS,GAAG,SAAS;GACtB;AAKH,MAFe,CAAC,CAAC,QAAQ,IAAI,QAG3B,QAAO;GACL,UAAU;GACV,MAAM;GACN,QAAQ;GACR,SAAS,GAAG,OAAO;GACpB;AAGH,SAAO;GACL,UAAU;GACV,MAAM;GACN,QAAQ;GACR,SAAS,GAAG,OAAO;GACnB,SAAS,OAAO,OAAO;GACvB,KAAK,UACD;IACE,aAAa,OAAO,OAAO;IAC3B,OAAO,YAAgC;KACrC,MAAM,MAAM,MAAM,QAAQ,MACxB,cAAc,SAAS,YACvB,EAAE,UAAU,MAAM,CACnB;AAED,SAAI,CAAC,IACH,QAAO;MAAE,SAAS;MAAO,SAAS;MAAuB;KAI3D,MAAM,UAAU,GAAG,KAAK,IAAI,eAAe,OAAO;AAClD,SAAI;MACF,IAAI,aAAa;AACjB,UAAI,MAAM,GAAG,OAAO,QAAQ,EAAE;AAC5B,oBAAa,MAAM,GAAG,SAAS,QAAQ;AAEvC,WAAI,WAAW,SAAS,GAAG,OAAO,GAAG,CACnC,QAAO;QACL,SAAS;QACT,SAAS,GAAG,OAAO;QACpB;AAEH,qBAAc;;AAGhB,oBAAc,GAAG,OAAO,GAAG,IAAI;AAC/B,YAAM,GAAG,UAAU,SAAS,WAAW;AAEvC,aAAO;OACL,SAAS;OACT,SAAS,SAAS,OAAO;OAC1B;cACM,OAAO;AAGd,aAAO;OAAE,SAAS;OAAO,SAAS,WADhC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;OACJ;;;IAGzD,GACD;GACL;SACK;AACN,SAAO;GACL,UAAU;GACV,MAAM;GACN,QAAQ;GACR,SAAS;GACV"}
|