crewly 1.8.9 → 1.8.12
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/config/constants.d.ts.map +1 -0
- package/config/index.d.ts.map +1 -0
- package/config/roles/_common/memory-instructions.md +6 -5
- package/config/roles/_common/wiki-instructions.md +49 -0
- package/config/roles/architect/prompt.md +2 -2
- package/config/roles/backend-developer/prompt.md +2 -2
- package/config/roles/designer/prompt.md +2 -2
- package/config/roles/developer/prompt.md +2 -2
- package/config/roles/frontend-developer/prompt.md +2 -2
- package/config/roles/fullstack-dev/prompt.md +2 -2
- package/config/roles/generalist/prompt.md +2 -2
- package/config/roles/ops/prompt.md +2 -2
- package/config/roles/orchestrator/prompt.md +135 -11
- package/config/roles/product-manager/prompt.md +2 -2
- package/config/roles/qa/prompt.md +2 -2
- package/config/roles/qa-engineer/prompt.md +2 -2
- package/config/roles/researcher/prompt.md +15 -6
- package/config/roles/sales/prompt.md +2 -2
- package/config/roles/support/prompt.md +2 -2
- package/config/roles/team-leader/prompt.md +17 -2
- package/config/roles/tpm/prompt.md +2 -2
- package/config/roles/ux-designer/prompt.md +2 -2
- package/config/skills/orchestrator/wiki-cleanup/SKILL.md +89 -0
- package/config/skills/orchestrator/wiki-cleanup/execute.sh +139 -0
- package/config/skills/orchestrator/wiki-lint/SKILL.md +75 -0
- package/config/skills/orchestrator/wiki-lint/execute.sh +66 -0
- package/config/skills/orchestrator/wiki-migrate/SKILL.md +103 -0
- package/config/skills/orchestrator/wiki-migrate/execute.sh +82 -0
- package/config/skills/orchestrator/wiki-process-queue/SKILL.md +9 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +169 -0
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +1779 -0
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +18 -0
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +63 -0
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.routes.js +5 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/wiki/wiki.controller.d.ts +109 -0
- package/dist/backend/backend/src/controllers/wiki/wiki.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/wiki/wiki.controller.js +419 -4
- package/dist/backend/backend/src/controllers/wiki/wiki.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/wiki/wiki.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/wiki/wiki.routes.js +11 -1
- package/dist/backend/backend/src/controllers/wiki/wiki.routes.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +78 -3
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/index.js.orc-bak-20260529 +3130 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +513 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +1568 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.d.ts +86 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.js +147 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts +68 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js +131 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts +130 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js +263 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts +74 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js +140 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts +29 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js +279 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts +340 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +1176 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts +79 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js +145 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts +79 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js +218 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts +16 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/index.js +16 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/index.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts +135 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js +185 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +141 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +310 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts +91 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js +143 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts +103 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js +256 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts +143 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js +264 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts +13 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js +91 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts +135 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +1937 -0
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js +1 -1
- package/dist/backend/backend/src/services/autonomous/auto-assign.service.d.ts +429 -0
- package/dist/backend/backend/src/services/autonomous/auto-assign.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/autonomous/auto-assign.service.js +852 -0
- package/dist/backend/backend/src/services/autonomous/auto-assign.service.js.map +1 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +171 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.js +725 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.js.map +1 -0
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +50 -0
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +45 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +34 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/project-task-watcher.service.d.ts +118 -0
- package/dist/backend/backend/src/services/v3/project-task-watcher.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/project-task-watcher.service.js +326 -0
- package/dist/backend/backend/src/services/v3/project-task-watcher.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.d.ts +72 -0
- package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js +186 -0
- package/dist/backend/backend/src/services/wiki/wiki-backlinks.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.d.ts +27 -4
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js +133 -10
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.d.ts +18 -1
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js +15 -4
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts +74 -0
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js +154 -0
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.d.ts +160 -0
- package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js +399 -0
- package/dist/backend/backend/src/services/wiki/wiki-cleanup.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-lint.service.d.ts +182 -0
- package/dist/backend/backend/src/services/wiki/wiki-lint.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-lint.service.js +505 -0
- package/dist/backend/backend/src/services/wiki/wiki-lint.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-migrate.service.d.ts +232 -0
- package/dist/backend/backend/src/services/wiki/wiki-migrate.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-migrate.service.js +1416 -0
- package/dist/backend/backend/src/services/wiki/wiki-migrate.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-recent.service.d.ts +51 -0
- package/dist/backend/backend/src/services/wiki/wiki-recent.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-recent.service.js +102 -0
- package/dist/backend/backend/src/services/wiki/wiki-recent.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.d.ts +104 -0
- package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.js +229 -0
- package/dist/backend/backend/src/services/wiki/wiki-reflect-trigger.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts +90 -0
- package/dist/backend/backend/src/services/wiki/wiki-search.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-search.service.js +190 -0
- package/dist/backend/backend/src/services/wiki/wiki-search.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.d.ts +164 -0
- package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.js +675 -0
- package/dist/backend/backend/src/services/wiki/wiki-workitem-bridge.service.js.map +1 -0
- package/dist/backend/backend/src/services/workflow/cron-task.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/cron-task.service.js +65 -0
- package/dist/backend/backend/src/services/workflow/cron-task.service.js.map +1 -1
- package/dist/backend/backend/src/types/auto-assign.types.d.ts +271 -0
- package/dist/backend/backend/src/types/auto-assign.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/auto-assign.types.js +136 -0
- package/dist/backend/backend/src/types/auto-assign.types.js.map +1 -0
- package/dist/backend/backend/src/types/cron-task.types.d.ts +16 -1
- package/dist/backend/backend/src/types/cron-task.types.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/esm-require.utils.d.ts +111 -0
- package/dist/backend/backend/src/utils/esm-require.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/esm-require.utils.js +124 -0
- package/dist/backend/backend/src/utils/esm-require.utils.js.map +1 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +220 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +1 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.js +37 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +1 -0
- package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.d.ts +56 -0
- package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.d.ts.map +1 -0
- package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.js +91 -0
- package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.js.map +1 -0
- package/dist/cli/backend/src/services/knowledge/learnings-index.service.d.ts +159 -0
- package/dist/cli/backend/src/services/knowledge/learnings-index.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/knowledge/learnings-index.service.js +304 -0
- package/dist/cli/backend/src/services/knowledge/learnings-index.service.js.map +1 -0
- package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.d.ts +115 -0
- package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.js +215 -0
- package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.js.map +1 -0
- package/dist/cli/backend/src/services/memory/embedding-provider.d.ts +78 -0
- package/dist/cli/backend/src/services/memory/embedding-provider.d.ts.map +1 -0
- package/dist/cli/backend/src/services/memory/embedding-provider.js +179 -0
- package/dist/cli/backend/src/services/memory/embedding-provider.js.map +1 -0
- package/dist/cli/backend/src/services/memory/vector-store.service.d.ts +331 -0
- package/dist/cli/backend/src/services/memory/vector-store.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/memory/vector-store.service.js +814 -0
- package/dist/cli/backend/src/services/memory/vector-store.service.js.map +1 -0
- package/dist/cli/backend/src/services/project/task-tracking.service.d.ts +171 -0
- package/dist/cli/backend/src/services/project/task-tracking.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/project/task-tracking.service.js +725 -0
- package/dist/cli/backend/src/services/project/task-tracking.service.js.map +1 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +45 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/types/auto-assign.types.d.ts +271 -0
- package/dist/cli/backend/src/types/auto-assign.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/auto-assign.types.js +136 -0
- package/dist/cli/backend/src/types/auto-assign.types.js.map +1 -0
- package/dist/cli/cli/src/index.js +0 -0
- package/frontend/dist/assets/{index-db3f5041.css → index-068bb4f6.css} +10 -1
- package/frontend/dist/assets/index-c24ceb15.js +4960 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- package/config/skills/agent/core/query-knowledge/SKILL.md +0 -87
- package/config/skills/agent/core/query-knowledge/execute.sh +0 -30
- package/config/skills/orchestrator/query-knowledge/SKILL.md +0 -75
- package/config/skills/orchestrator/query-knowledge/execute.sh +0 -30
- package/frontend/dist/assets/index-cc115bb4.js +0 -4926
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Search Service
|
|
3
|
+
*
|
|
4
|
+
* In-process full-text search across a wiki vault's `.md` files. Returns
|
|
5
|
+
* per-file matches with line numbers + short snippets so the UI can render
|
|
6
|
+
* a result list and let the user jump straight to a page.
|
|
7
|
+
*
|
|
8
|
+
* Phase 1: simple case-insensitive substring search. No tokenization,
|
|
9
|
+
* stemming, or inverted index. The vaults here are O(100s) of pages so
|
|
10
|
+
* walking + grepping per request is fine; we'll revisit when volumes
|
|
11
|
+
* justify a real index.
|
|
12
|
+
*
|
|
13
|
+
* @module services/wiki/wiki-search.service
|
|
14
|
+
*/
|
|
15
|
+
/** Cap on how many .md files are inspected per search. */
|
|
16
|
+
export declare const WIKI_SEARCH_MAX_FILES = 500;
|
|
17
|
+
/** Cap on how many results returned to the caller. */
|
|
18
|
+
export declare const WIKI_SEARCH_MAX_RESULTS = 50;
|
|
19
|
+
/** Cap on how many snippets surfaced per matching file. */
|
|
20
|
+
export declare const WIKI_SEARCH_MAX_SNIPPETS_PER_FILE = 3;
|
|
21
|
+
/** Maximum query length — guards against pathological input. */
|
|
22
|
+
export declare const WIKI_SEARCH_MAX_QUERY_LENGTH = 200;
|
|
23
|
+
/** Cap on per-file size we will read; larger files are skipped. */
|
|
24
|
+
export declare const WIKI_SEARCH_MAX_FILE_BYTES: number;
|
|
25
|
+
export interface WikiSearchSnippet {
|
|
26
|
+
/** 1-based line number where the match was found. */
|
|
27
|
+
lineNumber: number;
|
|
28
|
+
/** The matching line (trimmed for display). */
|
|
29
|
+
text: string;
|
|
30
|
+
}
|
|
31
|
+
export interface WikiSearchHit {
|
|
32
|
+
/** Relative path inside the vault, with forward slashes. */
|
|
33
|
+
relativePath: string;
|
|
34
|
+
/** True when the filename itself contains the query. */
|
|
35
|
+
filenameMatch: boolean;
|
|
36
|
+
/** Number of total content matches across the file. */
|
|
37
|
+
matchCount: number;
|
|
38
|
+
/** Up to `WIKI_SEARCH_MAX_SNIPPETS_PER_FILE` matching lines. */
|
|
39
|
+
snippets: WikiSearchSnippet[];
|
|
40
|
+
}
|
|
41
|
+
export interface WikiSearchResult {
|
|
42
|
+
ok: true;
|
|
43
|
+
vaultPath: string;
|
|
44
|
+
query: string;
|
|
45
|
+
hits: WikiSearchHit[];
|
|
46
|
+
/** True when the file/result cap was hit; UI should hint "narrow your search". */
|
|
47
|
+
truncated: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface WikiSearchFailure {
|
|
50
|
+
ok: false;
|
|
51
|
+
reason: 'vault_missing' | 'invalid_input' | 'invalid_query';
|
|
52
|
+
message: string;
|
|
53
|
+
}
|
|
54
|
+
export interface WikiSearchInput {
|
|
55
|
+
vaultPath: string;
|
|
56
|
+
query: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Service exposing `search()`. Stateless singleton — the constructor is
|
|
60
|
+
* empty but we use the class pattern to match the rest of the wiki
|
|
61
|
+
* services (`WikiBookkeepService.getInstance()`, etc.).
|
|
62
|
+
*/
|
|
63
|
+
export declare class WikiSearchService {
|
|
64
|
+
private static instance;
|
|
65
|
+
/** Singleton accessor. */
|
|
66
|
+
static getInstance(): WikiSearchService;
|
|
67
|
+
/** Reset for tests. */
|
|
68
|
+
static resetInstance(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Search a vault. Returns either `{ok:true, hits}` or a structured
|
|
71
|
+
* failure. The handler never throws on filesystem read errors — they
|
|
72
|
+
* are silently skipped so one bad file doesn't blank the whole result.
|
|
73
|
+
*/
|
|
74
|
+
search(input: WikiSearchInput): Promise<WikiSearchResult | WikiSearchFailure>;
|
|
75
|
+
/**
|
|
76
|
+
* Recursive walk collecting `.md` files. Skips dotfile dirs (e.g.
|
|
77
|
+
* `.git`, `.queue`) and stops once `WIKI_SEARCH_MAX_FILES` is reached.
|
|
78
|
+
*
|
|
79
|
+
* @param rootDir - vault root (used to compute relativePath).
|
|
80
|
+
* @param dir - current directory being walked.
|
|
81
|
+
* @param acc - accumulator populated with relative paths.
|
|
82
|
+
*/
|
|
83
|
+
private collectMdFiles;
|
|
84
|
+
/**
|
|
85
|
+
* Read one file and accumulate up to `WIKI_SEARCH_MAX_SNIPPETS_PER_FILE`
|
|
86
|
+
* snippets. Returns null when the file matches nothing.
|
|
87
|
+
*/
|
|
88
|
+
private searchFile;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=wiki-search.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-search.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-search.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,sDAAsD;AACtD,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,2DAA2D;AAC3D,eAAO,MAAM,iCAAiC,IAAI,CAAC;AACnD,gEAAgE;AAChE,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,mEAAmE;AACnE,eAAO,MAAM,0BAA0B,QAAa,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,aAAa,EAAE,OAAO,CAAC;IACvB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,IAAI,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,kFAAkF;IAClF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,eAAe,GAAG,eAAe,GAAG,eAAe,CAAC;IAC5D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IAEzD,0BAA0B;IAC1B,MAAM,CAAC,WAAW,IAAI,iBAAiB;IAKvC,uBAAuB;IACvB,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B;;;;OAIG;IACG,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,iBAAiB,CAAC;IAwDnF;;;;;;;OAOG;YACW,cAAc;IAqB5B;;;OAGG;YACW,UAAU;CAuDzB"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Search Service
|
|
3
|
+
*
|
|
4
|
+
* In-process full-text search across a wiki vault's `.md` files. Returns
|
|
5
|
+
* per-file matches with line numbers + short snippets so the UI can render
|
|
6
|
+
* a result list and let the user jump straight to a page.
|
|
7
|
+
*
|
|
8
|
+
* Phase 1: simple case-insensitive substring search. No tokenization,
|
|
9
|
+
* stemming, or inverted index. The vaults here are O(100s) of pages so
|
|
10
|
+
* walking + grepping per request is fine; we'll revisit when volumes
|
|
11
|
+
* justify a real index.
|
|
12
|
+
*
|
|
13
|
+
* @module services/wiki/wiki-search.service
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from 'fs/promises';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
import { existsSync } from 'fs';
|
|
18
|
+
/** Cap on how many .md files are inspected per search. */
|
|
19
|
+
export const WIKI_SEARCH_MAX_FILES = 500;
|
|
20
|
+
/** Cap on how many results returned to the caller. */
|
|
21
|
+
export const WIKI_SEARCH_MAX_RESULTS = 50;
|
|
22
|
+
/** Cap on how many snippets surfaced per matching file. */
|
|
23
|
+
export const WIKI_SEARCH_MAX_SNIPPETS_PER_FILE = 3;
|
|
24
|
+
/** Maximum query length — guards against pathological input. */
|
|
25
|
+
export const WIKI_SEARCH_MAX_QUERY_LENGTH = 200;
|
|
26
|
+
/** Cap on per-file size we will read; larger files are skipped. */
|
|
27
|
+
export const WIKI_SEARCH_MAX_FILE_BYTES = 256 * 1024;
|
|
28
|
+
/**
|
|
29
|
+
* Service exposing `search()`. Stateless singleton — the constructor is
|
|
30
|
+
* empty but we use the class pattern to match the rest of the wiki
|
|
31
|
+
* services (`WikiBookkeepService.getInstance()`, etc.).
|
|
32
|
+
*/
|
|
33
|
+
export class WikiSearchService {
|
|
34
|
+
static instance = null;
|
|
35
|
+
/** Singleton accessor. */
|
|
36
|
+
static getInstance() {
|
|
37
|
+
if (!this.instance)
|
|
38
|
+
this.instance = new WikiSearchService();
|
|
39
|
+
return this.instance;
|
|
40
|
+
}
|
|
41
|
+
/** Reset for tests. */
|
|
42
|
+
static resetInstance() {
|
|
43
|
+
this.instance = null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Search a vault. Returns either `{ok:true, hits}` or a structured
|
|
47
|
+
* failure. The handler never throws on filesystem read errors — they
|
|
48
|
+
* are silently skipped so one bad file doesn't blank the whole result.
|
|
49
|
+
*/
|
|
50
|
+
async search(input) {
|
|
51
|
+
const vaultPath = input.vaultPath;
|
|
52
|
+
const rawQuery = input.query ?? '';
|
|
53
|
+
if (!vaultPath || !path.isAbsolute(vaultPath)) {
|
|
54
|
+
return {
|
|
55
|
+
ok: false,
|
|
56
|
+
reason: 'invalid_input',
|
|
57
|
+
message: 'vaultPath must be an absolute path',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (!existsSync(vaultPath)) {
|
|
61
|
+
return { ok: false, reason: 'vault_missing', message: `vault not found: ${vaultPath}` };
|
|
62
|
+
}
|
|
63
|
+
const query = rawQuery.trim();
|
|
64
|
+
if (query.length === 0) {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
reason: 'invalid_query',
|
|
68
|
+
message: 'query must be at least one non-whitespace character',
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (query.length > WIKI_SEARCH_MAX_QUERY_LENGTH) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
reason: 'invalid_query',
|
|
75
|
+
message: `query exceeds ${WIKI_SEARCH_MAX_QUERY_LENGTH} characters`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const needle = query.toLowerCase();
|
|
79
|
+
const allFiles = [];
|
|
80
|
+
await this.collectMdFiles(vaultPath, vaultPath, allFiles);
|
|
81
|
+
const truncatedFiles = allFiles.length >= WIKI_SEARCH_MAX_FILES;
|
|
82
|
+
const slice = allFiles.slice(0, WIKI_SEARCH_MAX_FILES);
|
|
83
|
+
const hits = [];
|
|
84
|
+
for (const relativePath of slice) {
|
|
85
|
+
const hit = await this.searchFile(vaultPath, relativePath, needle);
|
|
86
|
+
if (hit)
|
|
87
|
+
hits.push(hit);
|
|
88
|
+
}
|
|
89
|
+
// Rank: filename matches first, then matchCount desc, then path asc for stability.
|
|
90
|
+
hits.sort((a, b) => {
|
|
91
|
+
if (a.filenameMatch !== b.filenameMatch)
|
|
92
|
+
return a.filenameMatch ? -1 : 1;
|
|
93
|
+
if (a.matchCount !== b.matchCount)
|
|
94
|
+
return b.matchCount - a.matchCount;
|
|
95
|
+
return a.relativePath.localeCompare(b.relativePath);
|
|
96
|
+
});
|
|
97
|
+
const truncatedResults = hits.length > WIKI_SEARCH_MAX_RESULTS;
|
|
98
|
+
const capped = hits.slice(0, WIKI_SEARCH_MAX_RESULTS);
|
|
99
|
+
const truncated = truncatedFiles || truncatedResults;
|
|
100
|
+
return { ok: true, vaultPath, query, hits: capped, truncated };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Recursive walk collecting `.md` files. Skips dotfile dirs (e.g.
|
|
104
|
+
* `.git`, `.queue`) and stops once `WIKI_SEARCH_MAX_FILES` is reached.
|
|
105
|
+
*
|
|
106
|
+
* @param rootDir - vault root (used to compute relativePath).
|
|
107
|
+
* @param dir - current directory being walked.
|
|
108
|
+
* @param acc - accumulator populated with relative paths.
|
|
109
|
+
*/
|
|
110
|
+
async collectMdFiles(rootDir, dir, acc) {
|
|
111
|
+
if (acc.length >= WIKI_SEARCH_MAX_FILES)
|
|
112
|
+
return;
|
|
113
|
+
let entries;
|
|
114
|
+
try {
|
|
115
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
for (const entry of entries) {
|
|
121
|
+
if (acc.length >= WIKI_SEARCH_MAX_FILES)
|
|
122
|
+
return;
|
|
123
|
+
if (entry.name.startsWith('.'))
|
|
124
|
+
continue;
|
|
125
|
+
const abs = path.join(dir, entry.name);
|
|
126
|
+
if (entry.isDirectory()) {
|
|
127
|
+
await this.collectMdFiles(rootDir, abs, acc);
|
|
128
|
+
}
|
|
129
|
+
else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
130
|
+
const rel = path.relative(rootDir, abs).replace(/\\/g, '/');
|
|
131
|
+
acc.push(rel);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Read one file and accumulate up to `WIKI_SEARCH_MAX_SNIPPETS_PER_FILE`
|
|
137
|
+
* snippets. Returns null when the file matches nothing.
|
|
138
|
+
*/
|
|
139
|
+
async searchFile(vaultPath, relativePath, needle) {
|
|
140
|
+
const absPath = path.join(vaultPath, relativePath);
|
|
141
|
+
const filenameMatch = relativePath.toLowerCase().includes(needle);
|
|
142
|
+
let stat;
|
|
143
|
+
try {
|
|
144
|
+
stat = await fs.stat(absPath);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return filenameMatch
|
|
148
|
+
? { relativePath, filenameMatch: true, matchCount: 0, snippets: [] }
|
|
149
|
+
: null;
|
|
150
|
+
}
|
|
151
|
+
if (stat.size > WIKI_SEARCH_MAX_FILE_BYTES) {
|
|
152
|
+
return filenameMatch
|
|
153
|
+
? { relativePath, filenameMatch: true, matchCount: 0, snippets: [] }
|
|
154
|
+
: null;
|
|
155
|
+
}
|
|
156
|
+
let content;
|
|
157
|
+
try {
|
|
158
|
+
content = await fs.readFile(absPath, 'utf8');
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return filenameMatch
|
|
162
|
+
? { relativePath, filenameMatch: true, matchCount: 0, snippets: [] }
|
|
163
|
+
: null;
|
|
164
|
+
}
|
|
165
|
+
const lines = content.split(/\r?\n/);
|
|
166
|
+
const snippets = [];
|
|
167
|
+
let matchCount = 0;
|
|
168
|
+
for (let i = 0; i < lines.length; i++) {
|
|
169
|
+
const line = lines[i];
|
|
170
|
+
if (line.toLowerCase().includes(needle)) {
|
|
171
|
+
matchCount++;
|
|
172
|
+
if (snippets.length < WIKI_SEARCH_MAX_SNIPPETS_PER_FILE) {
|
|
173
|
+
snippets.push({
|
|
174
|
+
lineNumber: i + 1,
|
|
175
|
+
text: line.trim().slice(0, 300),
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (matchCount === 0 && !filenameMatch)
|
|
181
|
+
return null;
|
|
182
|
+
return {
|
|
183
|
+
relativePath,
|
|
184
|
+
filenameMatch,
|
|
185
|
+
matchCount,
|
|
186
|
+
snippets,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=wiki-search.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-search.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-search.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WikiWorkItemBridgeService — materialises pending wiki work as claimable WIs.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the wiki-bookkeep / wiki-reflect "shouldFire ≥ threshold" cron
|
|
5
|
+
* model with the same V3 pool the rest of the system uses. Two source
|
|
6
|
+
* streams feed the pool:
|
|
7
|
+
*
|
|
8
|
+
* 1. Pending `wiki-queue` items (one WI per vault that has ≥ 1 pending
|
|
9
|
+
* item; the agent drains the whole vault in that WI).
|
|
10
|
+
* 2. Legacy `.crewly/knowledge/*` migration candidates per project (one
|
|
11
|
+
* WI per project root with > 0 proposed pages).
|
|
12
|
+
*
|
|
13
|
+
* Idle agents claim them through `TaskPoolService.claimFromPool` — no
|
|
14
|
+
* extra cron decisions about who to ping. Failures route through the
|
|
15
|
+
* standard task:failed / reconciler escalation paths (closing the loop
|
|
16
|
+
* with the 2026-05-27 reconciler-escalation fix in
|
|
17
|
+
* `reconciler-data-provider.ts:applyCorrection`).
|
|
18
|
+
*
|
|
19
|
+
* PR-1 routing (conservative): both kinds target the orchestrator
|
|
20
|
+
* session. The wiki skills today live under `config/skills/orchestrator/`,
|
|
21
|
+
* so ORC is the only role with a built-in handler. Broadening to TLs is
|
|
22
|
+
* a follow-up once the skills are promoted to a shared path.
|
|
23
|
+
*
|
|
24
|
+
* Dedupe: at most one non-terminal WI per (kind, vaultPath/projectRoot).
|
|
25
|
+
*
|
|
26
|
+
* @module services/wiki/wiki-workitem-bridge.service
|
|
27
|
+
*/
|
|
28
|
+
import { TaskPoolService } from '../task-pool/task-pool.service.js';
|
|
29
|
+
import { WikiQueueService } from './wiki-queue.service.js';
|
|
30
|
+
import { WikiMigrateService } from './wiki-migrate.service.js';
|
|
31
|
+
import { WikiCleanupService } from './wiki-cleanup.service.js';
|
|
32
|
+
/** WorkItem.metadata.kind value identifying a wiki queue drain WI. */
|
|
33
|
+
export declare const META_KIND_WIKI_DRAIN: "wiki_queue_drain";
|
|
34
|
+
/** WorkItem.metadata.kind value identifying a wiki legacy migration WI. */
|
|
35
|
+
export declare const META_KIND_WIKI_MIGRATE: "wiki_legacy_migrate";
|
|
36
|
+
/** WorkItem.metadata.kind value identifying a wiki cleanup (low-quality removal) WI. */
|
|
37
|
+
export declare const META_KIND_WIKI_CLEANUP: "wiki_quality_cleanup";
|
|
38
|
+
export interface WikiWorkItemBridgeOptions {
|
|
39
|
+
/** How often to scan vaults + projects (default 10 min). */
|
|
40
|
+
intervalMs?: number;
|
|
41
|
+
/** Target agent session for the created WIs (default `crewly-orc`). */
|
|
42
|
+
targetAgent?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Max new WIs to publish per tick (default 2). Throttles PTY flood —
|
|
45
|
+
* see {@link DEFAULT_MAX_CREATES_PER_TICK}.
|
|
46
|
+
*/
|
|
47
|
+
maxCreatesPerTick?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Per-key cooldown (default 30 min) between successive create attempts
|
|
50
|
+
* for the same vault path or project root. Survives pool deletes —
|
|
51
|
+
* see {@link DEFAULT_COOLDOWN_MS}.
|
|
52
|
+
*/
|
|
53
|
+
cooldownMs?: number;
|
|
54
|
+
/** Time source override (test seam). Returns `Date.now()` by default. */
|
|
55
|
+
now?: () => number;
|
|
56
|
+
/**
|
|
57
|
+
* Override the state file path (test seam). When omitted, the bridge
|
|
58
|
+
* resolves `~/.crewly/wiki-bridge-state.json` via `getCrewlyHomePath()`.
|
|
59
|
+
* Passing `null` disables persistence entirely — handy for unit tests
|
|
60
|
+
* that don't want filesystem side effects.
|
|
61
|
+
*/
|
|
62
|
+
statePath?: string | null;
|
|
63
|
+
/** Vault discovery override (default: `discoverWikiVaults`). */
|
|
64
|
+
discoverRoots?: () => Promise<string[]>;
|
|
65
|
+
/** Project-root discovery override (default: cwd + projects.json entries). */
|
|
66
|
+
discoverProjectRoots?: () => Promise<string[]>;
|
|
67
|
+
/** Wiki queue service override (test seam). */
|
|
68
|
+
queueService?: WikiQueueService;
|
|
69
|
+
/** Wiki migrate service override (test seam). */
|
|
70
|
+
migrateService?: WikiMigrateService;
|
|
71
|
+
/** Wiki cleanup service override (test seam). */
|
|
72
|
+
cleanupService?: WikiCleanupService;
|
|
73
|
+
/** Task pool override (test seam). */
|
|
74
|
+
taskPool?: TaskPoolService;
|
|
75
|
+
}
|
|
76
|
+
export interface WikiBridgeTickResult {
|
|
77
|
+
scannedVaults: string[];
|
|
78
|
+
createdForVault: string[];
|
|
79
|
+
skippedInflightVaults: string[];
|
|
80
|
+
scannedProjects: string[];
|
|
81
|
+
createdForProject: string[];
|
|
82
|
+
skippedInflightProjects: string[];
|
|
83
|
+
/** Candidates that were eligible but deferred to the next tick because of {@link WikiWorkItemBridgeOptions.maxCreatesPerTick}. */
|
|
84
|
+
deferredByThrottle: string[];
|
|
85
|
+
/** Candidates skipped because their cooldown hasn't elapsed yet. */
|
|
86
|
+
skippedByCooldown: string[];
|
|
87
|
+
/** Vault paths for which a cleanup WI was created this tick. */
|
|
88
|
+
createdCleanupForVault: string[];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Periodic bridge: pending wiki queue items + migration candidates
|
|
92
|
+
* become claimable WorkItems in the V3 pool.
|
|
93
|
+
*/
|
|
94
|
+
export declare class WikiWorkItemBridgeService {
|
|
95
|
+
private static instance;
|
|
96
|
+
private readonly logger;
|
|
97
|
+
private readonly intervalMs;
|
|
98
|
+
private readonly targetAgent;
|
|
99
|
+
private readonly maxCreatesPerTick;
|
|
100
|
+
private readonly cooldownMs;
|
|
101
|
+
private readonly nowFn;
|
|
102
|
+
private readonly discoverRoots;
|
|
103
|
+
private readonly discoverProjectRoots;
|
|
104
|
+
private readonly queue;
|
|
105
|
+
private readonly migrate;
|
|
106
|
+
private readonly cleanup;
|
|
107
|
+
private readonly pool;
|
|
108
|
+
private timer;
|
|
109
|
+
private running;
|
|
110
|
+
/** Per-key (kind + path) last-create timestamp. Survives pool deletes. */
|
|
111
|
+
private readonly lastCreatedAt;
|
|
112
|
+
/** Absolute path of the persisted state file (or `null` to disable). */
|
|
113
|
+
private readonly statePath;
|
|
114
|
+
/** True after `loadStateFromDisk` has either populated or no-op'd. */
|
|
115
|
+
private stateLoaded;
|
|
116
|
+
constructor(opts?: WikiWorkItemBridgeOptions);
|
|
117
|
+
/**
|
|
118
|
+
* Hydrate {@link lastCreatedAt} from disk. Idempotent — runs once per
|
|
119
|
+
* service lifetime. Bad/missing/stale-version files reset to empty.
|
|
120
|
+
*/
|
|
121
|
+
private loadStateFromDisk;
|
|
122
|
+
/**
|
|
123
|
+
* Persist {@link lastCreatedAt} to disk. Best-effort — write failures
|
|
124
|
+
* are logged but never throw (the bridge is non-essential infrastructure).
|
|
125
|
+
* Prunes expired entries before writing so the file stays small.
|
|
126
|
+
*/
|
|
127
|
+
private saveStateToDisk;
|
|
128
|
+
/**
|
|
129
|
+
* True iff the key's cooldown is still active (i.e., we created a WI
|
|
130
|
+
* for this key recently). Survives forced pool deletes so an
|
|
131
|
+
* agent-driven cleanup can't trick the bridge into re-creating
|
|
132
|
+
* immediately.
|
|
133
|
+
*/
|
|
134
|
+
private isCoolingDown;
|
|
135
|
+
private markCreated;
|
|
136
|
+
static getInstance(): WikiWorkItemBridgeService | null;
|
|
137
|
+
/** Wire / detach the production singleton. */
|
|
138
|
+
static setInstance(next: WikiWorkItemBridgeService | null): void;
|
|
139
|
+
/** Start the periodic scan. Idempotent. Fires an immediate tick. */
|
|
140
|
+
start(): void;
|
|
141
|
+
stop(): void;
|
|
142
|
+
/** Single pass — exposed for tests and the initial boot-time fire. */
|
|
143
|
+
tick(): Promise<WikiBridgeTickResult>;
|
|
144
|
+
/**
|
|
145
|
+
* Build the dedupe sets from the pool's current contents. A WI is
|
|
146
|
+
* "in-flight" if its kind metadata matches and its status is not
|
|
147
|
+
* terminal — i.e. it's still queued/claimed/running/etc.
|
|
148
|
+
*/
|
|
149
|
+
private snapshotInflight;
|
|
150
|
+
private createDrainWorkItem;
|
|
151
|
+
private createCleanupWorkItem;
|
|
152
|
+
private createMigrateWorkItem;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Best-effort label for a vault path that surfaces in UI/list views.
|
|
156
|
+
* Order matters: check global before the generic project tail.
|
|
157
|
+
*/
|
|
158
|
+
export declare function describeVaultScope(vaultPath: string): string;
|
|
159
|
+
/**
|
|
160
|
+
* Default project-root discovery used by the production bridge. Mirrors
|
|
161
|
+
* `discoverWikiVaults`'s project sources but returns roots, not vault paths.
|
|
162
|
+
*/
|
|
163
|
+
export declare function defaultProjectRoots(): Promise<string[]>;
|
|
164
|
+
//# sourceMappingURL=wiki-workitem-bridge.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-workitem-bridge.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-workitem-bridge.service.ts"],"names":[],"mappings":"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"}
|