@ai-setting/roy-agent-core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +99145 -0
- package/package.json +114 -0
- package/src/config/config-component.test.ts +627 -0
- package/src/config/config-component.ts +906 -0
- package/src/config/config-parser.test.ts +319 -0
- package/src/config/config-parser.ts +203 -0
- package/src/config/decentralized-config.test.ts +740 -0
- package/src/config/env-key.ts +210 -0
- package/src/config/env-source.test.ts +252 -0
- package/src/config/env-source.ts +301 -0
- package/src/config/file-source.test.ts +357 -0
- package/src/config/file-source.ts +421 -0
- package/src/config/index.ts +24 -0
- package/src/config/protocol-resolver.test.ts +217 -0
- package/src/config/protocol-resolver.ts +228 -0
- package/src/env/agent/agent-component.abort.test.ts +511 -0
- package/src/env/agent/agent-component.record-session.test.ts +349 -0
- package/src/env/agent/agent-component.test.ts +1389 -0
- package/src/env/agent/agent-component.tool-error.test.ts +327 -0
- package/src/env/agent/agent-component.ts +1711 -0
- package/src/env/agent/agent-config-registration.test.ts +226 -0
- package/src/env/agent/agent-config-registration.ts +46 -0
- package/src/env/agent/agent-reminder-plugin.integration.test.ts +243 -0
- package/src/env/agent/index.ts +10 -0
- package/src/env/agent/summary-agent.parse-hint.test.ts +360 -0
- package/src/env/agent/summary-agent.ts +508 -0
- package/src/env/agent/types.ts +536 -0
- package/src/env/commands/commands-component.test.ts +364 -0
- package/src/env/commands/commands-component.ts +604 -0
- package/src/env/commands/commands-config-registration.test.ts +198 -0
- package/src/env/commands/commands-config-registration.ts +38 -0
- package/src/env/commands/index.ts +21 -0
- package/src/env/commands/parser.test.ts +203 -0
- package/src/env/commands/parser.ts +115 -0
- package/src/env/commands/types.ts +184 -0
- package/src/env/commands-prompt-integration.test.ts +243 -0
- package/src/env/component-env.test.ts +119 -0
- package/src/env/component.ts +335 -0
- package/src/env/constants.test.ts +72 -0
- package/src/env/constants.ts +123 -0
- package/src/env/debug/debug-component.test.ts +114 -0
- package/src/env/debug/debug-component.ts +547 -0
- package/src/env/debug/formatters/index.ts +9 -0
- package/src/env/debug/formatters/repl-formatter.test.ts +139 -0
- package/src/env/debug/formatters/repl-formatter.ts +358 -0
- package/src/env/debug/formatters/trace-formatter.test.ts +119 -0
- package/src/env/debug/formatters/trace-formatter.ts +191 -0
- package/src/env/debug/formatters/tree-formatter.test.ts +107 -0
- package/src/env/debug/formatters/tree-formatter.ts +325 -0
- package/src/env/debug/index.ts +38 -0
- package/src/env/debug/parser/regex-parser.test.ts +201 -0
- package/src/env/debug/parser/regex-parser.ts +196 -0
- package/src/env/debug/parser/span-builder.test.ts +241 -0
- package/src/env/debug/parser/span-builder.ts +386 -0
- package/src/env/debug/reader/log-reader.test.ts +170 -0
- package/src/env/debug/reader/log-reader.ts +186 -0
- package/src/env/debug/reader/span-db-reader.test.ts +118 -0
- package/src/env/debug/reader/span-db-reader.ts +201 -0
- package/src/env/debug/types.test.ts +187 -0
- package/src/env/debug/types.ts +171 -0
- package/src/env/environment-init.test.ts +183 -0
- package/src/env/environment-lifecycle.test.ts +516 -0
- package/src/env/environment-service.test.ts +332 -0
- package/src/env/environment.handle-query.test.ts +96 -0
- package/src/env/environment.test.ts +232 -0
- package/src/env/environment.ts +708 -0
- package/src/env/errors.test.ts +165 -0
- package/src/env/errors.ts +157 -0
- package/src/env/event-source/event-source-agent-handler.test.ts +193 -0
- package/src/env/event-source/event-source-agent-handler.ts +111 -0
- package/src/env/event-source/event-source-component.process-cleanup.test.ts +236 -0
- package/src/env/event-source/event-source-component.stop.test.ts +346 -0
- package/src/env/event-source/event-source-component.test.ts +1207 -0
- package/src/env/event-source/event-source-component.ts +1379 -0
- package/src/env/event-source/event-source-config-registration.test.ts +242 -0
- package/src/env/event-source/event-source-config-registration.ts +37 -0
- package/src/env/event-source/event-source-integration.test.ts +320 -0
- package/src/env/event-source/event-source-platform.test.ts +630 -0
- package/src/env/event-source/types.ts +298 -0
- package/src/env/hook/global-hook-manager.ts +162 -0
- package/src/env/hook/hook-manager.test.ts +374 -0
- package/src/env/hook/hook-manager.ts +309 -0
- package/src/env/hook/index.ts +38 -0
- package/src/env/hook/types.ts +138 -0
- package/src/env/index.ts +144 -0
- package/src/env/interface.ts +203 -0
- package/src/env/llm/hooks.test.ts +293 -0
- package/src/env/llm/hooks.ts +316 -0
- package/src/env/llm/index.ts +61 -0
- package/src/env/llm/invoke-threshold-check.test.ts +88 -0
- package/src/env/llm/invoke-timeout.test.ts +54 -0
- package/src/env/llm/invoke.test.ts +71 -0
- package/src/env/llm/invoke.ts +1039 -0
- package/src/env/llm/llm-config.test.ts +523 -0
- package/src/env/llm/llm.test.ts +233 -0
- package/src/env/llm/llm.ts +568 -0
- package/src/env/llm/provider.test.ts +182 -0
- package/src/env/llm/provider.ts +108 -0
- package/src/env/llm/transform.test.ts +251 -0
- package/src/env/llm/transform.ts +286 -0
- package/src/env/llm/types.test.ts +580 -0
- package/src/env/llm/types.ts +424 -0
- package/src/env/log-trace/decorator-otel.test.ts +182 -0
- package/src/env/log-trace/decorator.ts +230 -0
- package/src/env/log-trace/index.ts +79 -0
- package/src/env/log-trace/log-trace-component.test.ts +242 -0
- package/src/env/log-trace/log-trace-component.ts +497 -0
- package/src/env/log-trace/log-trace-config-registration.test.ts +348 -0
- package/src/env/log-trace/log-trace-config-registration.ts +45 -0
- package/src/env/log-trace/logger.test.ts +149 -0
- package/src/env/log-trace/logger.ts +522 -0
- package/src/env/log-trace/opentelemetry/cli-propagation.test.ts +147 -0
- package/src/env/log-trace/opentelemetry/cli-propagation.ts +194 -0
- package/src/env/log-trace/opentelemetry/integration.test.ts +668 -0
- package/src/env/log-trace/opentelemetry/mod.ts +25 -0
- package/src/env/log-trace/opentelemetry/propagation-env.test.ts +181 -0
- package/src/env/log-trace/opentelemetry/propagation-env.ts +136 -0
- package/src/env/log-trace/opentelemetry/propagation.test.ts +259 -0
- package/src/env/log-trace/opentelemetry/propagation.ts +215 -0
- package/src/env/log-trace/opentelemetry/tracer-provider-context.test.ts +166 -0
- package/src/env/log-trace/opentelemetry/tracer-provider.test.ts +379 -0
- package/src/env/log-trace/opentelemetry/tracer-provider.ts +612 -0
- package/src/env/log-trace/span-storage.test.ts +145 -0
- package/src/env/log-trace/span-storage.ts +230 -0
- package/src/env/log-trace/trace-context.test.ts +187 -0
- package/src/env/log-trace/trace-context.ts +162 -0
- package/src/env/log-trace/types.test.ts +63 -0
- package/src/env/log-trace/types.ts +172 -0
- package/src/env/mcp/README.md +244 -0
- package/src/env/mcp/__integration__/mcp-component.integration.test.ts +373 -0
- package/src/env/mcp/config.test.ts +74 -0
- package/src/env/mcp/config.ts +116 -0
- package/src/env/mcp/index.ts +41 -0
- package/src/env/mcp/loader.test.ts +161 -0
- package/src/env/mcp/loader.ts +209 -0
- package/src/env/mcp/mcp-component.test.ts +111 -0
- package/src/env/mcp/mcp-component.ts +358 -0
- package/src/env/mcp/mcp-config-registration.test.ts +304 -0
- package/src/env/mcp/mcp-config-registration.ts +50 -0
- package/src/env/mcp/scanner.test.ts +170 -0
- package/src/env/mcp/scanner.ts +246 -0
- package/src/env/mcp/tool/adapter.test.ts +520 -0
- package/src/env/mcp/tool/adapter.ts +521 -0
- package/src/env/mcp/tool/index.ts +5 -0
- package/src/env/mcp/types.test.ts +171 -0
- package/src/env/mcp/types.ts +79 -0
- package/src/env/memory/README.md +177 -0
- package/src/env/memory/built-in/index.ts +59 -0
- package/src/env/memory/built-in/recall-memory.ts +103 -0
- package/src/env/memory/built-in/record-memory.ts +148 -0
- package/src/env/memory/index.ts +20 -0
- package/src/env/memory/memory-component.test.ts +239 -0
- package/src/env/memory/memory-component.ts +503 -0
- package/src/env/memory/memory-config-registration.test.ts +67 -0
- package/src/env/memory/memory-config-registration.ts +48 -0
- package/src/env/memory/memory-config.ts +45 -0
- package/src/env/memory/memory-file.test.ts +268 -0
- package/src/env/memory/plugin/index.ts +48 -0
- package/src/env/memory/plugin/memory-agent.test.ts +249 -0
- package/src/env/memory/plugin/memory-agent.ts +365 -0
- package/src/env/memory/plugin/memory-manager.ts +198 -0
- package/src/env/memory/plugin/memory-plugin-agent.test.ts +145 -0
- package/src/env/memory/plugin/memory-plugin.ts +210 -0
- package/src/env/memory/plugin/plugin-simplified.test.ts +51 -0
- package/src/env/memory/plugin/recall-memory.test.ts +106 -0
- package/src/env/memory/plugin/recall-memory.ts +53 -0
- package/src/env/memory/plugin/types.ts +101 -0
- package/src/env/memory/tools/memory-agent-tools.ts +228 -0
- package/src/env/memory/types.ts +85 -0
- package/src/env/paths.ts +118 -0
- package/src/env/prompt/index.ts +18 -0
- package/src/env/prompt/memory-prompts.test.ts +91 -0
- package/src/env/prompt/prompt-component.test.ts +491 -0
- package/src/env/prompt/prompt-component.ts +619 -0
- package/src/env/prompt/prompt-config-registration.test.ts +213 -0
- package/src/env/prompt/prompt-config-registration.ts +39 -0
- package/src/env/prompt/prompts-index.ts +504 -0
- package/src/env/prompt/renderer.ts +67 -0
- package/src/env/prompt/types.ts +136 -0
- package/src/env/session/hooks.ts +18 -0
- package/src/env/session/index.ts +37 -0
- package/src/env/session/search-query-parser.test.ts +425 -0
- package/src/env/session/search-query-parser.ts +171 -0
- package/src/env/session/session-checkpoint.test.ts +523 -0
- package/src/env/session/session-component.extract-recent-messages.test.ts +209 -0
- package/src/env/session/session-component.test.ts +132 -0
- package/src/env/session/session-component.ts +1249 -0
- package/src/env/session/session-config-registration.test.ts +138 -0
- package/src/env/session/session-config-registration.ts +52 -0
- package/src/env/session/session-message-converter.test.ts +763 -0
- package/src/env/session/session-message-converter.ts +415 -0
- package/src/env/session/session-message-e2e.test.ts +448 -0
- package/src/env/session/session-search.test.ts +391 -0
- package/src/env/session/session-store.test.ts +362 -0
- package/src/env/session/session-store.ts +141 -0
- package/src/env/session/storage/index.ts +6 -0
- package/src/env/session/storage/memory.ts +502 -0
- package/src/env/session/storage/sqlite.ts +794 -0
- package/src/env/session/types.ts +742 -0
- package/src/env/skill/config.ts +39 -0
- package/src/env/skill/index.ts +6 -0
- package/src/env/skill/parser.test.ts +116 -0
- package/src/env/skill/parser.ts +77 -0
- package/src/env/skill/scanner.test.ts +211 -0
- package/src/env/skill/scanner.ts +119 -0
- package/src/env/skill/skill-component.test.ts +234 -0
- package/src/env/skill/skill-component.ts +352 -0
- package/src/env/skill/skill-config-registration.test.ts +60 -0
- package/src/env/skill/skill-config-registration.ts +43 -0
- package/src/env/skill/tool/index.ts +1 -0
- package/src/env/skill/tool/skill-tool.test.ts +100 -0
- package/src/env/skill/tool/skill-tool.ts +72 -0
- package/src/env/skill/types.ts +64 -0
- package/src/env/task/delegate/delegate-tool.test.ts +498 -0
- package/src/env/task/delegate/delegate-tool.ts +1014 -0
- package/src/env/task/delegate/index.ts +18 -0
- package/src/env/task/delegate/stop-tool.test.ts +140 -0
- package/src/env/task/delegate/stop-tool.ts +119 -0
- package/src/env/task/delegate/task-events.test.ts +178 -0
- package/src/env/task/delegate/task-events.ts +143 -0
- package/src/env/task/hooks/contexts.test.ts +92 -0
- package/src/env/task/hooks/contexts.ts +192 -0
- package/src/env/task/hooks/index.ts +23 -0
- package/src/env/task/hooks/task-hook-points.test.ts +32 -0
- package/src/env/task/hooks/task-hook-points.ts +54 -0
- package/src/env/task/index.ts +7 -0
- package/src/env/task/plugins/index.ts +13 -0
- package/src/env/task/plugins/task-plugin.test.ts +74 -0
- package/src/env/task/plugins/task-plugin.ts +89 -0
- package/src/env/task/plugins/task-tag-plugin.test.ts +377 -0
- package/src/env/task/plugins/task-tag-plugin.ts +319 -0
- package/src/env/task/plugins/task-workflow-extractor.integration.test.ts +226 -0
- package/src/env/task/plugins/workflow-extractor-agent.test.ts +107 -0
- package/src/env/task/plugins/workflow-extractor-agent.ts +225 -0
- package/src/env/task/storage/index.ts +6 -0
- package/src/env/task/storage/sqlite-task-store.test.ts +283 -0
- package/src/env/task/storage/sqlite-task-store.ts +903 -0
- package/src/env/task/storage/task-search.test.ts +291 -0
- package/src/env/task/tag-service.test.ts +198 -0
- package/src/env/task/tag-service.ts +264 -0
- package/src/env/task/task-component.test.ts +193 -0
- package/src/env/task/task-component.ts +658 -0
- package/src/env/task/task-config-registration.test.ts +57 -0
- package/src/env/task/task-config-registration.ts +37 -0
- package/src/env/task/task-types.test.ts +137 -0
- package/src/env/task/tools/complete-tool.ts +44 -0
- package/src/env/task/tools/create-tool.ts +49 -0
- package/src/env/task/tools/delete-tool.ts +43 -0
- package/src/env/task/tools/get-tool.ts +59 -0
- package/src/env/task/tools/index.ts +10 -0
- package/src/env/task/tools/list-tool.ts +40 -0
- package/src/env/task/tools/operation/create-tool.ts +48 -0
- package/src/env/task/tools/operation/delete-tool.ts +43 -0
- package/src/env/task/tools/operation/get-tool.ts +43 -0
- package/src/env/task/tools/operation/index.ts +9 -0
- package/src/env/task/tools/operation/list-tool.ts +40 -0
- package/src/env/task/tools/operation/operation-tools.test.ts +274 -0
- package/src/env/task/tools/operation/operation-types.ts +75 -0
- package/src/env/task/tools/operation/update-tool.ts +47 -0
- package/src/env/task/tools/task-tools.test.ts +203 -0
- package/src/env/task/tools/task-types.test.ts +75 -0
- package/src/env/task/tools/task-types.ts +68 -0
- package/src/env/task/tools/update-tool.ts +70 -0
- package/src/env/task/types.ts +160 -0
- package/src/env/tool/built-in/bash.ts +201 -0
- package/src/env/tool/built-in/echo.ts +29 -0
- package/src/env/tool/built-in/edit-file.test.ts +136 -0
- package/src/env/tool/built-in/edit-file.ts +92 -0
- package/src/env/tool/built-in/glob.test.ts +94 -0
- package/src/env/tool/built-in/glob.ts +65 -0
- package/src/env/tool/built-in/grep.test.ts +122 -0
- package/src/env/tool/built-in/grep.ts +108 -0
- package/src/env/tool/built-in/index.ts +44 -0
- package/src/env/tool/built-in/read-file.test.ts +84 -0
- package/src/env/tool/built-in/read-file.ts +75 -0
- package/src/env/tool/built-in/write-file.test.ts +119 -0
- package/src/env/tool/built-in/write-file.ts +68 -0
- package/src/env/tool/index.ts +24 -0
- package/src/env/tool/registry.test.ts +257 -0
- package/src/env/tool/registry.ts +167 -0
- package/src/env/tool/tool-component.test.ts +559 -0
- package/src/env/tool/tool-component.ts +563 -0
- package/src/env/tool/tool-config-registration.test.ts +249 -0
- package/src/env/tool/tool-config-registration.ts +46 -0
- package/src/env/tool/types.ts +267 -0
- package/src/env/tool/validator.test.ts +143 -0
- package/src/env/tool/validator.ts +44 -0
- package/src/env/types.ts +180 -0
- package/src/env/workflow/ask-user-tool-registration.test.ts +216 -0
- package/src/env/workflow/complex-workflow.integration.test.ts +1900 -0
- package/src/env/workflow/decorators/decorator-node.ts +229 -0
- package/src/env/workflow/decorators/decorator.test.ts +196 -0
- package/src/env/workflow/decorators/edge.ts +82 -0
- package/src/env/workflow/decorators/index.ts +31 -0
- package/src/env/workflow/decorators/node-as.ts +98 -0
- package/src/env/workflow/decorators/workflow.ts +54 -0
- package/src/env/workflow/engine/dag-manager.test.ts +570 -0
- package/src/env/workflow/engine/dag-manager.ts +594 -0
- package/src/env/workflow/engine/engine.ts +1422 -0
- package/src/env/workflow/engine/event-bus.test.ts +359 -0
- package/src/env/workflow/engine/event-bus.ts +156 -0
- package/src/env/workflow/engine/executor-agent-session.test.ts +84 -0
- package/src/env/workflow/engine/executor.test.ts +619 -0
- package/src/env/workflow/engine/executor.ts +593 -0
- package/src/env/workflow/engine/index.ts +24 -0
- package/src/env/workflow/engine/node-registry.test.ts +560 -0
- package/src/env/workflow/engine/node-registry.ts +289 -0
- package/src/env/workflow/engine/resume-removed.test.ts +22 -0
- package/src/env/workflow/engine/scheduler.test.ts +715 -0
- package/src/env/workflow/engine/scheduler.ts +318 -0
- package/src/env/workflow/engine/workflow-engine.test.ts +815 -0
- package/src/env/workflow/extractor/workflow-converter.ts +306 -0
- package/src/env/workflow/fixtures.ts +380 -0
- package/src/env/workflow/index.ts +38 -0
- package/src/env/workflow/integration/run-resume-unified.test.ts +186 -0
- package/src/env/workflow/integration/service-integration.test.ts +267 -0
- package/src/env/workflow/metadata/keys.ts +12 -0
- package/src/env/workflow/nodes/agent-component-adapter.test.ts +318 -0
- package/src/env/workflow/nodes/agent-component-adapter.ts +448 -0
- package/src/env/workflow/nodes/agent-node.test.ts +371 -0
- package/src/env/workflow/nodes/agent-node.ts +598 -0
- package/src/env/workflow/nodes/ask-user-node.ts +113 -0
- package/src/env/workflow/nodes/condition-node.ts +200 -0
- package/src/env/workflow/nodes/index.ts +9 -0
- package/src/env/workflow/nodes/merge-node.ts +141 -0
- package/src/env/workflow/nodes/skill-node.test.ts +253 -0
- package/src/env/workflow/nodes/skill-node.ts +393 -0
- package/src/env/workflow/nodes/tool-node.test.ts +251 -0
- package/src/env/workflow/nodes/tool-node.ts +493 -0
- package/src/env/workflow/nodes/workflow-llm-history.test.ts +455 -0
- package/src/env/workflow/nodes/workflow-node.test.ts +315 -0
- package/src/env/workflow/nodes/workflow-node.ts +311 -0
- package/src/env/workflow/service/index.ts +27 -0
- package/src/env/workflow/service/registry.test.ts +133 -0
- package/src/env/workflow/service/registry.ts +71 -0
- package/src/env/workflow/service/workflow-service.test.ts +310 -0
- package/src/env/workflow/service/workflow-service.ts +393 -0
- package/src/env/workflow/storage/index.ts +28 -0
- package/src/env/workflow/storage/mock-repositories.ts +385 -0
- package/src/env/workflow/storage/sqlite.test.ts +179 -0
- package/src/env/workflow/storage/sqlite.ts +163 -0
- package/src/env/workflow/storage/workflow-repo.test.ts +780 -0
- package/src/env/workflow/storage/workflow-repo.ts +342 -0
- package/src/env/workflow/tools/ask-user-tool.ts +82 -0
- package/src/env/workflow/tools/index.ts +26 -0
- package/src/env/workflow/tools/run-workflow.test.ts +352 -0
- package/src/env/workflow/tools/run-workflow.ts +214 -0
- package/src/env/workflow/types/context.ts +18 -0
- package/src/env/workflow/types/decorators-types.ts +198 -0
- package/src/env/workflow/types/event.test.ts +515 -0
- package/src/env/workflow/types/event.ts +193 -0
- package/src/env/workflow/types/index.ts +49 -0
- package/src/env/workflow/types/run.test.ts +437 -0
- package/src/env/workflow/types/run.ts +173 -0
- package/src/env/workflow/types/workflow-hil.ts +114 -0
- package/src/env/workflow/types/workflow-message.test.ts +138 -0
- package/src/env/workflow/types/workflow-message.ts +196 -0
- package/src/env/workflow/types/workflow-session.test.ts +95 -0
- package/src/env/workflow/types/workflow-session.ts +59 -0
- package/src/env/workflow/types/workflow.test.ts +495 -0
- package/src/env/workflow/types/workflow.ts +195 -0
- package/src/env/workflow/types_compat.ts +51 -0
- package/src/env/workflow/utils/create-workflow.ts +47 -0
- package/src/env/workflow/utils/execution-state.ts +245 -0
- package/src/env/workflow/utils/index.ts +18 -0
- package/src/env/workflow/utils/node-registry-helper.ts +58 -0
- package/src/env/workflow/utils/recovery-validator.test.ts +460 -0
- package/src/env/workflow/utils/recovery-validator.ts +377 -0
- package/src/env/workflow/utils/session-parser.test.ts +111 -0
- package/src/env/workflow/utils/session-parser.ts +94 -0
- package/src/env/workflow/utils/session-recovery.test.ts +334 -0
- package/src/env/workflow/utils/session-recovery.ts +188 -0
- package/src/env/workflow/utils/template-resolver.test.ts +258 -0
- package/src/env/workflow/utils/template-resolver.ts +436 -0
- package/src/env/workflow/utils/validation-rules.ts +149 -0
- package/src/env/workflow/workflow-component.ts +544 -0
- package/src/index.ts +422 -0
- package/src/utils/id.ts +21 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tests for TaskStore searchTasksByKeywords functionality
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, test, expect, beforeEach } from "bun:test";
|
|
6
|
+
import { SQLiteTaskStore } from "./sqlite-task-store";
|
|
7
|
+
|
|
8
|
+
describe("TaskStore.searchTasks with keywords", () => {
|
|
9
|
+
let store: SQLiteTaskStore;
|
|
10
|
+
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
store = new SQLiteTaskStore(":memory:");
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// ========================================================================
|
|
16
|
+
// 基本搜索
|
|
17
|
+
// ========================================================================
|
|
18
|
+
|
|
19
|
+
test("should find tasks by keyword (single keyword)", async () => {
|
|
20
|
+
// Create tasks
|
|
21
|
+
await store.createTask({
|
|
22
|
+
title: "Fix login bug",
|
|
23
|
+
description: "Login page has issues",
|
|
24
|
+
tags: ["bug", "authentication"],
|
|
25
|
+
sessionId: "test",
|
|
26
|
+
});
|
|
27
|
+
await store.createTask({
|
|
28
|
+
title: "Add new feature",
|
|
29
|
+
description: "Implement new feature",
|
|
30
|
+
tags: ["feature"],
|
|
31
|
+
sessionId: "test",
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const results = await store.searchTasksByKeywords(["login"]);
|
|
35
|
+
|
|
36
|
+
expect(results.length).toBe(1);
|
|
37
|
+
expect(results[0].title).toBe("Fix login bug");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("should support multi-keyword AND search", async () => {
|
|
41
|
+
await store.createTask({
|
|
42
|
+
title: "Fix login bug",
|
|
43
|
+
description: "Login page has issues",
|
|
44
|
+
tags: ["bug", "authentication"],
|
|
45
|
+
sessionId: "test",
|
|
46
|
+
});
|
|
47
|
+
await store.createTask({
|
|
48
|
+
title: "Fix register bug",
|
|
49
|
+
description: "Register page has issues",
|
|
50
|
+
tags: ["bug"],
|
|
51
|
+
sessionId: "test",
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const results = await store.searchTasksByKeywords(["fix", "login"]);
|
|
55
|
+
|
|
56
|
+
expect(results.length).toBeGreaterThanOrEqual(1);
|
|
57
|
+
expect(results[0].title).toContain("login");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// ========================================================================
|
|
61
|
+
// 关键字列表搜索
|
|
62
|
+
// ========================================================================
|
|
63
|
+
|
|
64
|
+
test("should support keywords array parameter", async () => {
|
|
65
|
+
await store.createTask({
|
|
66
|
+
title: "Implement user authentication",
|
|
67
|
+
description: "User login and logout",
|
|
68
|
+
tags: ["auth", "security"],
|
|
69
|
+
sessionId: "test",
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const results = await store.searchTasksByKeywords(["auth", "user", "security"]);
|
|
73
|
+
|
|
74
|
+
expect(results.length).toBe(1);
|
|
75
|
+
expect(results[0].title).toContain("authentication");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("should search in tags field", async () => {
|
|
79
|
+
await store.createTask({
|
|
80
|
+
title: "Task 1",
|
|
81
|
+
description: "Description",
|
|
82
|
+
tags: ["typescript", "backend"],
|
|
83
|
+
sessionId: "test",
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const results = await store.searchTasksByKeywords(["typescript"]);
|
|
87
|
+
|
|
88
|
+
expect(results.length).toBe(1);
|
|
89
|
+
expect(results[0].tags).toContain("typescript");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("should search in description field", async () => {
|
|
93
|
+
await store.createTask({
|
|
94
|
+
title: "Task without keyword in title",
|
|
95
|
+
description: "This is about database optimization",
|
|
96
|
+
sessionId: "test",
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const results = await store.searchTasksByKeywords(["database"]);
|
|
100
|
+
|
|
101
|
+
expect(results.length).toBe(1);
|
|
102
|
+
expect(results[0].description).toContain("database");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("should search in goals_and_expected_deliverables field", async () => {
|
|
106
|
+
await store.createTask({
|
|
107
|
+
title: "Task without keyword in title",
|
|
108
|
+
description: "General description",
|
|
109
|
+
goals_and_expected_deliverables: "Improve API performance by 50%",
|
|
110
|
+
sessionId: "test",
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const results = await store.searchTasksByKeywords(["performance"]);
|
|
114
|
+
|
|
115
|
+
expect(results.length).toBe(1);
|
|
116
|
+
expect(results[0].goals_and_expected_deliverables).toContain("performance");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test("should search in operation records", async () => {
|
|
120
|
+
const task = await store.createTask({
|
|
121
|
+
title: "Task with operation",
|
|
122
|
+
description: "Description",
|
|
123
|
+
sessionId: "test",
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
await store.createOperation({
|
|
127
|
+
taskId: task.id,
|
|
128
|
+
sessionId: "test",
|
|
129
|
+
actionType: "solution",
|
|
130
|
+
actionTitle: "Implemented caching mechanism",
|
|
131
|
+
actionDescription: "Added Redis caching for API responses",
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const results = await store.searchTasksByKeywords(["caching", "redis"]);
|
|
135
|
+
|
|
136
|
+
expect(results.length).toBe(1);
|
|
137
|
+
expect(results[0].id).toBe(task.id);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test("should exclude specified task ID", async () => {
|
|
141
|
+
const task1 = await store.createTask({
|
|
142
|
+
title: "Duplicate task",
|
|
143
|
+
description: "Same description",
|
|
144
|
+
tags: ["test"],
|
|
145
|
+
sessionId: "test",
|
|
146
|
+
});
|
|
147
|
+
await store.createTask({
|
|
148
|
+
title: "Another task",
|
|
149
|
+
description: "Same description",
|
|
150
|
+
tags: ["test"],
|
|
151
|
+
sessionId: "test",
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const results = await store.searchTasksByKeywords(["test"], { excludeTaskId: task1.id });
|
|
155
|
+
|
|
156
|
+
expect(results.length).toBe(1);
|
|
157
|
+
expect(results[0].id).not.toBe(task1.id);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test("should support limit parameter", async () => {
|
|
161
|
+
// Create 5 tasks with same tag
|
|
162
|
+
for (let i = 0; i < 5; i++) {
|
|
163
|
+
await store.createTask({
|
|
164
|
+
title: `Task ${i}`,
|
|
165
|
+
description: "Same description with keyword",
|
|
166
|
+
tags: ["test"],
|
|
167
|
+
sessionId: "test",
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const results = await store.searchTasksByKeywords(["keyword"], { limit: 2 });
|
|
172
|
+
|
|
173
|
+
expect(results.length).toBeLessThanOrEqual(2);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// ========================================================================
|
|
177
|
+
// 类似任务查找
|
|
178
|
+
// ========================================================================
|
|
179
|
+
|
|
180
|
+
test("should find similar tasks by tags", async () => {
|
|
181
|
+
const task1 = await store.createTask({
|
|
182
|
+
title: "Task 1",
|
|
183
|
+
description: "Description",
|
|
184
|
+
tags: ["bug", "backend"],
|
|
185
|
+
sessionId: "test",
|
|
186
|
+
});
|
|
187
|
+
const task2 = await store.createTask({
|
|
188
|
+
title: "Task 2",
|
|
189
|
+
description: "Description",
|
|
190
|
+
tags: ["bug", "frontend"],
|
|
191
|
+
sessionId: "test",
|
|
192
|
+
});
|
|
193
|
+
await store.createTask({
|
|
194
|
+
title: "Task 3",
|
|
195
|
+
description: "Description",
|
|
196
|
+
tags: ["feature"],
|
|
197
|
+
sessionId: "test",
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
const results = await store.findSimilarTasksByKeywords(["bug"], { excludeTaskId: task1.id });
|
|
201
|
+
|
|
202
|
+
expect(results.length).toBe(1);
|
|
203
|
+
expect(results[0].id).toBe(task2.id);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test("should exclude itself from results", async () => {
|
|
207
|
+
const task = await store.createTask({
|
|
208
|
+
title: "My task",
|
|
209
|
+
description: "My description",
|
|
210
|
+
tags: ["test"],
|
|
211
|
+
sessionId: "test",
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const results = await store.findSimilarTasksByKeywords(["test"], { excludeTaskId: task.id });
|
|
215
|
+
|
|
216
|
+
expect(results.length).toBe(0);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
test("should sort by relevance", async () => {
|
|
220
|
+
const task1 = await store.createTask({
|
|
221
|
+
title: "Task 1",
|
|
222
|
+
description: "Description with bug",
|
|
223
|
+
tags: ["bug"],
|
|
224
|
+
sessionId: "test",
|
|
225
|
+
});
|
|
226
|
+
const task2 = await store.createTask({
|
|
227
|
+
title: "Task 2",
|
|
228
|
+
description: "Description",
|
|
229
|
+
tags: ["bug", "backend", "api"],
|
|
230
|
+
sessionId: "test",
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const results = await store.findSimilarTasksByKeywords(["bug", "backend"]);
|
|
234
|
+
|
|
235
|
+
// Task2 has more matches (3 tags vs 1)
|
|
236
|
+
expect(results[0].id).toBe(task2.id);
|
|
237
|
+
expect(results[1].id).toBe(task1.id);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// ========================================================================
|
|
241
|
+
// 向后兼容
|
|
242
|
+
// ========================================================================
|
|
243
|
+
|
|
244
|
+
test("original query parameter should still work", async () => {
|
|
245
|
+
await store.createTask({
|
|
246
|
+
title: "Login feature",
|
|
247
|
+
description: "Implement login",
|
|
248
|
+
sessionId: "test",
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const results = await store.searchTasks("login");
|
|
252
|
+
|
|
253
|
+
expect(results.length).toBe(1);
|
|
254
|
+
expect(results[0].title).toContain("Login");
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// ========================================================================
|
|
258
|
+
// 边界情况
|
|
259
|
+
// ========================================================================
|
|
260
|
+
|
|
261
|
+
test("should return empty array when no results", async () => {
|
|
262
|
+
const results = await store.searchTasksByKeywords(["nonexistent"]);
|
|
263
|
+
|
|
264
|
+
expect(results.length).toBe(0);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
test("should return empty array for empty keywords list", async () => {
|
|
268
|
+
await store.createTask({
|
|
269
|
+
title: "Test task",
|
|
270
|
+
description: "Description",
|
|
271
|
+
sessionId: "test",
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
const results = await store.searchTasksByKeywords([]);
|
|
275
|
+
|
|
276
|
+
expect(results.length).toBe(0);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
test("should handle case insensitivity", async () => {
|
|
280
|
+
await store.createTask({
|
|
281
|
+
title: "BUG FIX",
|
|
282
|
+
description: "Description",
|
|
283
|
+
tags: ["BACKEND"],
|
|
284
|
+
sessionId: "test",
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
const results = await store.searchTasksByKeywords(["bug", "backend"]);
|
|
288
|
+
|
|
289
|
+
expect(results.length).toBe(1);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview TagService Tests
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, test, expect, beforeEach } from "vitest";
|
|
6
|
+
import { DefaultTagService } from "./tag-service";
|
|
7
|
+
import { SQLiteTaskStore } from "./storage/sqlite-task-store";
|
|
8
|
+
import type { TaskStore } from "./storage/sqlite-task-store";
|
|
9
|
+
|
|
10
|
+
describe("TagService", () => {
|
|
11
|
+
let store: TaskStore;
|
|
12
|
+
let tagService: DefaultTagService;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
store = new SQLiteTaskStore(":memory:");
|
|
16
|
+
tagService = new DefaultTagService(store);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe("Tag CRUD", () => {
|
|
20
|
+
test("should create a tag", async () => {
|
|
21
|
+
const tag = await tagService.createTag("bug");
|
|
22
|
+
|
|
23
|
+
expect(tag.id).toBeDefined();
|
|
24
|
+
expect(tag.name).toBe("bug");
|
|
25
|
+
expect(tag.taskCount).toBe(0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("should return existing tag if name already exists", async () => {
|
|
29
|
+
const tag1 = await tagService.createTag("feature");
|
|
30
|
+
const tag2 = await tagService.createTag("feature");
|
|
31
|
+
|
|
32
|
+
expect(tag1.id).toBe(tag2.id);
|
|
33
|
+
expect(tag2.name).toBe("feature");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("should get tag by id", async () => {
|
|
37
|
+
const created = await tagService.createTag("docs");
|
|
38
|
+
const retrieved = await tagService.getTag(created.id);
|
|
39
|
+
|
|
40
|
+
expect(retrieved?.name).toBe("docs");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("should get tag by name", async () => {
|
|
44
|
+
await tagService.createTag("refactor");
|
|
45
|
+
const tag = await tagService.getTagByName("refactor");
|
|
46
|
+
|
|
47
|
+
expect(tag?.name).toBe("refactor");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("should list tags ordered by count", async () => {
|
|
51
|
+
await tagService.createTag("tag1");
|
|
52
|
+
await tagService.createTag("tag2");
|
|
53
|
+
await tagService.createTag("tag3");
|
|
54
|
+
|
|
55
|
+
const tags = await tagService.listTags({ orderBy: "count" });
|
|
56
|
+
|
|
57
|
+
expect(tags).toHaveLength(3);
|
|
58
|
+
expect(tags[0].name).toBe("tag1");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("should search tags by name", async () => {
|
|
62
|
+
await tagService.createTag("bug");
|
|
63
|
+
await tagService.createTag("bug-fix");
|
|
64
|
+
await tagService.createTag("feature");
|
|
65
|
+
|
|
66
|
+
const results = await tagService.searchTags({ query: "bug" });
|
|
67
|
+
|
|
68
|
+
expect(results.length).toBeGreaterThanOrEqual(2);
|
|
69
|
+
expect(results.some(t => t.name === "bug")).toBe(true);
|
|
70
|
+
expect(results.some(t => t.name === "bug-fix")).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("should delete tag", async () => {
|
|
74
|
+
const tag = await tagService.createTag("to-delete");
|
|
75
|
+
const result = await tagService.deleteTag(tag.id);
|
|
76
|
+
|
|
77
|
+
expect(result).toBe(true);
|
|
78
|
+
expect(await tagService.getTag(tag.id)).toBeUndefined();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe("Tag and Task Association", () => {
|
|
83
|
+
test("should add tags to task", async () => {
|
|
84
|
+
// Create task first
|
|
85
|
+
const task = await store.createTask({
|
|
86
|
+
title: "Test Task",
|
|
87
|
+
sessionId: "test-session",
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const tag1 = await tagService.createTag("frontend");
|
|
91
|
+
const tag2 = await tagService.createTag("ui");
|
|
92
|
+
|
|
93
|
+
await tagService.addTagsToTask(task.id, [tag1.id, tag2.id]);
|
|
94
|
+
|
|
95
|
+
const tags = await tagService.getTagsForTask(task.id);
|
|
96
|
+
expect(tags).toHaveLength(2);
|
|
97
|
+
expect(tags.map(t => t.name)).toContain("frontend");
|
|
98
|
+
expect(tags.map(t => t.name)).toContain("ui");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("should remove tags from task", async () => {
|
|
102
|
+
const task = await store.createTask({
|
|
103
|
+
title: "Test Task",
|
|
104
|
+
sessionId: "test-session",
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const tag = await tagService.createTag("test");
|
|
108
|
+
await tagService.addTagsToTask(task.id, [tag.id]);
|
|
109
|
+
await tagService.removeTagsFromTask(task.id, [tag.id]);
|
|
110
|
+
|
|
111
|
+
const tags = await tagService.getTagsForTask(task.id);
|
|
112
|
+
expect(tags).toHaveLength(0);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("should get task IDs by tag names", async () => {
|
|
116
|
+
const task1 = await store.createTask({
|
|
117
|
+
title: "Task 1",
|
|
118
|
+
sessionId: "test-session",
|
|
119
|
+
});
|
|
120
|
+
const task2 = await store.createTask({
|
|
121
|
+
title: "Task 2",
|
|
122
|
+
sessionId: "test-session",
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const tag = await tagService.createTag("common");
|
|
126
|
+
await tagService.addTagsToTask(task1.id, [tag.id]);
|
|
127
|
+
await tagService.addTagsToTask(task2.id, [tag.id]);
|
|
128
|
+
|
|
129
|
+
const taskIds = await tagService.getTaskIdsByTags(["common"]);
|
|
130
|
+
|
|
131
|
+
expect(taskIds).toContain(task1.id);
|
|
132
|
+
expect(taskIds).toContain(task2.id);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test("should sync tags to task", async () => {
|
|
136
|
+
const task = await store.createTask({
|
|
137
|
+
title: "Test Task",
|
|
138
|
+
sessionId: "test-session",
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
await tagService.syncTagsToTask(task.id, ["new-tag1", "new-tag2"]);
|
|
142
|
+
|
|
143
|
+
const tags = await tagService.getTagsForTask(task.id);
|
|
144
|
+
expect(tags).toHaveLength(2);
|
|
145
|
+
expect(tags.map(t => t.name)).toContain("new-tag1");
|
|
146
|
+
expect(tags.map(t => t.name)).toContain("new-tag2");
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("Retrieval Capabilities", () => {
|
|
151
|
+
// TODO: Skip until findSimilarTasks is implemented
|
|
152
|
+
test.skip("should find similar tasks by tags", async () => {
|
|
153
|
+
const task1 = await store.createTask({
|
|
154
|
+
title: "Task 1",
|
|
155
|
+
sessionId: "test-session",
|
|
156
|
+
});
|
|
157
|
+
const task2 = await store.createTask({
|
|
158
|
+
title: "Task 2",
|
|
159
|
+
sessionId: "test-session",
|
|
160
|
+
});
|
|
161
|
+
const task3 = await store.createTask({
|
|
162
|
+
title: "Task 3",
|
|
163
|
+
sessionId: "test-session",
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const tag1 = await tagService.createTag("bug");
|
|
167
|
+
const tag2 = await tagService.createTag("frontend");
|
|
168
|
+
|
|
169
|
+
await tagService.addTagsToTask(task1.id, [tag1.id, tag2.id]);
|
|
170
|
+
await tagService.addTagsToTask(task2.id, [tag1.id]);
|
|
171
|
+
await tagService.addTagsToTask(task3.id, [tag2.id]);
|
|
172
|
+
|
|
173
|
+
const similar = await tagService.findSimilarTasks(task1.id, 5);
|
|
174
|
+
|
|
175
|
+
// Should find task2 (1 tag match) before task3 (0 tag match)
|
|
176
|
+
expect(similar.length).toBeGreaterThan(0);
|
|
177
|
+
expect(similar[0].id).toBe(task2.id);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("should search tasks by query", async () => {
|
|
181
|
+
await store.createTask({
|
|
182
|
+
title: "Fix login bug",
|
|
183
|
+
description: "Users cannot login",
|
|
184
|
+
sessionId: "test-session",
|
|
185
|
+
});
|
|
186
|
+
await store.createTask({
|
|
187
|
+
title: "Add feature",
|
|
188
|
+
description: "New feature request",
|
|
189
|
+
sessionId: "test-session",
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const results = await tagService.searchTasks("login");
|
|
193
|
+
|
|
194
|
+
expect(results.length).toBe(1);
|
|
195
|
+
expect(results[0].title).toContain("login");
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
});
|