argustack 0.2.0 → 0.3.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/README.md +31 -115
- package/dist/adapters/board/board-sync.js +2 -2
- package/dist/adapters/board/board-sync.js.map +1 -1
- package/dist/adapters/board/md-parser.js +3 -3
- package/dist/adapters/board/md-parser.js.map +1 -1
- package/dist/adapters/board/skill-discovery.js +2 -2
- package/dist/adapters/board/skill-discovery.js.map +1 -1
- package/dist/adapters/board/skill-runner.js +2 -2
- package/dist/adapters/board/skill-runner.js.map +1 -1
- package/dist/adapters/board/store.d.ts.map +1 -1
- package/dist/adapters/board/store.js +11 -11
- package/dist/adapters/board/store.js.map +1 -1
- package/dist/adapters/csv/mapper.js +11 -11
- package/dist/adapters/csv/mapper.js.map +1 -1
- package/dist/adapters/csv/parser.d.ts.map +1 -1
- package/dist/adapters/csv/parser.js +8 -7
- package/dist/adapters/csv/parser.js.map +1 -1
- package/dist/adapters/csv/provider.js +4 -4
- package/dist/adapters/csv/provider.js.map +1 -1
- package/dist/adapters/db/client.js +2 -2
- package/dist/adapters/db/client.js.map +1 -1
- package/dist/adapters/db/index.js +1 -0
- package/dist/adapters/db/index.js.map +1 -1
- package/dist/adapters/db/mapper.js +1 -1
- package/dist/adapters/db/mapper.js.map +1 -1
- package/dist/adapters/db/provider.js +4 -4
- package/dist/adapters/db/provider.js.map +1 -1
- package/dist/adapters/db/sql-validator.js +2 -2
- package/dist/adapters/db/sql-validator.js.map +1 -1
- package/dist/adapters/docker/cli-docker-control.d.ts +13 -0
- package/dist/adapters/docker/cli-docker-control.d.ts.map +1 -0
- package/dist/adapters/docker/cli-docker-control.js +70 -0
- package/dist/adapters/docker/cli-docker-control.js.map +1 -0
- package/dist/adapters/docker/index.d.ts +2 -0
- package/dist/adapters/docker/index.d.ts.map +1 -0
- package/dist/adapters/docker/index.js +2 -0
- package/dist/adapters/docker/index.js.map +1 -0
- package/dist/adapters/git/mapper.js +1 -1
- package/dist/adapters/git/mapper.js.map +1 -1
- package/dist/adapters/git/provider.js +4 -4
- package/dist/adapters/git/provider.js.map +1 -1
- package/dist/adapters/github/mapper.js +3 -3
- package/dist/adapters/github/mapper.js.map +1 -1
- package/dist/adapters/github/provider.d.ts.map +1 -1
- package/dist/adapters/github/provider.js +2 -2
- package/dist/adapters/github/provider.js.map +1 -1
- package/dist/adapters/jira/mapper.js +4 -4
- package/dist/adapters/jira/mapper.js.map +1 -1
- package/dist/adapters/jira/provider.js +8 -8
- package/dist/adapters/jira/provider.js.map +1 -1
- package/dist/adapters/jira-proxy/client.js +4 -4
- package/dist/adapters/jira-proxy/client.js.map +1 -1
- package/dist/adapters/jira-proxy/config-loader.d.ts +9 -0
- package/dist/adapters/jira-proxy/config-loader.d.ts.map +1 -1
- package/dist/adapters/jira-proxy/config-loader.js +26 -3
- package/dist/adapters/jira-proxy/config-loader.js.map +1 -1
- package/dist/adapters/jira-proxy/index.d.ts +1 -1
- package/dist/adapters/jira-proxy/index.d.ts.map +1 -1
- package/dist/adapters/jira-proxy/index.js +1 -1
- package/dist/adapters/jira-proxy/index.js.map +1 -1
- package/dist/adapters/jira-proxy/mapper.js +2 -2
- package/dist/adapters/jira-proxy/mapper.js.map +1 -1
- package/dist/adapters/jira-proxy/provider.d.ts.map +1 -1
- package/dist/adapters/jira-proxy/provider.js +19 -8
- package/dist/adapters/jira-proxy/provider.js.map +1 -1
- package/dist/adapters/lmstudio/embedding-provider.js +4 -4
- package/dist/adapters/lmstudio/embedding-provider.js.map +1 -1
- package/dist/adapters/lsp/jsonrpc.js +1 -1
- package/dist/adapters/lsp/jsonrpc.js.map +1 -1
- package/dist/adapters/lsp/typescript-lsp.js +7 -7
- package/dist/adapters/lsp/typescript-lsp.js.map +1 -1
- package/dist/adapters/neo4j/client.js +2 -2
- package/dist/adapters/neo4j/client.js.map +1 -1
- package/dist/adapters/neo4j/graph-store.js +3 -3
- package/dist/adapters/neo4j/graph-store.js.map +1 -1
- package/dist/adapters/neo4j/mapper.js +4 -4
- package/dist/adapters/neo4j/mapper.js.map +1 -1
- package/dist/adapters/ollama/chat-llm.d.ts +24 -0
- package/dist/adapters/ollama/chat-llm.d.ts.map +1 -0
- package/dist/adapters/ollama/chat-llm.js +53 -0
- package/dist/adapters/ollama/chat-llm.js.map +1 -0
- package/dist/adapters/ollama/embedding-provider.d.ts +30 -0
- package/dist/adapters/ollama/embedding-provider.d.ts.map +1 -0
- package/dist/adapters/ollama/embedding-provider.js +124 -0
- package/dist/adapters/ollama/embedding-provider.js.map +1 -0
- package/dist/adapters/ollama/http-ollama-control.d.ts +24 -0
- package/dist/adapters/ollama/http-ollama-control.d.ts.map +1 -0
- package/dist/adapters/ollama/http-ollama-control.js +224 -0
- package/dist/adapters/ollama/http-ollama-control.js.map +1 -0
- package/dist/adapters/ollama/index.d.ts +6 -0
- package/dist/adapters/ollama/index.d.ts.map +1 -0
- package/dist/adapters/ollama/index.js +4 -0
- package/dist/adapters/ollama/index.js.map +1 -0
- package/dist/adapters/platform/index.d.ts +2 -0
- package/dist/adapters/platform/index.d.ts.map +1 -0
- package/dist/adapters/platform/index.js +2 -0
- package/dist/adapters/platform/index.js.map +1 -0
- package/dist/adapters/platform/node-platform-probe.d.ts +9 -0
- package/dist/adapters/platform/node-platform-probe.d.ts.map +1 -0
- package/dist/adapters/platform/node-platform-probe.js +88 -0
- package/dist/adapters/platform/node-platform-probe.js.map +1 -0
- package/dist/adapters/postgres/code-meta.js +13 -13
- package/dist/adapters/postgres/code-meta.js.map +1 -1
- package/dist/adapters/postgres/index.d.ts +2 -0
- package/dist/adapters/postgres/index.d.ts.map +1 -1
- package/dist/adapters/postgres/index.js +2 -0
- package/dist/adapters/postgres/index.js.map +1 -1
- package/dist/adapters/postgres/migrate-helpers.d.ts +43 -0
- package/dist/adapters/postgres/migrate-helpers.d.ts.map +1 -0
- package/dist/adapters/postgres/migrate-helpers.js +136 -0
- package/dist/adapters/postgres/migrate-helpers.js.map +1 -0
- package/dist/adapters/postgres/readiness-probe.d.ts +22 -0
- package/dist/adapters/postgres/readiness-probe.d.ts.map +1 -0
- package/dist/adapters/postgres/readiness-probe.js +47 -0
- package/dist/adapters/postgres/readiness-probe.js.map +1 -0
- package/dist/adapters/postgres/schema.d.ts +11 -1
- package/dist/adapters/postgres/schema.d.ts.map +1 -1
- package/dist/adapters/postgres/schema.js +159 -113
- package/dist/adapters/postgres/schema.js.map +1 -1
- package/dist/adapters/postgres/storage-commits.d.ts +13 -0
- package/dist/adapters/postgres/storage-commits.d.ts.map +1 -0
- package/dist/adapters/postgres/storage-commits.js +63 -0
- package/dist/adapters/postgres/storage-commits.js.map +1 -0
- package/dist/adapters/postgres/storage-dbschema.d.ts +14 -0
- package/dist/adapters/postgres/storage-dbschema.d.ts.map +1 -0
- package/dist/adapters/postgres/storage-dbschema.js +63 -0
- package/dist/adapters/postgres/storage-dbschema.js.map +1 -0
- package/dist/adapters/postgres/storage-graph.d.ts +18 -0
- package/dist/adapters/postgres/storage-graph.d.ts.map +1 -0
- package/dist/adapters/postgres/storage-graph.js +127 -0
- package/dist/adapters/postgres/storage-graph.js.map +1 -0
- package/dist/adapters/postgres/storage-issues.d.ts +26 -0
- package/dist/adapters/postgres/storage-issues.d.ts.map +1 -0
- package/dist/adapters/postgres/storage-issues.js +233 -0
- package/dist/adapters/postgres/storage-issues.js.map +1 -0
- package/dist/adapters/postgres/storage-prs.d.ts +15 -0
- package/dist/adapters/postgres/storage-prs.d.ts.map +1 -0
- package/dist/adapters/postgres/storage-prs.js +142 -0
- package/dist/adapters/postgres/storage-prs.js.map +1 -0
- package/dist/adapters/postgres/storage-query.d.ts +26 -0
- package/dist/adapters/postgres/storage-query.d.ts.map +1 -0
- package/dist/adapters/postgres/storage-query.js +74 -0
- package/dist/adapters/postgres/storage-query.js.map +1 -0
- package/dist/adapters/postgres/storage-search.d.ts +18 -0
- package/dist/adapters/postgres/storage-search.d.ts.map +1 -0
- package/dist/adapters/postgres/storage-search.js +90 -0
- package/dist/adapters/postgres/storage-search.js.map +1 -0
- package/dist/adapters/postgres/storage.d.ts +47 -31
- package/dist/adapters/postgres/storage.d.ts.map +1 -1
- package/dist/adapters/postgres/storage.js +86 -602
- package/dist/adapters/postgres/storage.js.map +1 -1
- package/dist/adapters/postgres/workspace-store.d.ts +26 -0
- package/dist/adapters/postgres/workspace-store.d.ts.map +1 -0
- package/dist/adapters/postgres/workspace-store.js +94 -0
- package/dist/adapters/postgres/workspace-store.js.map +1 -0
- package/dist/adapters/qdrant/client.js +1 -1
- package/dist/adapters/qdrant/client.js.map +1 -1
- package/dist/adapters/qdrant/mapper.d.ts.map +1 -1
- package/dist/adapters/qdrant/mapper.js +11 -4
- package/dist/adapters/qdrant/mapper.js.map +1 -1
- package/dist/adapters/qdrant/vector-store.d.ts +1 -0
- package/dist/adapters/qdrant/vector-store.d.ts.map +1 -1
- package/dist/adapters/qdrant/vector-store.js +40 -10
- package/dist/adapters/qdrant/vector-store.js.map +1 -1
- package/dist/adapters/tree-sitter/parser.d.ts.map +1 -1
- package/dist/adapters/tree-sitter/parser.js +12 -12
- package/dist/adapters/tree-sitter/parser.js.map +1 -1
- package/dist/adapters/voyage/embedding-provider.js +2 -2
- package/dist/adapters/voyage/embedding-provider.js.map +1 -1
- package/dist/cli/add/code.d.ts +3 -0
- package/dist/cli/add/code.d.ts.map +1 -0
- package/dist/cli/add/code.js +97 -0
- package/dist/cli/add/code.js.map +1 -0
- package/dist/cli/add/csv.d.ts +3 -0
- package/dist/cli/add/csv.d.ts.map +1 -0
- package/dist/cli/add/csv.js +26 -0
- package/dist/cli/add/csv.js.map +1 -0
- package/dist/cli/add/db.d.ts +3 -0
- package/dist/cli/add/db.d.ts.map +1 -0
- package/dist/cli/add/db.js +46 -0
- package/dist/cli/add/db.js.map +1 -0
- package/dist/cli/add/git.d.ts +3 -0
- package/dist/cli/add/git.d.ts.map +1 -0
- package/dist/cli/add/git.js +26 -0
- package/dist/cli/add/git.js.map +1 -0
- package/dist/cli/add/github.d.ts +3 -0
- package/dist/cli/add/github.d.ts.map +1 -0
- package/dist/cli/add/github.js +32 -0
- package/dist/cli/add/github.js.map +1 -0
- package/dist/cli/add/index.d.ts +3 -0
- package/dist/cli/add/index.d.ts.map +1 -0
- package/dist/cli/add/index.js +18 -0
- package/dist/cli/add/index.js.map +1 -0
- package/dist/cli/add/jira.d.ts +3 -0
- package/dist/cli/add/jira.d.ts.map +1 -0
- package/dist/cli/add/jira.js +45 -0
- package/dist/cli/add/jira.js.map +1 -0
- package/dist/cli/add/shared.d.ts +31 -0
- package/dist/cli/add/shared.d.ts.map +1 -0
- package/dist/cli/add/shared.js +102 -0
- package/dist/cli/add/shared.js.map +1 -0
- package/dist/cli/board-server.js +1 -1
- package/dist/cli/board-server.js.map +1 -1
- package/dist/cli/board.d.ts.map +1 -1
- package/dist/cli/board.js +11 -12
- package/dist/cli/board.js.map +1 -1
- package/dist/cli/code.d.ts.map +1 -1
- package/dist/cli/code.js +95 -193
- package/dist/cli/code.js.map +1 -1
- package/dist/cli/embed.d.ts.map +1 -1
- package/dist/cli/embed.js +21 -26
- package/dist/cli/embed.js.map +1 -1
- package/dist/cli/graph.d.ts.map +1 -1
- package/dist/cli/graph.js +37 -55
- package/dist/cli/graph.js.map +1 -1
- package/dist/cli/index.js +28 -25
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/cleanup.d.ts +11 -0
- package/dist/cli/init/cleanup.d.ts.map +1 -0
- package/dist/cli/init/cleanup.js +39 -0
- package/dist/cli/init/cleanup.js.map +1 -0
- package/dist/cli/init/generators.js +27 -27
- package/dist/cli/init/generators.js.map +1 -1
- package/dist/cli/init/index.d.ts +0 -10
- package/dist/cli/init/index.d.ts.map +1 -1
- package/dist/cli/init/index.js +386 -354
- package/dist/cli/init/index.js.map +1 -1
- package/dist/cli/init/presenter.d.ts +30 -0
- package/dist/cli/init/presenter.d.ts.map +1 -0
- package/dist/cli/init/presenter.js +152 -0
- package/dist/cli/init/presenter.js.map +1 -0
- package/dist/cli/init/prompts.d.ts +28 -0
- package/dist/cli/init/prompts.d.ts.map +1 -0
- package/dist/cli/init/prompts.js +110 -0
- package/dist/cli/init/prompts.js.map +1 -0
- package/dist/cli/init/setup-csv.js +2 -2
- package/dist/cli/init/setup-csv.js.map +1 -1
- package/dist/cli/init/setup-db.d.ts.map +1 -1
- package/dist/cli/init/setup-db.js +17 -14
- package/dist/cli/init/setup-db.js.map +1 -1
- package/dist/cli/init/setup-git.js +16 -16
- package/dist/cli/init/setup-git.js.map +1 -1
- package/dist/cli/init/setup-github.d.ts.map +1 -1
- package/dist/cli/init/setup-github.js +7 -5
- package/dist/cli/init/setup-github.js.map +1 -1
- package/dist/cli/init/setup-jira.d.ts.map +1 -1
- package/dist/cli/init/setup-jira.js +11 -9
- package/dist/cli/init/setup-jira.js.map +1 -1
- package/dist/cli/init/types.d.ts +4 -0
- package/dist/cli/init/types.d.ts.map +1 -1
- package/dist/cli/init/types.js +4 -4
- package/dist/cli/init/types.js.map +1 -1
- package/dist/cli/mcp-install.d.ts +1 -1
- package/dist/cli/mcp-install.d.ts.map +1 -1
- package/dist/cli/mcp-install.js +10 -24
- package/dist/cli/mcp-install.js.map +1 -1
- package/dist/cli/migrate-to-hub-impl.d.ts +51 -0
- package/dist/cli/migrate-to-hub-impl.d.ts.map +1 -0
- package/dist/cli/migrate-to-hub-impl.js +171 -0
- package/dist/cli/migrate-to-hub-impl.js.map +1 -0
- package/dist/cli/migrate-to-hub.d.ts +3 -0
- package/dist/cli/migrate-to-hub.d.ts.map +1 -0
- package/dist/cli/migrate-to-hub.js +90 -0
- package/dist/cli/migrate-to-hub.js.map +1 -0
- package/dist/cli/push.d.ts.map +1 -1
- package/dist/cli/push.js +62 -65
- package/dist/cli/push.js.map +1 -1
- package/dist/cli/sources.d.ts +0 -7
- package/dist/cli/sources.d.ts.map +1 -1
- package/dist/cli/sources.js +47 -112
- package/dist/cli/sources.js.map +1 -1
- package/dist/cli/status.d.ts +0 -3
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +95 -70
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/sync.d.ts +0 -10
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +186 -317
- package/dist/cli/sync.js.map +1 -1
- package/dist/cli/workspace/add.d.ts +3 -0
- package/dist/cli/workspace/add.d.ts.map +1 -0
- package/dist/cli/workspace/add.js +38 -0
- package/dist/cli/workspace/add.js.map +1 -0
- package/dist/cli/workspace/index.d.ts +3 -0
- package/dist/cli/workspace/index.d.ts.map +1 -0
- package/dist/cli/workspace/index.js +16 -0
- package/dist/cli/workspace/index.js.map +1 -0
- package/dist/cli/workspace/info.d.ts +3 -0
- package/dist/cli/workspace/info.d.ts.map +1 -0
- package/dist/cli/workspace/info.js +69 -0
- package/dist/cli/workspace/info.js.map +1 -0
- package/dist/cli/workspace/list.d.ts +3 -0
- package/dist/cli/workspace/list.d.ts.map +1 -0
- package/dist/cli/workspace/list.js +36 -0
- package/dist/cli/workspace/list.js.map +1 -0
- package/dist/cli/workspace/remove.d.ts +3 -0
- package/dist/cli/workspace/remove.d.ts.map +1 -0
- package/dist/cli/workspace/remove.js +43 -0
- package/dist/cli/workspace/remove.js.map +1 -0
- package/dist/cli/workspace/shared.d.ts +7 -0
- package/dist/cli/workspace/shared.d.ts.map +1 -0
- package/dist/cli/workspace/shared.js +17 -0
- package/dist/cli/workspace/shared.js.map +1 -0
- package/dist/cli/workspace/use.d.ts +3 -0
- package/dist/cli/workspace/use.d.ts.map +1 -0
- package/dist/cli/workspace/use.js +27 -0
- package/dist/cli/workspace/use.js.map +1 -0
- package/dist/code-intel/file-discovery.js +3 -3
- package/dist/code-intel/file-discovery.js.map +1 -1
- package/dist/code-intel/indexer.js +8 -8
- package/dist/code-intel/indexer.js.map +1 -1
- package/dist/code-intel/lsp-resolver.js +5 -5
- package/dist/code-intel/lsp-resolver.js.map +1 -1
- package/dist/code-intel/ranker.d.ts +14 -0
- package/dist/code-intel/ranker.d.ts.map +1 -1
- package/dist/code-intel/ranker.js +54 -0
- package/dist/code-intel/ranker.js.map +1 -1
- package/dist/code-intel/resolver.js +4 -4
- package/dist/code-intel/resolver.js.map +1 -1
- package/dist/code-intel/tsconfig-paths.js +2 -2
- package/dist/code-intel/tsconfig-paths.js.map +1 -1
- package/dist/code-intel/watcher.js +4 -4
- package/dist/code-intel/watcher.js.map +1 -1
- package/dist/core/board/board-column.value-object.js +1 -1
- package/dist/core/board/board-column.value-object.js.map +1 -1
- package/dist/core/board/pipeline.value-object.js +1 -1
- package/dist/core/board/pipeline.value-object.js.map +1 -1
- package/dist/core/board/skill-execution.entity.js +1 -1
- package/dist/core/board/skill-execution.entity.js.map +1 -1
- package/dist/core/board/task-title.value-object.js +1 -1
- package/dist/core/board/task-title.value-object.js.map +1 -1
- package/dist/core/ports/chat-llm.d.ts +36 -0
- package/dist/core/ports/chat-llm.d.ts.map +1 -0
- package/dist/core/ports/chat-llm.js +2 -0
- package/dist/core/ports/chat-llm.js.map +1 -0
- package/dist/core/ports/code-meta.d.ts +4 -0
- package/dist/core/ports/code-meta.d.ts.map +1 -1
- package/dist/core/ports/code-vector-store.d.ts +5 -0
- package/dist/core/ports/code-vector-store.d.ts.map +1 -1
- package/dist/core/ports/docker-control.d.ts +44 -0
- package/dist/core/ports/docker-control.d.ts.map +1 -0
- package/dist/core/ports/docker-control.js +8 -0
- package/dist/core/ports/docker-control.js.map +1 -0
- package/dist/core/ports/hub-readiness-probe.d.ts +22 -0
- package/dist/core/ports/hub-readiness-probe.d.ts.map +1 -0
- package/dist/core/ports/hub-readiness-probe.js +2 -0
- package/dist/core/ports/hub-readiness-probe.js.map +1 -0
- package/dist/core/ports/index.d.ts +4 -0
- package/dist/core/ports/index.d.ts.map +1 -1
- package/dist/core/ports/ollama-control.d.ts +61 -0
- package/dist/core/ports/ollama-control.d.ts.map +1 -0
- package/dist/core/ports/ollama-control.js +7 -0
- package/dist/core/ports/ollama-control.js.map +1 -0
- package/dist/core/ports/platform-probe.d.ts +47 -0
- package/dist/core/ports/platform-probe.d.ts.map +1 -0
- package/dist/core/ports/platform-probe.js +8 -0
- package/dist/core/ports/platform-probe.js.map +1 -0
- package/dist/core/ports/storage.d.ts +62 -29
- package/dist/core/ports/storage.d.ts.map +1 -1
- package/dist/core/ports/workspace-store.d.ts +52 -0
- package/dist/core/ports/workspace-store.d.ts.map +1 -0
- package/dist/core/ports/workspace-store.js +2 -0
- package/dist/core/ports/workspace-store.js.map +1 -0
- package/dist/core/types/index.d.ts +2 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/init.d.ts +29 -0
- package/dist/core/types/init.d.ts.map +1 -0
- package/dist/core/types/init.js +2 -0
- package/dist/core/types/init.js.map +1 -0
- package/dist/core/types/workspace.d.ts +78 -0
- package/dist/core/types/workspace.d.ts.map +1 -0
- package/dist/core/types/workspace.js +2 -0
- package/dist/core/types/workspace.js.map +1 -0
- package/dist/mcp/helpers.d.ts +121 -30
- package/dist/mcp/helpers.d.ts.map +1 -1
- package/dist/mcp/helpers.js +240 -264
- package/dist/mcp/helpers.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +43 -5
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/code-graph.d.ts.map +1 -1
- package/dist/mcp/tools/code-graph.js +109 -74
- package/dist/mcp/tools/code-graph.js.map +1 -1
- package/dist/mcp/tools/code-hybrid.d.ts.map +1 -1
- package/dist/mcp/tools/code-hybrid.js +75 -51
- package/dist/mcp/tools/code-hybrid.js.map +1 -1
- package/dist/mcp/tools/code-search.d.ts.map +1 -1
- package/dist/mcp/tools/code-search.js +32 -32
- package/dist/mcp/tools/code-search.js.map +1 -1
- package/dist/mcp/tools/database.d.ts.map +1 -1
- package/dist/mcp/tools/database.js +86 -97
- package/dist/mcp/tools/database.js.map +1 -1
- package/dist/mcp/tools/estimate.d.ts.map +1 -1
- package/dist/mcp/tools/estimate.js +106 -82
- package/dist/mcp/tools/estimate.js.map +1 -1
- package/dist/mcp/tools/graph.d.ts.map +1 -1
- package/dist/mcp/tools/graph.js +142 -157
- package/dist/mcp/tools/graph.js.map +1 -1
- package/dist/mcp/tools/issue.d.ts.map +1 -1
- package/dist/mcp/tools/issue.js +172 -172
- package/dist/mcp/tools/issue.js.map +1 -1
- package/dist/mcp/tools/push.d.ts.map +1 -1
- package/dist/mcp/tools/push.js +70 -100
- package/dist/mcp/tools/push.js.map +1 -1
- package/dist/mcp/tools/query.d.ts.map +1 -1
- package/dist/mcp/tools/query.js +187 -246
- package/dist/mcp/tools/query.js.map +1 -1
- package/dist/mcp/tools/search.d.ts.map +1 -1
- package/dist/mcp/tools/search.js +25 -22
- package/dist/mcp/tools/search.js.map +1 -1
- package/dist/mcp/tools/workspace.d.ts.map +1 -1
- package/dist/mcp/tools/workspace.js +120 -73
- package/dist/mcp/tools/workspace.js.map +1 -1
- package/dist/use-cases/build-graph.d.ts +1 -1
- package/dist/use-cases/build-graph.d.ts.map +1 -1
- package/dist/use-cases/build-graph.js +63 -50
- package/dist/use-cases/build-graph.js.map +1 -1
- package/dist/use-cases/code-search.d.ts +29 -5
- package/dist/use-cases/code-search.d.ts.map +1 -1
- package/dist/use-cases/code-search.js +98 -9
- package/dist/use-cases/code-search.js.map +1 -1
- package/dist/use-cases/embed.d.ts +1 -1
- package/dist/use-cases/embed.d.ts.map +1 -1
- package/dist/use-cases/embed.js +5 -5
- package/dist/use-cases/embed.js.map +1 -1
- package/dist/use-cases/index-code.js +2 -2
- package/dist/use-cases/index-code.js.map +1 -1
- package/dist/use-cases/init/bootstrap-hub.d.ts +55 -0
- package/dist/use-cases/init/bootstrap-hub.d.ts.map +1 -0
- package/dist/use-cases/init/bootstrap-hub.js +116 -0
- package/dist/use-cases/init/bootstrap-hub.js.map +1 -0
- package/dist/use-cases/init/check-dims-conflict.d.ts +33 -0
- package/dist/use-cases/init/check-dims-conflict.d.ts.map +1 -0
- package/dist/use-cases/init/check-dims-conflict.js +39 -0
- package/dist/use-cases/init/check-dims-conflict.js.map +1 -0
- package/dist/use-cases/init/check-hub-exists.d.ts +23 -0
- package/dist/use-cases/init/check-hub-exists.d.ts.map +1 -0
- package/dist/use-cases/init/check-hub-exists.js +39 -0
- package/dist/use-cases/init/check-hub-exists.js.map +1 -0
- package/dist/use-cases/init/check-ports.d.ts +18 -0
- package/dist/use-cases/init/check-ports.d.ts.map +1 -0
- package/dist/use-cases/init/check-ports.js +25 -0
- package/dist/use-cases/init/check-ports.js.map +1 -0
- package/dist/use-cases/init/check-versions.d.ts +37 -0
- package/dist/use-cases/init/check-versions.d.ts.map +1 -0
- package/dist/use-cases/init/check-versions.js +50 -0
- package/dist/use-cases/init/check-versions.js.map +1 -0
- package/dist/use-cases/init/clear-stale-active.d.ts +20 -0
- package/dist/use-cases/init/clear-stale-active.d.ts.map +1 -0
- package/dist/use-cases/init/clear-stale-active.js +26 -0
- package/dist/use-cases/init/clear-stale-active.js.map +1 -0
- package/dist/use-cases/init/ensure-embedding-model.d.ts +20 -0
- package/dist/use-cases/init/ensure-embedding-model.d.ts.map +1 -0
- package/dist/use-cases/init/ensure-embedding-model.js +24 -0
- package/dist/use-cases/init/ensure-embedding-model.js.map +1 -0
- package/dist/use-cases/init/ensure-ollama-running.d.ts +19 -0
- package/dist/use-cases/init/ensure-ollama-running.d.ts.map +1 -0
- package/dist/use-cases/init/ensure-ollama-running.js +24 -0
- package/dist/use-cases/init/ensure-ollama-running.js.map +1 -0
- package/dist/use-cases/init/health-check-existing-llm.d.ts +25 -0
- package/dist/use-cases/init/health-check-existing-llm.d.ts.map +1 -0
- package/dist/use-cases/init/health-check-existing-llm.js +42 -0
- package/dist/use-cases/init/health-check-existing-llm.js.map +1 -0
- package/dist/use-cases/init/install-ollama.d.ts +27 -0
- package/dist/use-cases/init/install-ollama.d.ts.map +1 -0
- package/dist/use-cases/init/install-ollama.js +51 -0
- package/dist/use-cases/init/install-ollama.js.map +1 -0
- package/dist/use-cases/init/probe-llm.d.ts +32 -0
- package/dist/use-cases/init/probe-llm.d.ts.map +1 -0
- package/dist/use-cases/init/probe-llm.js +42 -0
- package/dist/use-cases/init/probe-llm.js.map +1 -0
- package/dist/use-cases/init/resolve-hub-ports.d.ts +46 -0
- package/dist/use-cases/init/resolve-hub-ports.d.ts.map +1 -0
- package/dist/use-cases/init/resolve-hub-ports.js +77 -0
- package/dist/use-cases/init/resolve-hub-ports.js.map +1 -0
- package/dist/use-cases/init/validate-workspace-name.d.ts +26 -0
- package/dist/use-cases/init/validate-workspace-name.d.ts.map +1 -0
- package/dist/use-cases/init/validate-workspace-name.js +39 -0
- package/dist/use-cases/init/validate-workspace-name.js.map +1 -0
- package/dist/use-cases/init/wait-for-docker.d.ts +16 -0
- package/dist/use-cases/init/wait-for-docker.d.ts.map +1 -0
- package/dist/use-cases/init/wait-for-docker.js +16 -0
- package/dist/use-cases/init/wait-for-docker.js.map +1 -0
- package/dist/use-cases/init/write-config-env.d.ts +32 -0
- package/dist/use-cases/init/write-config-env.d.ts.map +1 -0
- package/dist/use-cases/init/write-config-env.js +118 -0
- package/dist/use-cases/init/write-config-env.js.map +1 -0
- package/dist/use-cases/move-task.js +2 -2
- package/dist/use-cases/move-task.js.map +1 -1
- package/dist/use-cases/pull-db.d.ts +1 -1
- package/dist/use-cases/pull-db.d.ts.map +1 -1
- package/dist/use-cases/pull-db.js +3 -3
- package/dist/use-cases/pull-db.js.map +1 -1
- package/dist/use-cases/pull-git.d.ts +1 -1
- package/dist/use-cases/pull-git.d.ts.map +1 -1
- package/dist/use-cases/pull-git.js +5 -5
- package/dist/use-cases/pull-git.js.map +1 -1
- package/dist/use-cases/pull-github.d.ts +1 -1
- package/dist/use-cases/pull-github.d.ts.map +1 -1
- package/dist/use-cases/pull-github.js +6 -6
- package/dist/use-cases/pull-github.js.map +1 -1
- package/dist/use-cases/pull.d.ts +1 -1
- package/dist/use-cases/pull.d.ts.map +1 -1
- package/dist/use-cases/pull.js +6 -6
- package/dist/use-cases/pull.js.map +1 -1
- package/dist/use-cases/push.d.ts +2 -2
- package/dist/use-cases/push.d.ts.map +1 -1
- package/dist/use-cases/push.js +8 -8
- package/dist/use-cases/push.js.map +1 -1
- package/dist/use-cases/register-code-project.d.ts +8 -0
- package/dist/use-cases/register-code-project.d.ts.map +1 -1
- package/dist/use-cases/register-code-project.js +8 -0
- package/dist/use-cases/register-code-project.js.map +1 -1
- package/dist/use-cases/watch-code.js +1 -1
- package/dist/use-cases/watch-code.js.map +1 -1
- package/dist/workspace/active-workspace.d.ts +26 -0
- package/dist/workspace/active-workspace.d.ts.map +1 -0
- package/dist/workspace/active-workspace.js +69 -0
- package/dist/workspace/active-workspace.js.map +1 -0
- package/dist/workspace/adf.d.ts.map +1 -1
- package/dist/workspace/adf.js +20 -19
- package/dist/workspace/adf.js.map +1 -1
- package/dist/workspace/config.d.ts +11 -0
- package/dist/workspace/config.d.ts.map +1 -1
- package/dist/workspace/config.js +76 -22
- package/dist/workspace/config.js.map +1 -1
- package/dist/workspace/hub-config.d.ts +74 -0
- package/dist/workspace/hub-config.d.ts.map +1 -0
- package/dist/workspace/hub-config.js +164 -0
- package/dist/workspace/hub-config.js.map +1 -0
- package/dist/workspace/registry.d.ts +23 -3
- package/dist/workspace/registry.d.ts.map +1 -1
- package/dist/workspace/registry.js +32 -14
- package/dist/workspace/registry.js.map +1 -1
- package/dist/workspace/resolver.d.ts +20 -18
- package/dist/workspace/resolver.d.ts.map +1 -1
- package/dist/workspace/resolver.js +100 -59
- package/dist/workspace/resolver.js.map +1 -1
- package/package.json +4 -2
- package/templates/hub-config.env +65 -0
- package/templates/hub-docker-compose.yml +88 -0
- package/templates/migrate-to-hub.sql +90 -0
- package/dist/cli/workspaces.d.ts +0 -3
- package/dist/cli/workspaces.d.ts.map +0 -1
- package/dist/cli/workspaces.js +0 -34
- package/dist/cli/workspaces.js.map +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IOllamaControl, PullError } from '../../core/ports/ollama-control.js';
|
|
2
|
+
export type EnsureEmbeddingModelResult = {
|
|
3
|
+
ok: true;
|
|
4
|
+
alreadyPresent: boolean;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
kind: PullError;
|
|
8
|
+
details: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Make sure the requested embedding model is available in Ollama.
|
|
12
|
+
* If it's already in `ollama list` — return immediately. Otherwise
|
|
13
|
+
* trigger `ollama pull` and stream progress through `onProgress`.
|
|
14
|
+
*/
|
|
15
|
+
export declare class EnsureEmbeddingModelUseCase {
|
|
16
|
+
private readonly ollama;
|
|
17
|
+
constructor(ollama: IOllamaControl);
|
|
18
|
+
execute(modelName: string, onProgress?: (pct: number, status: string) => void): Promise<EnsureEmbeddingModelResult>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=ensure-embedding-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-embedding-model.d.ts","sourceRoot":"","sources":["../../../src/use-cases/init/ensure-embedding-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAEpF,MAAM,MAAM,0BAA0B,GAClC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD;;;;GAIG;AACH,qBAAa,2BAA2B;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAE7C,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GACjD,OAAO,CAAC,0BAA0B,CAAC;CAYvC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make sure the requested embedding model is available in Ollama.
|
|
3
|
+
* If it's already in `ollama list` — return immediately. Otherwise
|
|
4
|
+
* trigger `ollama pull` and stream progress through `onProgress`.
|
|
5
|
+
*/
|
|
6
|
+
export class EnsureEmbeddingModelUseCase {
|
|
7
|
+
ollama;
|
|
8
|
+
constructor(ollama) {
|
|
9
|
+
this.ollama = ollama;
|
|
10
|
+
}
|
|
11
|
+
async execute(modelName, onProgress) {
|
|
12
|
+
const models = await this.ollama.listModels();
|
|
13
|
+
const present = models.some((m) => m.name === modelName || m.name.startsWith(`${modelName}:`));
|
|
14
|
+
if (present) {
|
|
15
|
+
return { ok: true, alreadyPresent: true };
|
|
16
|
+
}
|
|
17
|
+
const result = await this.ollama.pullModel(modelName, onProgress);
|
|
18
|
+
if (result.ok) {
|
|
19
|
+
return { ok: true, alreadyPresent: false };
|
|
20
|
+
}
|
|
21
|
+
return { ok: false, kind: result.kind, details: result.details };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=ensure-embedding-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-embedding-model.js","sourceRoot":"","sources":["../../../src/use-cases/init/ensure-embedding-model.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,MAAM,OAAO,2BAA2B;IACT;IAA7B,YAA6B,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;IAEvD,KAAK,CAAC,OAAO,CACX,SAAiB,EACjB,UAAkD;QAElD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC;QAC/F,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;QAC5C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAClE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;QAC7C,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACnE,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IOllamaControl } from '../../core/ports/ollama-control.js';
|
|
2
|
+
export type EnsureOllamaRunningResult = {
|
|
3
|
+
ok: true;
|
|
4
|
+
alreadyRunning: boolean;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
reason: 'timeout';
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Make sure `ollama serve` is reachable on http://localhost:11434.
|
|
11
|
+
* Starts the daemon in the background if it's not running, then
|
|
12
|
+
* waits up to `timeoutMs` for the HTTP API to answer.
|
|
13
|
+
*/
|
|
14
|
+
export declare class EnsureOllamaRunningUseCase {
|
|
15
|
+
private readonly ollama;
|
|
16
|
+
constructor(ollama: IOllamaControl);
|
|
17
|
+
execute(timeoutMs?: number): Promise<EnsureOllamaRunningResult>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=ensure-ollama-running.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-ollama-running.d.ts","sourceRoot":"","sources":["../../../src/use-cases/init/ensure-ollama-running.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,MAAM,yBAAyB,GACjC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAIrC;;;;GAIG;AACH,qBAAa,0BAA0B;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAE7C,OAAO,CAAC,SAAS,GAAE,MAA2B,GAAG,OAAO,CAAC,yBAAyB,CAAC;CAW1F"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
2
|
+
/**
|
|
3
|
+
* Make sure `ollama serve` is reachable on http://localhost:11434.
|
|
4
|
+
* Starts the daemon in the background if it's not running, then
|
|
5
|
+
* waits up to `timeoutMs` for the HTTP API to answer.
|
|
6
|
+
*/
|
|
7
|
+
export class EnsureOllamaRunningUseCase {
|
|
8
|
+
ollama;
|
|
9
|
+
constructor(ollama) {
|
|
10
|
+
this.ollama = ollama;
|
|
11
|
+
}
|
|
12
|
+
async execute(timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
13
|
+
if (await this.ollama.isRunning()) {
|
|
14
|
+
return { ok: true, alreadyRunning: true };
|
|
15
|
+
}
|
|
16
|
+
await this.ollama.startInBackground();
|
|
17
|
+
const healthy = await this.ollama.waitHealthy(timeoutMs);
|
|
18
|
+
if (!healthy) {
|
|
19
|
+
return { ok: false, reason: 'timeout' };
|
|
20
|
+
}
|
|
21
|
+
return { ok: true, alreadyRunning: false };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=ensure-ollama-running.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-ollama-running.js","sourceRoot":"","sources":["../../../src/use-cases/init/ensure-ollama-running.ts"],"names":[],"mappings":"AAMA,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC;;;;GAIG;AACH,MAAM,OAAO,0BAA0B;IACR;IAA7B,YAA6B,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;IAEvD,KAAK,CAAC,OAAO,CAAC,YAAoB,kBAAkB;QAClD,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;YAClC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;QAC5C,CAAC;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC1C,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;IAC7C,CAAC;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HubConfig } from '../../workspace/hub-config.js';
|
|
2
|
+
import type { ProbeLlmUseCase } from './probe-llm.js';
|
|
3
|
+
export type HealthCheckExistingLlmResult = {
|
|
4
|
+
configured: false;
|
|
5
|
+
} | {
|
|
6
|
+
configured: true;
|
|
7
|
+
healthy: true;
|
|
8
|
+
dims: number;
|
|
9
|
+
} | {
|
|
10
|
+
configured: true;
|
|
11
|
+
healthy: false;
|
|
12
|
+
details: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Re-init flow: if the hub already has an LLM provider configured,
|
|
16
|
+
* do a single quick probe to make sure it still works. Used to warn
|
|
17
|
+
* the user that their LM Studio is down / model was deleted, with
|
|
18
|
+
* an offer to reconfigure.
|
|
19
|
+
*/
|
|
20
|
+
export declare class HealthCheckExistingLlmUseCase {
|
|
21
|
+
private readonly probe;
|
|
22
|
+
constructor(probe: ProbeLlmUseCase);
|
|
23
|
+
execute(config: HubConfig): Promise<HealthCheckExistingLlmResult>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=health-check-existing-llm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-check-existing-llm.d.ts","sourceRoot":"","sources":["../../../src/use-cases/init/health-check-existing-llm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,MAAM,4BAA4B,GACpC;IAAE,UAAU,EAAE,KAAK,CAAA;CAAE,GACrB;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D;;;;;GAKG;AACH,qBAAa,6BAA6B;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,eAAe;IAE7C,OAAO,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,4BAA4B,CAAC;CAexE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-init flow: if the hub already has an LLM provider configured,
|
|
3
|
+
* do a single quick probe to make sure it still works. Used to warn
|
|
4
|
+
* the user that their LM Studio is down / model was deleted, with
|
|
5
|
+
* an offer to reconfigure.
|
|
6
|
+
*/
|
|
7
|
+
export class HealthCheckExistingLlmUseCase {
|
|
8
|
+
probe;
|
|
9
|
+
constructor(probe) {
|
|
10
|
+
this.probe = probe;
|
|
11
|
+
}
|
|
12
|
+
async execute(config) {
|
|
13
|
+
if (!config.embedding.userConfigured) {
|
|
14
|
+
return { configured: false };
|
|
15
|
+
}
|
|
16
|
+
const url = resolveUrl(config);
|
|
17
|
+
const model = config.embedding.model;
|
|
18
|
+
if (url === null || url === '' || model === '') {
|
|
19
|
+
return { configured: false };
|
|
20
|
+
}
|
|
21
|
+
const result = await this.probe.execute({ url, model, retries: 1 });
|
|
22
|
+
if (result.ok) {
|
|
23
|
+
return { configured: true, healthy: true, dims: result.dims };
|
|
24
|
+
}
|
|
25
|
+
return { configured: true, healthy: false, details: `${result.kind}: ${result.details}` };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function resolveUrl(config) {
|
|
29
|
+
switch (config.embedding.provider) {
|
|
30
|
+
case 'ollama':
|
|
31
|
+
return config.embedding.ollamaUrl ?? 'http://localhost:11434';
|
|
32
|
+
case 'lmstudio':
|
|
33
|
+
return config.embedding.lmstudioUrl ?? 'http://localhost:1234';
|
|
34
|
+
case 'custom':
|
|
35
|
+
return config.embedding.customUrl ?? null;
|
|
36
|
+
case 'voyage':
|
|
37
|
+
return null;
|
|
38
|
+
default:
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=health-check-existing-llm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-check-existing-llm.js","sourceRoot":"","sources":["../../../src/use-cases/init/health-check-existing-llm.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,OAAO,6BAA6B;IACX;IAA7B,YAA6B,KAAsB;QAAtB,UAAK,GAAL,KAAK,CAAiB;IAAG,CAAC;IAEvD,KAAK,CAAC,OAAO,CAAC,MAAiB;QAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;YACrC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QAC/B,CAAC;QACD,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;QACrC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YAC/C,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QAC/B,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QACpE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAChE,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;IAC5F,CAAC;CACF;AAED,SAAS,UAAU,CAAC,MAAiB;IACnC,QAAQ,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAClC,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC,SAAS,CAAC,SAAS,IAAI,wBAAwB,CAAC;QAChE,KAAK,UAAU;YACb,OAAO,MAAM,CAAC,SAAS,CAAC,WAAW,IAAI,uBAAuB,CAAC;QACjE,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC,SAAS,CAAC,SAAS,IAAI,IAAI,CAAC;QAC5C,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC;QACd;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IOllamaControl } from '../../core/ports/ollama-control.js';
|
|
2
|
+
import type { IPlatformProbe } from '../../core/ports/platform-probe.js';
|
|
3
|
+
export type InstallOllamaFailureKind = 'unsupported-os' | 'no-brew-no-curl' | 'brew-failed' | 'curl-failed';
|
|
4
|
+
export type InstallOllamaResult = {
|
|
5
|
+
ok: true;
|
|
6
|
+
via: 'brew' | 'curl';
|
|
7
|
+
} | {
|
|
8
|
+
ok: false;
|
|
9
|
+
kind: InstallOllamaFailureKind;
|
|
10
|
+
details: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Install Ollama using whatever package manager is appropriate for
|
|
14
|
+
* the current OS. macOS tries `brew install ollama` first, falls back
|
|
15
|
+
* to `curl install.sh` if brew is missing or fails. Linux uses
|
|
16
|
+
* `curl install.sh` directly. Windows is rejected (caller should show
|
|
17
|
+
* the manual link).
|
|
18
|
+
*/
|
|
19
|
+
export declare class InstallOllamaUseCase {
|
|
20
|
+
private readonly ollama;
|
|
21
|
+
private readonly platform;
|
|
22
|
+
constructor(ollama: IOllamaControl, platform: IPlatformProbe);
|
|
23
|
+
execute(): Promise<InstallOllamaResult>;
|
|
24
|
+
private tryBrew;
|
|
25
|
+
private tryCurl;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=install-ollama.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-ollama.d.ts","sourceRoot":"","sources":["../../../src/use-cases/init/install-ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,oCAAoC,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,MAAM,wBAAwB,GAChC,gBAAgB,GAChB,iBAAiB,GACjB,aAAa,GACb,aAAa,CAAC;AAElB,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAClC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,wBAAwB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAE7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,cAAc;IAGrC,OAAO,IAAI,OAAO,CAAC,mBAAmB,CAAC;YAe/B,OAAO;YAYP,OAAO;CAWtB"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install Ollama using whatever package manager is appropriate for
|
|
3
|
+
* the current OS. macOS tries `brew install ollama` first, falls back
|
|
4
|
+
* to `curl install.sh` if brew is missing or fails. Linux uses
|
|
5
|
+
* `curl install.sh` directly. Windows is rejected (caller should show
|
|
6
|
+
* the manual link).
|
|
7
|
+
*/
|
|
8
|
+
export class InstallOllamaUseCase {
|
|
9
|
+
ollama;
|
|
10
|
+
platform;
|
|
11
|
+
constructor(ollama, platform) {
|
|
12
|
+
this.ollama = ollama;
|
|
13
|
+
this.platform = platform;
|
|
14
|
+
}
|
|
15
|
+
async execute() {
|
|
16
|
+
const os = this.platform.detectOS();
|
|
17
|
+
if (os === 'windows' || os === 'unknown') {
|
|
18
|
+
return { ok: false, kind: 'unsupported-os', details: `OS=${os}` };
|
|
19
|
+
}
|
|
20
|
+
if (os === 'macos') {
|
|
21
|
+
const brewResult = await this.tryBrew();
|
|
22
|
+
if (brewResult !== null) {
|
|
23
|
+
return brewResult;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return this.tryCurl();
|
|
27
|
+
}
|
|
28
|
+
async tryBrew() {
|
|
29
|
+
const has = await this.platform.hasCommand('brew');
|
|
30
|
+
if (!has) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const result = await this.ollama.installViaBrew();
|
|
34
|
+
if (result.ok) {
|
|
35
|
+
return { ok: true, via: 'brew' };
|
|
36
|
+
}
|
|
37
|
+
return { ok: false, kind: 'brew-failed', details: result.details };
|
|
38
|
+
}
|
|
39
|
+
async tryCurl() {
|
|
40
|
+
const has = await this.platform.hasCommand('curl');
|
|
41
|
+
if (!has) {
|
|
42
|
+
return { ok: false, kind: 'no-brew-no-curl', details: 'curl not installed' };
|
|
43
|
+
}
|
|
44
|
+
const result = await this.ollama.installViaCurl();
|
|
45
|
+
if (result.ok) {
|
|
46
|
+
return { ok: true, via: 'curl' };
|
|
47
|
+
}
|
|
48
|
+
return { ok: false, kind: 'curl-failed', details: result.details };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=install-ollama.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-ollama.js","sourceRoot":"","sources":["../../../src/use-cases/init/install-ollama.ts"],"names":[],"mappings":"AAaA;;;;;;GAMG;AACH,MAAM,OAAO,oBAAoB;IAEZ;IACA;IAFnB,YACmB,MAAsB,EACtB,QAAwB;QADxB,WAAM,GAAN,MAAM,CAAgB;QACtB,aAAQ,GAAR,QAAQ,CAAgB;IACxC,CAAC;IAEJ,KAAK,CAAC,OAAO;QACX,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACpC,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACzC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACpE,CAAC;QAED,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YACnB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACxC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;gBACxB,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAkB,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QACjE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACrE,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;QAC/E,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAClD,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACrE,CAAC;CACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { IOllamaControl, ProbeError } from '../../core/ports/ollama-control.js';
|
|
2
|
+
export interface ProbeLlmInput {
|
|
3
|
+
readonly url: string;
|
|
4
|
+
readonly model: string;
|
|
5
|
+
readonly retries?: number;
|
|
6
|
+
readonly delayMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export type ProbeLlmResult = {
|
|
9
|
+
ok: true;
|
|
10
|
+
dims: number;
|
|
11
|
+
attempts: number;
|
|
12
|
+
} | {
|
|
13
|
+
ok: false;
|
|
14
|
+
kind: ProbeError;
|
|
15
|
+
details: string;
|
|
16
|
+
attempts: number;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Try to fetch an embedding from the given URL+model. Retries up to
|
|
20
|
+
* `retries` times with a fixed delay so transient timeouts don't fail
|
|
21
|
+
* the whole init.
|
|
22
|
+
*
|
|
23
|
+
* Works for any OpenAI-compatible /api/embeddings endpoint (Ollama,
|
|
24
|
+
* LM Studio, llama-server). Internally calls `IOllamaControl.probeEmbedding`
|
|
25
|
+
* which sends a POST to `${url}/api/embeddings`.
|
|
26
|
+
*/
|
|
27
|
+
export declare class ProbeLlmUseCase {
|
|
28
|
+
private readonly ollama;
|
|
29
|
+
constructor(ollama: IOllamaControl);
|
|
30
|
+
execute(input: ProbeLlmInput): Promise<ProbeLlmResult>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=probe-llm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-llm.d.ts","sourceRoot":"","sources":["../../../src/use-cases/init/probe-llm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAErF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAMvE;;;;;;;;GAQG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAE7C,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;CAwB7D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const DEFAULT_RETRIES = 3;
|
|
2
|
+
const DEFAULT_DELAY_MS = 5000;
|
|
3
|
+
const PROBE_TEXT = 'argustack-init-probe';
|
|
4
|
+
/**
|
|
5
|
+
* Try to fetch an embedding from the given URL+model. Retries up to
|
|
6
|
+
* `retries` times with a fixed delay so transient timeouts don't fail
|
|
7
|
+
* the whole init.
|
|
8
|
+
*
|
|
9
|
+
* Works for any OpenAI-compatible /api/embeddings endpoint (Ollama,
|
|
10
|
+
* LM Studio, llama-server). Internally calls `IOllamaControl.probeEmbedding`
|
|
11
|
+
* which sends a POST to `${url}/api/embeddings`.
|
|
12
|
+
*/
|
|
13
|
+
export class ProbeLlmUseCase {
|
|
14
|
+
ollama;
|
|
15
|
+
constructor(ollama) {
|
|
16
|
+
this.ollama = ollama;
|
|
17
|
+
}
|
|
18
|
+
async execute(input) {
|
|
19
|
+
const retries = input.retries ?? DEFAULT_RETRIES;
|
|
20
|
+
const delay = input.delayMs ?? DEFAULT_DELAY_MS;
|
|
21
|
+
let attempts = 0;
|
|
22
|
+
let lastKind = 'no-response';
|
|
23
|
+
let lastDetails = '';
|
|
24
|
+
while (attempts < retries) {
|
|
25
|
+
attempts += 1;
|
|
26
|
+
const result = await this.ollama.probeEmbedding(input.model, PROBE_TEXT, input.url);
|
|
27
|
+
if (result.ok) {
|
|
28
|
+
return { ok: true, dims: result.dims, attempts };
|
|
29
|
+
}
|
|
30
|
+
lastKind = result.kind;
|
|
31
|
+
lastDetails = result.details;
|
|
32
|
+
if (result.kind === 'model-not-found' || result.kind === 'wrong-format') {
|
|
33
|
+
return { ok: false, kind: result.kind, details: result.details, attempts };
|
|
34
|
+
}
|
|
35
|
+
if (attempts < retries) {
|
|
36
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { ok: false, kind: lastKind, details: lastDetails, attempts };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=probe-llm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-llm.js","sourceRoot":"","sources":["../../../src/use-cases/init/probe-llm.ts"],"names":[],"mappings":"AAaA,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAE1C;;;;;;;;GAQG;AACH,MAAM,OAAO,eAAe;IACG;IAA7B,YAA6B,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;IAEvD,KAAK,CAAC,OAAO,CAAC,KAAoB;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,eAAe,CAAC;QACjD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,IAAI,gBAAgB,CAAC;QAChD,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,QAAQ,GAAe,aAAa,CAAC;QACzC,IAAI,WAAW,GAAG,EAAE,CAAC;QAErB,OAAO,QAAQ,GAAG,OAAO,EAAE,CAAC;YAC1B,QAAQ,IAAI,CAAC,CAAC;YACd,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACpF,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;gBACd,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;YACnD,CAAC;YACD,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;YACvB,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC;YAC7B,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBACxE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;YAC7E,CAAC;YACD,IAAI,QAAQ,GAAG,OAAO,EAAE,CAAC;gBACvB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IACvE,CAAC;CACF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { IPlatformProbe, PortInUse } from '../../core/ports/platform-probe.js';
|
|
2
|
+
export interface HubPorts {
|
|
3
|
+
pg: number;
|
|
4
|
+
pgweb: number;
|
|
5
|
+
neo4jHttp: number;
|
|
6
|
+
neo4jBolt: number;
|
|
7
|
+
qdrantRest: number;
|
|
8
|
+
qdrantGrpc: number;
|
|
9
|
+
}
|
|
10
|
+
export type HubPortKey = keyof HubPorts;
|
|
11
|
+
export interface PortPlanEntry {
|
|
12
|
+
readonly key: HubPortKey;
|
|
13
|
+
readonly default: number;
|
|
14
|
+
readonly current: number;
|
|
15
|
+
readonly conflict: PortInUse | null;
|
|
16
|
+
readonly suggested: number | null;
|
|
17
|
+
}
|
|
18
|
+
export interface ResolveHubPortsResult {
|
|
19
|
+
readonly plan: readonly PortPlanEntry[];
|
|
20
|
+
/**
|
|
21
|
+
* `true` when at least one port differs from its default — caller
|
|
22
|
+
* should ask the user to confirm / customize. `false` means the
|
|
23
|
+
* default set is fully usable and init can continue silently.
|
|
24
|
+
*/
|
|
25
|
+
readonly needsConfirmation: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Pre-bootstrap port planner. For each hub service:
|
|
29
|
+
* 1. Try its default port.
|
|
30
|
+
* 2. If occupied — record the conflict and scan forward up to
|
|
31
|
+
* `MAX_FALLBACK_SCAN` ports for a free one. The suggested
|
|
32
|
+
* number is the first free port found.
|
|
33
|
+
* 3. Skip ports that are already chosen earlier in the plan so two
|
|
34
|
+
* services never collide on the same suggestion.
|
|
35
|
+
*
|
|
36
|
+
* Caller (init flow) then prompts the user per conflict: accept
|
|
37
|
+
* suggestion, enter custom, or abort.
|
|
38
|
+
*/
|
|
39
|
+
export declare class ResolveHubPortsUseCase {
|
|
40
|
+
private readonly platform;
|
|
41
|
+
constructor(platform: IPlatformProbe);
|
|
42
|
+
execute(defaults: HubPorts): Promise<ResolveHubPortsResult>;
|
|
43
|
+
private findFreePort;
|
|
44
|
+
}
|
|
45
|
+
export declare function labelForPortKey(key: HubPortKey): string;
|
|
46
|
+
//# sourceMappingURL=resolve-hub-ports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-hub-ports.d.ts","sourceRoot":"","sources":["../../../src/use-cases/init/resolve-hub-ports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAEpF,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC;AAExC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACrC;AAaD;;;;;;;;;;;GAWG;AACH,qBAAa,sBAAsB;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,cAAc;IAE/C,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,qBAAqB,CAAC;YAkCnD,YAAY;CAY3B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAEvD"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const MAX_FALLBACK_SCAN = 20;
|
|
2
|
+
const SERVICE_LABEL = {
|
|
3
|
+
pg: 'Postgres',
|
|
4
|
+
pgweb: 'pgweb',
|
|
5
|
+
neo4jHttp: 'Neo4j HTTP',
|
|
6
|
+
neo4jBolt: 'Neo4j Bolt',
|
|
7
|
+
qdrantRest: 'Qdrant REST',
|
|
8
|
+
qdrantGrpc: 'Qdrant gRPC',
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Pre-bootstrap port planner. For each hub service:
|
|
12
|
+
* 1. Try its default port.
|
|
13
|
+
* 2. If occupied — record the conflict and scan forward up to
|
|
14
|
+
* `MAX_FALLBACK_SCAN` ports for a free one. The suggested
|
|
15
|
+
* number is the first free port found.
|
|
16
|
+
* 3. Skip ports that are already chosen earlier in the plan so two
|
|
17
|
+
* services never collide on the same suggestion.
|
|
18
|
+
*
|
|
19
|
+
* Caller (init flow) then prompts the user per conflict: accept
|
|
20
|
+
* suggestion, enter custom, or abort.
|
|
21
|
+
*/
|
|
22
|
+
export class ResolveHubPortsUseCase {
|
|
23
|
+
platform;
|
|
24
|
+
constructor(platform) {
|
|
25
|
+
this.platform = platform;
|
|
26
|
+
}
|
|
27
|
+
async execute(defaults) {
|
|
28
|
+
const plan = [];
|
|
29
|
+
const used = new Set();
|
|
30
|
+
let needsConfirmation = false;
|
|
31
|
+
for (const key of Object.keys(defaults)) {
|
|
32
|
+
const defaultPort = defaults[key];
|
|
33
|
+
const status = await this.platform.checkPort(defaultPort);
|
|
34
|
+
if (status.free && !used.has(defaultPort)) {
|
|
35
|
+
plan.push({ key, default: defaultPort, current: defaultPort, conflict: null, suggested: null });
|
|
36
|
+
used.add(defaultPort);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const conflict = status.free
|
|
40
|
+
? null
|
|
41
|
+
: status;
|
|
42
|
+
const suggested = await this.findFreePort(defaultPort + 1, used);
|
|
43
|
+
plan.push({
|
|
44
|
+
key,
|
|
45
|
+
default: defaultPort,
|
|
46
|
+
current: suggested ?? defaultPort,
|
|
47
|
+
conflict,
|
|
48
|
+
suggested,
|
|
49
|
+
});
|
|
50
|
+
if (suggested !== null) {
|
|
51
|
+
used.add(suggested);
|
|
52
|
+
}
|
|
53
|
+
needsConfirmation = true;
|
|
54
|
+
}
|
|
55
|
+
return { plan, needsConfirmation };
|
|
56
|
+
}
|
|
57
|
+
async findFreePort(start, alreadyChosen) {
|
|
58
|
+
for (let i = 0; i < MAX_FALLBACK_SCAN; i++) {
|
|
59
|
+
const candidate = start + i;
|
|
60
|
+
if (candidate > 65535) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
if (alreadyChosen.has(candidate)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const status = await this.platform.checkPort(candidate);
|
|
67
|
+
if (status.free) {
|
|
68
|
+
return candidate;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export function labelForPortKey(key) {
|
|
75
|
+
return SERVICE_LABEL[key];
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=resolve-hub-ports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-hub-ports.js","sourceRoot":"","sources":["../../../src/use-cases/init/resolve-hub-ports.ts"],"names":[],"mappings":"AA+BA,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B,MAAM,aAAa,GAA+B;IAChD,EAAE,EAAE,UAAU;IACd,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,YAAY;IACvB,SAAS,EAAE,YAAY;IACvB,UAAU,EAAE,aAAa;IACzB,UAAU,EAAE,aAAa;CAC1B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,sBAAsB;IACJ;IAA7B,YAA6B,QAAwB;QAAxB,aAAQ,GAAR,QAAQ,CAAgB;IAAG,CAAC;IAEzD,KAAK,CAAC,OAAO,CAAC,QAAkB;QAC9B,MAAM,IAAI,GAAoB,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,IAAI,iBAAiB,GAAG,KAAK,CAAC;QAE9B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAiB,EAAE,CAAC;YACxD,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAC1D,IAAI,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1C,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACtB,SAAS;YACX,CAAC;YAED,MAAM,QAAQ,GAAqB,MAAM,CAAC,IAAI;gBAC5C,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,MAAM,CAAC;YACX,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC;gBACR,GAAG;gBACH,OAAO,EAAE,WAAW;gBACpB,OAAO,EAAE,SAAS,IAAI,WAAW;gBACjC,QAAQ;gBACR,SAAS;aACV,CAAC,CAAC;YACH,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACtB,CAAC;YACD,iBAAiB,GAAG,IAAI,CAAC;QAC3B,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,aAA0B;QAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,iBAAiB,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;YAC5B,IAAI,SAAS,GAAG,KAAK,EAAE,CAAC;gBAAC,OAAO,IAAI,CAAC;YAAC,CAAC;YACvC,IAAI,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACxD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBAChB,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,MAAM,UAAU,eAAe,CAAC,GAAe;IAC7C,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { IWorkspaceStore } from '../../core/ports/workspace-store.js';
|
|
2
|
+
export type WorkspaceNameAction = 'create' | 'switch';
|
|
3
|
+
export type ValidateWorkspaceNameResult = {
|
|
4
|
+
ok: true;
|
|
5
|
+
action: WorkspaceNameAction;
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
reason: 'empty' | 'invalid-slug';
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Validate user-supplied workspace name and decide whether it should be
|
|
14
|
+
* created fresh or used to switch to an existing entry.
|
|
15
|
+
*
|
|
16
|
+
* - Empty / invalid slug → `{ ok: false, reason }` — caller re-prompts.
|
|
17
|
+
* - Valid slug + new → `{ action: 'create' }` — caller calls store.create.
|
|
18
|
+
* - Valid slug + already in DB → `{ action: 'switch' }` — caller just
|
|
19
|
+
* marks it active without writing the row.
|
|
20
|
+
*/
|
|
21
|
+
export declare class ValidateWorkspaceNameUseCase {
|
|
22
|
+
private readonly hubStore;
|
|
23
|
+
constructor(hubStore: IWorkspaceStore);
|
|
24
|
+
execute(rawName: string): Promise<ValidateWorkspaceNameResult>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=validate-workspace-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-workspace-name.d.ts","sourceRoot":"","sources":["../../../src/use-cases/init/validate-workspace-name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAE3E,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEtD,MAAM,MAAM,2BAA2B,GACnC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CAAA;CAAE,CAAC;AAIpD;;;;;;;;GAQG;AACH,qBAAa,4BAA4B;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,eAAe;IAEhD,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,2BAA2B,CAAC;CAerE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const SLUG_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
2
|
+
/**
|
|
3
|
+
* Validate user-supplied workspace name and decide whether it should be
|
|
4
|
+
* created fresh or used to switch to an existing entry.
|
|
5
|
+
*
|
|
6
|
+
* - Empty / invalid slug → `{ ok: false, reason }` — caller re-prompts.
|
|
7
|
+
* - Valid slug + new → `{ action: 'create' }` — caller calls store.create.
|
|
8
|
+
* - Valid slug + already in DB → `{ action: 'switch' }` — caller just
|
|
9
|
+
* marks it active without writing the row.
|
|
10
|
+
*/
|
|
11
|
+
export class ValidateWorkspaceNameUseCase {
|
|
12
|
+
hubStore;
|
|
13
|
+
constructor(hubStore) {
|
|
14
|
+
this.hubStore = hubStore;
|
|
15
|
+
}
|
|
16
|
+
async execute(rawName) {
|
|
17
|
+
const trimmed = rawName.trim();
|
|
18
|
+
if (trimmed.length === 0) {
|
|
19
|
+
return { ok: false, reason: 'empty' };
|
|
20
|
+
}
|
|
21
|
+
const slug = slugify(trimmed);
|
|
22
|
+
if (!SLUG_RE.test(slug)) {
|
|
23
|
+
return { ok: false, reason: 'invalid-slug' };
|
|
24
|
+
}
|
|
25
|
+
const existing = (await this.hubStore.getById(slug)) ?? (await this.hubStore.getByName(slug));
|
|
26
|
+
if (existing !== null) {
|
|
27
|
+
return { ok: true, action: 'switch', id: existing.id, name: existing.name };
|
|
28
|
+
}
|
|
29
|
+
return { ok: true, action: 'create', id: slug, name: slug };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function slugify(raw) {
|
|
33
|
+
return raw
|
|
34
|
+
.toLowerCase()
|
|
35
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
36
|
+
.replace(/-+/g, '-')
|
|
37
|
+
.replace(/^-|-$/g, '');
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=validate-workspace-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-workspace-name.js","sourceRoot":"","sources":["../../../src/use-cases/init/validate-workspace-name.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,GAAG,2BAA2B,CAAC;AAE5C;;;;;;;;GAQG;AACH,MAAM,OAAO,4BAA4B;IACV;IAA7B,YAA6B,QAAyB;QAAzB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAE1D,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACxC,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QAC/C,CAAC;QACD,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9F,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9E,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC9D,CAAC;CACF;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,GAAG;SACP,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IDockerControl } from '../../core/ports/docker-control.js';
|
|
2
|
+
export interface WaitForDockerOptions {
|
|
3
|
+
readonly timeoutMs?: number;
|
|
4
|
+
readonly intervalMs?: number;
|
|
5
|
+
readonly onTick?: (secondsElapsed: number) => void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Block until `docker info` answers, polling every `intervalMs`.
|
|
9
|
+
* Returns true if docker came up before timeout; false on timeout.
|
|
10
|
+
*/
|
|
11
|
+
export declare class WaitForDockerUseCase {
|
|
12
|
+
private readonly docker;
|
|
13
|
+
constructor(docker: IDockerControl);
|
|
14
|
+
execute(options?: WaitForDockerOptions): Promise<boolean>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=wait-for-docker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait-for-docker.d.ts","sourceRoot":"","sources":["../../../src/use-cases/init/wait-for-docker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAKD;;;GAGG;AACH,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAE7C,OAAO,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,OAAO,CAAC;CAOpE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const DEFAULT_TIMEOUT_MS = 600_000;
|
|
2
|
+
const DEFAULT_INTERVAL_MS = 5_000;
|
|
3
|
+
/**
|
|
4
|
+
* Block until `docker info` answers, polling every `intervalMs`.
|
|
5
|
+
* Returns true if docker came up before timeout; false on timeout.
|
|
6
|
+
*/
|
|
7
|
+
export class WaitForDockerUseCase {
|
|
8
|
+
docker;
|
|
9
|
+
constructor(docker) {
|
|
10
|
+
this.docker = docker;
|
|
11
|
+
}
|
|
12
|
+
async execute(options = {}) {
|
|
13
|
+
return this.docker.pollUntilRunning(options.timeoutMs ?? DEFAULT_TIMEOUT_MS, options.intervalMs ?? DEFAULT_INTERVAL_MS, options.onTick);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=wait-for-docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait-for-docker.js","sourceRoot":"","sources":["../../../src/use-cases/init/wait-for-docker.ts"],"names":[],"mappings":"AAQA,MAAM,kBAAkB,GAAG,OAAO,CAAC;AACnC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IACF;IAA7B,YAA6B,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;IAEvD,KAAK,CAAC,OAAO,CAAC,UAAgC,EAAE;QAC9C,OAAO,IAAI,CAAC,MAAM,CAAC,gBAAgB,CACjC,OAAO,CAAC,SAAS,IAAI,kBAAkB,EACvC,OAAO,CAAC,UAAU,IAAI,mBAAmB,EACzC,OAAO,CAAC,MAAM,CACf,CAAC;IACJ,CAAC;CACF"}
|