crewly 1.8.9 → 1.8.11
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 +418 -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 +64 -0
- 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 +4 -1
- 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 +24 -1
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.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 +84 -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 +156 -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,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Backlinks Service
|
|
3
|
+
*
|
|
4
|
+
* Given a target page in a vault, scan every other page for `[[wikilink]]`
|
|
5
|
+
* references that resolve to it. Powers the UI's right-side "References"
|
|
6
|
+
* panel.
|
|
7
|
+
*
|
|
8
|
+
* Phase 1: plain scan, no incremental index. Vaults are small enough that
|
|
9
|
+
* a single regex pass per file is fine.
|
|
10
|
+
*
|
|
11
|
+
* @module services/wiki/wiki-backlinks.service
|
|
12
|
+
*/
|
|
13
|
+
/** Hard cap on scanned files to avoid pathological vaults. */
|
|
14
|
+
export declare const WIKI_BACKLINKS_MAX_FILES = 500;
|
|
15
|
+
/** Cap on per-file size to read; larger files are skipped. */
|
|
16
|
+
export declare const WIKI_BACKLINKS_MAX_FILE_BYTES: number;
|
|
17
|
+
/** Max snippets surfaced per source page. */
|
|
18
|
+
export declare const WIKI_BACKLINKS_MAX_SNIPPETS_PER_FILE = 2;
|
|
19
|
+
/** Total backlink rows returned. */
|
|
20
|
+
export declare const WIKI_BACKLINKS_MAX_RESULTS = 50;
|
|
21
|
+
export interface WikiBacklinkSnippet {
|
|
22
|
+
lineNumber: number;
|
|
23
|
+
text: string;
|
|
24
|
+
}
|
|
25
|
+
export interface WikiBacklink {
|
|
26
|
+
/** Source page that links to the target. */
|
|
27
|
+
relativePath: string;
|
|
28
|
+
/** Up to N snippets where the link appears. */
|
|
29
|
+
snippets: WikiBacklinkSnippet[];
|
|
30
|
+
}
|
|
31
|
+
export interface WikiBacklinksInput {
|
|
32
|
+
vaultPath: string;
|
|
33
|
+
/** The page being backlinked TO. */
|
|
34
|
+
relativePath: string;
|
|
35
|
+
}
|
|
36
|
+
export interface WikiBacklinksResult {
|
|
37
|
+
ok: true;
|
|
38
|
+
vaultPath: string;
|
|
39
|
+
relativePath: string;
|
|
40
|
+
backlinks: WikiBacklink[];
|
|
41
|
+
truncated: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface WikiBacklinksFailure {
|
|
44
|
+
ok: false;
|
|
45
|
+
reason: 'vault_missing' | 'invalid_input';
|
|
46
|
+
message: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolve a wikilink target string against a known target page.
|
|
50
|
+
*
|
|
51
|
+
* The matcher mirrors the frontend's `resolveWikilink` semantics so a
|
|
52
|
+
* `[[customers/anthropic]]` reference matches the page at
|
|
53
|
+
* `llm-curated/customers/anthropic.md`.
|
|
54
|
+
*
|
|
55
|
+
* @param wikilinkTarget - Raw target from `[[…]]` (no alias, trimmed).
|
|
56
|
+
* @param normalizedTargetPath - The target page path, normalized (lowercase,
|
|
57
|
+
* forward slashes, with `.md` suffix).
|
|
58
|
+
* @returns true when the wikilink would resolve to the target page.
|
|
59
|
+
*/
|
|
60
|
+
export declare function wikilinkMatchesTarget(wikilinkTarget: string, normalizedTargetPath: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Backlinks service. Singleton pattern to match the other wiki services.
|
|
63
|
+
*/
|
|
64
|
+
export declare class WikiBacklinksService {
|
|
65
|
+
private static instance;
|
|
66
|
+
static getInstance(): WikiBacklinksService;
|
|
67
|
+
static resetInstance(): void;
|
|
68
|
+
find(input: WikiBacklinksInput): Promise<WikiBacklinksResult | WikiBacklinksFailure>;
|
|
69
|
+
private collectMdFiles;
|
|
70
|
+
private scanFile;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=wiki-backlinks.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-backlinks.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-backlinks.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,8DAA8D;AAC9D,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,8DAA8D;AAC9D,eAAO,MAAM,6BAA6B,QAAa,CAAC;AACxD,6CAA6C;AAC7C,eAAO,MAAM,oCAAoC,IAAI,CAAC;AACtD,oCAAoC;AACpC,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAK7C,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,IAAI,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,eAAe,GAAG,eAAe,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,MAAM,EACtB,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CAmBT;AAED;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqC;IAE5D,MAAM,CAAC,WAAW,IAAI,oBAAoB;IAK1C,MAAM,CAAC,aAAa,IAAI,IAAI;IAItB,IAAI,CACR,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,GAAG,oBAAoB,CAAC;YA8CxC,cAAc;YAqBd,QAAQ;CA2CvB"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki Backlinks Service
|
|
3
|
+
*
|
|
4
|
+
* Given a target page in a vault, scan every other page for `[[wikilink]]`
|
|
5
|
+
* references that resolve to it. Powers the UI's right-side "References"
|
|
6
|
+
* panel.
|
|
7
|
+
*
|
|
8
|
+
* Phase 1: plain scan, no incremental index. Vaults are small enough that
|
|
9
|
+
* a single regex pass per file is fine.
|
|
10
|
+
*
|
|
11
|
+
* @module services/wiki/wiki-backlinks.service
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'fs/promises';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import { existsSync } from 'fs';
|
|
16
|
+
/** Hard cap on scanned files to avoid pathological vaults. */
|
|
17
|
+
export const WIKI_BACKLINKS_MAX_FILES = 500;
|
|
18
|
+
/** Cap on per-file size to read; larger files are skipped. */
|
|
19
|
+
export const WIKI_BACKLINKS_MAX_FILE_BYTES = 256 * 1024;
|
|
20
|
+
/** Max snippets surfaced per source page. */
|
|
21
|
+
export const WIKI_BACKLINKS_MAX_SNIPPETS_PER_FILE = 2;
|
|
22
|
+
/** Total backlink rows returned. */
|
|
23
|
+
export const WIKI_BACKLINKS_MAX_RESULTS = 50;
|
|
24
|
+
/** `[[target]]` or `[[target|alias]]`. */
|
|
25
|
+
const WIKILINK_RE = /\[\[([^\]|]+?)(?:\|[^\]]+?)?\]\]/g;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a wikilink target string against a known target page.
|
|
28
|
+
*
|
|
29
|
+
* The matcher mirrors the frontend's `resolveWikilink` semantics so a
|
|
30
|
+
* `[[customers/anthropic]]` reference matches the page at
|
|
31
|
+
* `llm-curated/customers/anthropic.md`.
|
|
32
|
+
*
|
|
33
|
+
* @param wikilinkTarget - Raw target from `[[…]]` (no alias, trimmed).
|
|
34
|
+
* @param normalizedTargetPath - The target page path, normalized (lowercase,
|
|
35
|
+
* forward slashes, with `.md` suffix).
|
|
36
|
+
* @returns true when the wikilink would resolve to the target page.
|
|
37
|
+
*/
|
|
38
|
+
export function wikilinkMatchesTarget(wikilinkTarget, normalizedTargetPath) {
|
|
39
|
+
const raw = wikilinkTarget.trim().toLowerCase();
|
|
40
|
+
if (!raw)
|
|
41
|
+
return false;
|
|
42
|
+
const withMd = raw.endsWith('.md') ? raw : `${raw}.md`;
|
|
43
|
+
if (withMd === normalizedTargetPath)
|
|
44
|
+
return true;
|
|
45
|
+
if (normalizedTargetPath.endsWith(`/${withMd}`))
|
|
46
|
+
return true;
|
|
47
|
+
// Basename match — only if the wikilink target has no slashes (it's just
|
|
48
|
+
// a name) so we don't over-match on partial paths.
|
|
49
|
+
if (!raw.includes('/')) {
|
|
50
|
+
const baseNoMd = raw.endsWith('.md') ? raw.slice(0, -3) : raw;
|
|
51
|
+
const targetBase = normalizedTargetPath.split('/').pop() ?? '';
|
|
52
|
+
const targetBaseNoMd = targetBase.endsWith('.md')
|
|
53
|
+
? targetBase.slice(0, -3)
|
|
54
|
+
: targetBase;
|
|
55
|
+
if (baseNoMd === targetBaseNoMd)
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Backlinks service. Singleton pattern to match the other wiki services.
|
|
62
|
+
*/
|
|
63
|
+
export class WikiBacklinksService {
|
|
64
|
+
static instance = null;
|
|
65
|
+
static getInstance() {
|
|
66
|
+
if (!this.instance)
|
|
67
|
+
this.instance = new WikiBacklinksService();
|
|
68
|
+
return this.instance;
|
|
69
|
+
}
|
|
70
|
+
static resetInstance() {
|
|
71
|
+
this.instance = null;
|
|
72
|
+
}
|
|
73
|
+
async find(input) {
|
|
74
|
+
const { vaultPath, relativePath } = input;
|
|
75
|
+
if (!vaultPath || !path.isAbsolute(vaultPath)) {
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
reason: 'invalid_input',
|
|
79
|
+
message: 'vaultPath must be an absolute path',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (!existsSync(vaultPath)) {
|
|
83
|
+
return { ok: false, reason: 'vault_missing', message: `vault not found: ${vaultPath}` };
|
|
84
|
+
}
|
|
85
|
+
if (!relativePath || !relativePath.endsWith('.md')) {
|
|
86
|
+
return {
|
|
87
|
+
ok: false,
|
|
88
|
+
reason: 'invalid_input',
|
|
89
|
+
message: 'relativePath is required and must end in .md',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const normalizedTarget = relativePath.replace(/\\/g, '/').toLowerCase();
|
|
93
|
+
const allFiles = [];
|
|
94
|
+
await this.collectMdFiles(vaultPath, vaultPath, allFiles);
|
|
95
|
+
const truncatedFiles = allFiles.length >= WIKI_BACKLINKS_MAX_FILES;
|
|
96
|
+
const slice = allFiles.slice(0, WIKI_BACKLINKS_MAX_FILES);
|
|
97
|
+
const backlinks = [];
|
|
98
|
+
for (const source of slice) {
|
|
99
|
+
if (backlinks.length >= WIKI_BACKLINKS_MAX_RESULTS)
|
|
100
|
+
break;
|
|
101
|
+
// A page does not backlink to itself.
|
|
102
|
+
if (source.toLowerCase() === normalizedTarget)
|
|
103
|
+
continue;
|
|
104
|
+
const found = await this.scanFile(vaultPath, source, normalizedTarget);
|
|
105
|
+
if (found)
|
|
106
|
+
backlinks.push(found);
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
ok: true,
|
|
110
|
+
vaultPath,
|
|
111
|
+
relativePath,
|
|
112
|
+
backlinks,
|
|
113
|
+
truncated: truncatedFiles || backlinks.length >= WIKI_BACKLINKS_MAX_RESULTS,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
async collectMdFiles(rootDir, dir, acc) {
|
|
117
|
+
if (acc.length >= WIKI_BACKLINKS_MAX_FILES)
|
|
118
|
+
return;
|
|
119
|
+
let entries;
|
|
120
|
+
try {
|
|
121
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
for (const entry of entries) {
|
|
127
|
+
if (acc.length >= WIKI_BACKLINKS_MAX_FILES)
|
|
128
|
+
return;
|
|
129
|
+
if (entry.name.startsWith('.'))
|
|
130
|
+
continue;
|
|
131
|
+
const abs = path.join(dir, entry.name);
|
|
132
|
+
if (entry.isDirectory()) {
|
|
133
|
+
await this.collectMdFiles(rootDir, abs, acc);
|
|
134
|
+
}
|
|
135
|
+
else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
136
|
+
const rel = path.relative(rootDir, abs).replace(/\\/g, '/');
|
|
137
|
+
acc.push(rel);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async scanFile(vaultPath, relativePath, normalizedTarget) {
|
|
142
|
+
const abs = path.join(vaultPath, relativePath);
|
|
143
|
+
let stat;
|
|
144
|
+
try {
|
|
145
|
+
stat = await fs.stat(abs);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
if (stat.size > WIKI_BACKLINKS_MAX_FILE_BYTES)
|
|
151
|
+
return null;
|
|
152
|
+
let content;
|
|
153
|
+
try {
|
|
154
|
+
content = await fs.readFile(abs, 'utf8');
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
if (!content.includes('[['))
|
|
160
|
+
return null;
|
|
161
|
+
const lines = content.split(/\r?\n/);
|
|
162
|
+
const snippets = [];
|
|
163
|
+
for (let i = 0; i < lines.length; i++) {
|
|
164
|
+
const line = lines[i];
|
|
165
|
+
if (!line.includes('[['))
|
|
166
|
+
continue;
|
|
167
|
+
WIKILINK_RE.lastIndex = 0;
|
|
168
|
+
let m;
|
|
169
|
+
while ((m = WIKILINK_RE.exec(line)) !== null) {
|
|
170
|
+
if (wikilinkMatchesTarget(m[1], normalizedTarget)) {
|
|
171
|
+
if (snippets.length < WIKI_BACKLINKS_MAX_SNIPPETS_PER_FILE) {
|
|
172
|
+
snippets.push({
|
|
173
|
+
lineNumber: i + 1,
|
|
174
|
+
text: line.trim().slice(0, 300),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
break; // one snippet per line
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (snippets.length >= WIKI_BACKLINKS_MAX_SNIPPETS_PER_FILE)
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
return snippets.length > 0 ? { relativePath, snippets } : null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=wiki-backlinks.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-backlinks.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-backlinks.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAEhC,8DAA8D;AAC9D,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAC5C,8DAA8D;AAC9D,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,GAAG,IAAI,CAAC;AACxD,6CAA6C;AAC7C,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,CAAC;AACtD,oCAAoC;AACpC,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAE7C,0CAA0C;AAC1C,MAAM,WAAW,GAAG,mCAAmC,CAAC;AAkCxD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CACnC,cAAsB,EACtB,oBAA4B;IAE5B,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAChD,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IAEvB,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC;IACvD,IAAI,MAAM,KAAK,oBAAoB;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,oBAAoB,CAAC,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7D,yEAAyE;IACzE,mDAAmD;IACnD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9D,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;QAC/D,MAAM,cAAc,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC/C,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACzB,CAAC,CAAC,UAAU,CAAC;QACf,IAAI,QAAQ,KAAK,cAAc;YAAE,OAAO,IAAI,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,oBAAoB;IACvB,MAAM,CAAC,QAAQ,GAAgC,IAAI,CAAC;IAE5D,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC/D,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,aAAa;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,KAAyB;QAEzB,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;QAE1C,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9C,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,eAAe;gBACvB,OAAO,EAAE,oCAAoC;aAC9C,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,oBAAoB,SAAS,EAAE,EAAE,CAAC;QAC1F,CAAC;QACD,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACnD,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,eAAe;gBACvB,OAAO,EAAE,8CAA8C;aACxD,CAAC;QACJ,CAAC;QAED,MAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAExE,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC1D,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,wBAAwB,CAAC;QACnE,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC;QAE1D,MAAM,SAAS,GAAmB,EAAE,CAAC;QACrC,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;YAC3B,IAAI,SAAS,CAAC,MAAM,IAAI,0BAA0B;gBAAE,MAAM;YAC1D,sCAAsC;YACtC,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,gBAAgB;gBAAE,SAAS;YACxD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;YACvE,IAAI,KAAK;gBAAE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,OAAO;YACL,EAAE,EAAE,IAAI;YACR,SAAS;YACT,YAAY;YACZ,SAAS;YACT,SAAS,EAAE,cAAc,IAAI,SAAS,CAAC,MAAM,IAAI,0BAA0B;SAC5E,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,OAAe,EAAE,GAAW,EAAE,GAAa;QACtE,IAAI,GAAG,CAAC,MAAM,IAAI,wBAAwB;YAAE,OAAO;QACnD,IAAI,OAA8B,CAAC;QACnC,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,GAAG,CAAC,MAAM,IAAI,wBAAwB;gBAAE,OAAO;YACnD,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACzC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YAC/C,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAC5D,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,QAAQ,CACpB,SAAiB,EACjB,YAAoB,EACpB,gBAAwB;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QAC/C,IAAI,IAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,GAAG,6BAA6B;YAAE,OAAO,IAAI,CAAC;QAC3D,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAEzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,QAAQ,GAA0B,EAAE,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,SAAS;YACnC,WAAW,CAAC,SAAS,GAAG,CAAC,CAAC;YAC1B,IAAI,CAAyB,CAAC;YAC9B,OAAO,CAAC,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC7C,IAAI,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAAE,CAAC;oBAClD,IAAI,QAAQ,CAAC,MAAM,GAAG,oCAAoC,EAAE,CAAC;wBAC3D,QAAQ,CAAC,IAAI,CAAC;4BACZ,UAAU,EAAE,CAAC,GAAG,CAAC;4BACjB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;yBAChC,CAAC,CAAC;oBACL,CAAC;oBACD,MAAM,CAAC,uBAAuB;gBAChC,CAAC;YACH,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,IAAI,oCAAoC;gBAAE,MAAM;QACrE,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,CAAC"}
|
|
@@ -39,7 +39,10 @@ export interface WikiBookkeepTriggerOptions {
|
|
|
39
39
|
/**
|
|
40
40
|
* Discover absolute vault paths by walking the well-known Crewly roots:
|
|
41
41
|
* - `<env CREWLY_PROJECT_VAULT_PATH>` (single explicit override)
|
|
42
|
-
* - `<process.cwd>/.crewly/wiki` (current project vault)
|
|
42
|
+
* - `<process.cwd>/.crewly/wiki` (current project vault — the OSS's own dir)
|
|
43
|
+
* - `~/.crewly/projects.json` → every registered project's `.crewly/wiki`
|
|
44
|
+
* (Closie, Flopost, CE, etc. — each team manages a project, and that
|
|
45
|
+
* project gets its own vault per v2.1 spec §1)
|
|
43
46
|
* - `~/.crewly/teams/<uuid>/wiki` (every team vault)
|
|
44
47
|
* - `~/.crewly/global-wiki` (ORC cross-project vault, if present)
|
|
45
48
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wiki-bookkeep-trigger.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-bookkeep-trigger.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAOH,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErF,MAAM,MAAM,kBAAkB,GAAG,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,kBAAkB,KACvB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE1B,MAAM,WAAW,0BAA0B;IACzC,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,MAAM,EAAE,kBAAkB,CAAC;IAC3B,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,yDAAyD;IACzD,eAAe,CAAC,EAAE,mBAAmB,CAAC;CACvC;AAKD
|
|
1
|
+
{"version":3,"file":"wiki-bookkeep-trigger.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-bookkeep-trigger.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAOH,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErF,MAAM,MAAM,kBAAkB,GAAG,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,kBAAkB,KACvB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE1B,MAAM,WAAW,0BAA0B;IACzC,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,MAAM,EAAE,kBAAkB,CAAC;IAC3B,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,yDAAyD;IACzD,eAAe,CAAC,EAAE,mBAAmB,CAAC;CACvC;AAKD;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAgD5D;AAED;;GAEG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA2C;IAClE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0B;IACxD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsB;IACtD,OAAO,CAAC,KAAK,CAA+B;IAC5C,6CAA6C;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,kEAAkE;IAClE,OAAO,CAAC,QAAQ,CAAqB;gBAEzB,IAAI,EAAE,0BAA0B;IAS5C,MAAM,CAAC,WAAW,IAAI,0BAA0B,GAAG,IAAI;IAIvD,6EAA6E;IAC7E,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,0BAA0B,GAAG,IAAI,GAAG,IAAI;IAKjE,kCAAkC;IAClC,KAAK,IAAI,IAAI;IAWb,kDAAkD;IAClD,IAAI,IAAI,IAAI;IAQZ;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC;QACpB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;IAoDF,kDAAkD;IAClD,wBAAwB,IAAI,IAAI;CAGjC"}
|
|
@@ -33,7 +33,10 @@ const DEFAULT_DEBOUNCE_MS = 6 * 3600 * 1000;
|
|
|
33
33
|
/**
|
|
34
34
|
* Discover absolute vault paths by walking the well-known Crewly roots:
|
|
35
35
|
* - `<env CREWLY_PROJECT_VAULT_PATH>` (single explicit override)
|
|
36
|
-
* - `<process.cwd>/.crewly/wiki` (current project vault)
|
|
36
|
+
* - `<process.cwd>/.crewly/wiki` (current project vault — the OSS's own dir)
|
|
37
|
+
* - `~/.crewly/projects.json` → every registered project's `.crewly/wiki`
|
|
38
|
+
* (Closie, Flopost, CE, etc. — each team manages a project, and that
|
|
39
|
+
* project gets its own vault per v2.1 spec §1)
|
|
37
40
|
* - `~/.crewly/teams/<uuid>/wiki` (every team vault)
|
|
38
41
|
* - `~/.crewly/global-wiki` (ORC cross-project vault, if present)
|
|
39
42
|
*
|
|
@@ -47,6 +50,26 @@ export async function discoverWikiVaults() {
|
|
|
47
50
|
candidates.push(fromEnv);
|
|
48
51
|
candidates.push(path.join(process.cwd(), '.crewly/wiki'));
|
|
49
52
|
candidates.push(path.join(os.homedir(), '.crewly/global-wiki'));
|
|
53
|
+
// (NEW 2026-05-27) Every registered project's wiki. Without this, only
|
|
54
|
+
// the OSS's own cwd project (Crewly itself) surfaces — Closie/Flopost/CE
|
|
55
|
+
// managed by their teams stay invisible despite being real projects.
|
|
56
|
+
const projectsJsonPath = path.join(os.homedir(), '.crewly/projects.json');
|
|
57
|
+
if (existsSync(projectsJsonPath)) {
|
|
58
|
+
try {
|
|
59
|
+
const raw = await fs.readFile(projectsJsonPath, 'utf8');
|
|
60
|
+
const parsed = JSON.parse(raw);
|
|
61
|
+
if (Array.isArray(parsed)) {
|
|
62
|
+
for (const entry of parsed) {
|
|
63
|
+
if (entry && typeof entry.path === 'string' && path.isAbsolute(entry.path)) {
|
|
64
|
+
candidates.push(path.join(entry.path, '.crewly/wiki'));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// malformed projects.json — skip; partial discovery is fine
|
|
71
|
+
}
|
|
72
|
+
}
|
|
50
73
|
const teamsRoot = path.join(os.homedir(), '.crewly/teams');
|
|
51
74
|
if (existsSync(teamsRoot)) {
|
|
52
75
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wiki-bookkeep-trigger.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-bookkeep-trigger.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAmB,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAsB,MAAM,4BAA4B,CAAC;AAoBrF,MAAM,mBAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAC3C,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C
|
|
1
|
+
{"version":3,"file":"wiki-bookkeep-trigger.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-bookkeep-trigger.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WikiChatSubscriberService — listens on chat-v2's `chat_message` event
|
|
3
|
+
* and fires `WikiIngestService.ingest` for every user-authored message.
|
|
4
|
+
*
|
|
5
|
+
* Phase A (rules-only routing):
|
|
6
|
+
* senderType === 'user' → ingest into the Crewly project vault.
|
|
7
|
+
* senderType === 'agent' | 'system' → skip.
|
|
8
|
+
*
|
|
9
|
+
* Phase B (per spec §4.5) will replace the project-only routing with an
|
|
10
|
+
* LLM-driven gate that picks team / project / global per source.
|
|
11
|
+
*
|
|
12
|
+
* Failure mode is FIRE-AND-FORGET: a malformed message, missing schema,
|
|
13
|
+
* or filesystem error MUST NOT block the live chat flow. Errors are
|
|
14
|
+
* logged at warn-level and swallowed.
|
|
15
|
+
*
|
|
16
|
+
* @module services/wiki/wiki-chat-subscriber.service
|
|
17
|
+
*/
|
|
18
|
+
import type { ChatV2Service } from '../chat-v2/chat-v2.service.js';
|
|
19
|
+
import { WikiIngestService } from './wiki-ingest.service.js';
|
|
20
|
+
/**
|
|
21
|
+
* Shape we consume from chat-v2's `chat_message` payload. Kept narrow so
|
|
22
|
+
* we don't take a heavy structural dep on the wire DTO; matches the
|
|
23
|
+
* fields produced by `toMessageDTO` (chat-v2.service.ts:1537).
|
|
24
|
+
*/
|
|
25
|
+
interface MinimalChatMessageDTO {
|
|
26
|
+
id: string;
|
|
27
|
+
channelId: string;
|
|
28
|
+
senderType: 'user' | 'agent' | 'system';
|
|
29
|
+
senderId: string;
|
|
30
|
+
content: string;
|
|
31
|
+
contentType: string;
|
|
32
|
+
createdAt: string | number;
|
|
33
|
+
}
|
|
34
|
+
export interface WikiChatSubscriberOptions {
|
|
35
|
+
/** chat-v2 singleton — `getChatV2Service()` at composition root. */
|
|
36
|
+
chatService: ChatV2Service;
|
|
37
|
+
/** Absolute path to the project vault. Default falls back to env / well-known location. */
|
|
38
|
+
projectVaultPath?: string;
|
|
39
|
+
/** Optional override for tests. */
|
|
40
|
+
ingestService?: WikiIngestService;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Process-singleton subscriber. Call `start()` once at server boot,
|
|
44
|
+
* `stop()` at shutdown.
|
|
45
|
+
*/
|
|
46
|
+
export declare class WikiChatSubscriberService {
|
|
47
|
+
private readonly logger;
|
|
48
|
+
private readonly chatService;
|
|
49
|
+
private readonly projectVaultPath;
|
|
50
|
+
private readonly ingestService;
|
|
51
|
+
private boundHandler;
|
|
52
|
+
private started;
|
|
53
|
+
constructor(opts: WikiChatSubscriberOptions);
|
|
54
|
+
/**
|
|
55
|
+
* Subscribe to `chat_message`. Idempotent — calling start() twice
|
|
56
|
+
* leaves a single listener.
|
|
57
|
+
*/
|
|
58
|
+
start(): void;
|
|
59
|
+
/** Detach. Safe to call when not started. */
|
|
60
|
+
stop(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Handle a single chat message. Public for tests.
|
|
63
|
+
*/
|
|
64
|
+
handle(dto: MinimalChatMessageDTO): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Decide whether a chat-v2 message should drive a wiki write.
|
|
67
|
+
* Public for tests; logic is conservative — only ingest user-authored
|
|
68
|
+
* text messages, skip agents/system, mentions-only pings, and slash
|
|
69
|
+
* commands.
|
|
70
|
+
*/
|
|
71
|
+
isIngestable(dto: MinimalChatMessageDTO): boolean;
|
|
72
|
+
}
|
|
73
|
+
export {};
|
|
74
|
+
//# sourceMappingURL=wiki-chat-subscriber.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-chat-subscriber.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-chat-subscriber.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAsB,MAAM,0BAA0B,CAAC;AAEjF;;;;GAIG;AACH,UAAU,qBAAqB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC,oEAAoE;IACpE,WAAW,EAAE,aAAa,CAAC;IAC3B,2FAA2F;IAC3F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED;;;GAGG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgB;IAC5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,YAAY,CAAuD;IAC3E,OAAO,CAAC,OAAO,CAAS;gBAEZ,IAAI,EAAE,yBAAyB;IAO3C;;;OAGG;IACH,KAAK,IAAI,IAAI;IAgBb,6CAA6C;IAC7C,IAAI,IAAI,IAAI;IAQZ;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmDvD;;;;;OAKG;IACH,YAAY,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO;CAYlD"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WikiChatSubscriberService — listens on chat-v2's `chat_message` event
|
|
3
|
+
* and fires `WikiIngestService.ingest` for every user-authored message.
|
|
4
|
+
*
|
|
5
|
+
* Phase A (rules-only routing):
|
|
6
|
+
* senderType === 'user' → ingest into the Crewly project vault.
|
|
7
|
+
* senderType === 'agent' | 'system' → skip.
|
|
8
|
+
*
|
|
9
|
+
* Phase B (per spec §4.5) will replace the project-only routing with an
|
|
10
|
+
* LLM-driven gate that picks team / project / global per source.
|
|
11
|
+
*
|
|
12
|
+
* Failure mode is FIRE-AND-FORGET: a malformed message, missing schema,
|
|
13
|
+
* or filesystem error MUST NOT block the live chat flow. Errors are
|
|
14
|
+
* logged at warn-level and swallowed.
|
|
15
|
+
*
|
|
16
|
+
* @module services/wiki/wiki-chat-subscriber.service
|
|
17
|
+
*/
|
|
18
|
+
import * as path from 'path';
|
|
19
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
20
|
+
import { WikiIngestService, detectMessageShape } from './wiki-ingest.service.js';
|
|
21
|
+
/**
|
|
22
|
+
* Process-singleton subscriber. Call `start()` once at server boot,
|
|
23
|
+
* `stop()` at shutdown.
|
|
24
|
+
*/
|
|
25
|
+
export class WikiChatSubscriberService {
|
|
26
|
+
logger;
|
|
27
|
+
chatService;
|
|
28
|
+
projectVaultPath;
|
|
29
|
+
ingestService;
|
|
30
|
+
boundHandler = null;
|
|
31
|
+
started = false;
|
|
32
|
+
constructor(opts) {
|
|
33
|
+
this.logger = LoggerService.getInstance().createComponentLogger('WikiChatSubscriber');
|
|
34
|
+
this.chatService = opts.chatService;
|
|
35
|
+
this.projectVaultPath = opts.projectVaultPath ?? resolveDefaultProjectVaultPath();
|
|
36
|
+
this.ingestService = opts.ingestService ?? WikiIngestService.getInstance();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Subscribe to `chat_message`. Idempotent — calling start() twice
|
|
40
|
+
* leaves a single listener.
|
|
41
|
+
*/
|
|
42
|
+
start() {
|
|
43
|
+
if (this.started) {
|
|
44
|
+
this.logger.debug('start() called twice — ignoring');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this.boundHandler = (dto) => {
|
|
48
|
+
// Fire-and-forget; any thrown error is logged + swallowed in handle().
|
|
49
|
+
void this.handle(dto);
|
|
50
|
+
};
|
|
51
|
+
this.chatService.on('chat_message', this.boundHandler);
|
|
52
|
+
this.started = true;
|
|
53
|
+
this.logger.info('WikiChatSubscriber started', {
|
|
54
|
+
vaultPath: this.projectVaultPath,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/** Detach. Safe to call when not started. */
|
|
58
|
+
stop() {
|
|
59
|
+
if (!this.started || !this.boundHandler)
|
|
60
|
+
return;
|
|
61
|
+
this.chatService.off('chat_message', this.boundHandler);
|
|
62
|
+
this.boundHandler = null;
|
|
63
|
+
this.started = false;
|
|
64
|
+
this.logger.info('WikiChatSubscriber stopped');
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Handle a single chat message. Public for tests.
|
|
68
|
+
*/
|
|
69
|
+
async handle(dto) {
|
|
70
|
+
try {
|
|
71
|
+
if (!this.isIngestable(dto)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const ingestInput = {
|
|
75
|
+
vaultPath: this.projectVaultPath,
|
|
76
|
+
sourceType: 'user_chat',
|
|
77
|
+
sourceRef: `chat:${dto.channelId}:${dto.id}`,
|
|
78
|
+
sourceBody: dto.content,
|
|
79
|
+
callerSession: `user/${dto.senderId}`,
|
|
80
|
+
};
|
|
81
|
+
// Phase A rules-based promotion: decision-shaped chats land in
|
|
82
|
+
// BOTH log.md (audit) and llm-curated/decisions/<date>-<slug>.md
|
|
83
|
+
// (canonical). Phase B will replace `detectMessageShape` with an
|
|
84
|
+
// LLM gate per v2.1 §4.
|
|
85
|
+
const shape = detectMessageShape(dto.content);
|
|
86
|
+
if (shape === 'decision') {
|
|
87
|
+
const result = await this.ingestService.ingestDecision(ingestInput);
|
|
88
|
+
if (!result.log.ok) {
|
|
89
|
+
this.logger.warn('WikiChatSubscriber decision-log ingest refused', {
|
|
90
|
+
reason: result.log.reason,
|
|
91
|
+
messageId: dto.id,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (!result.decision.ok) {
|
|
95
|
+
this.logger.warn('WikiChatSubscriber decisions/ promotion refused', {
|
|
96
|
+
reason: result.decision.reason,
|
|
97
|
+
messageId: dto.id,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const outcome = await this.ingestService.ingest(ingestInput);
|
|
103
|
+
if (!outcome.ok) {
|
|
104
|
+
this.logger.warn('WikiChatSubscriber ingest refused', {
|
|
105
|
+
reason: outcome.reason,
|
|
106
|
+
messageId: dto.id,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
// Swallow — chat flow must not block on wiki write failures.
|
|
112
|
+
this.logger.warn('WikiChatSubscriber.handle threw (swallowed)', {
|
|
113
|
+
messageId: dto.id,
|
|
114
|
+
error: err.message,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Decide whether a chat-v2 message should drive a wiki write.
|
|
120
|
+
* Public for tests; logic is conservative — only ingest user-authored
|
|
121
|
+
* text messages, skip agents/system, mentions-only pings, and slash
|
|
122
|
+
* commands.
|
|
123
|
+
*/
|
|
124
|
+
isIngestable(dto) {
|
|
125
|
+
if (dto.senderType !== 'user')
|
|
126
|
+
return false;
|
|
127
|
+
if (!dto.content || dto.content.trim().length === 0)
|
|
128
|
+
return false;
|
|
129
|
+
// Skip slash commands — they're orc-controls, not knowledge.
|
|
130
|
+
if (dto.content.trimStart().startsWith('/'))
|
|
131
|
+
return false;
|
|
132
|
+
// chat-v2 defaults `contentType` to 'markdown' when sendMessage doesn't
|
|
133
|
+
// supply one (chat-v2.service.ts ~line 1240). Accept the two readable
|
|
134
|
+
// text-bearing types; reject binary/system flavors like 'system_note'.
|
|
135
|
+
const acceptable = new Set(['text', 'markdown']);
|
|
136
|
+
if (dto.contentType && !acceptable.has(dto.contentType))
|
|
137
|
+
return false;
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Resolve a sensible default vault path:
|
|
143
|
+
* 1. `CREWLY_PROJECT_VAULT_PATH` env var (explicit override)
|
|
144
|
+
* 2. `<cwd>/.crewly/wiki` if it exists
|
|
145
|
+
* 3. The Crewly repo's own project vault (the only one with SCHEMA.md today)
|
|
146
|
+
*/
|
|
147
|
+
function resolveDefaultProjectVaultPath() {
|
|
148
|
+
const fromEnv = process.env['CREWLY_PROJECT_VAULT_PATH'];
|
|
149
|
+
if (fromEnv && path.isAbsolute(fromEnv)) {
|
|
150
|
+
return fromEnv;
|
|
151
|
+
}
|
|
152
|
+
return path.join('/Users/yellowsunhy/Desktop/projects/crewly-projects/crewly', '.crewly/wiki');
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=wiki-chat-subscriber.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-chat-subscriber.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-chat-subscriber.service.ts"],"names":[],"mappings":"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"}
|