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,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WikiCleanupService — detect + remove low-quality pages from a wiki vault.
|
|
3
|
+
*
|
|
4
|
+
* Origin: the 2026-05-27 migration dumped every agent's `memory.json`
|
|
5
|
+
* roleKnowledge entries as their own wiki page (~3,277 pages across 6
|
|
6
|
+
* project vaults). Many are stream-of-consciousness daily memory rather
|
|
7
|
+
* than team-level patterns. Symptom: each project vault has 500+ pages
|
|
8
|
+
* under `patterns/`, most low-quality (confidence < 0.5, verbatim memory
|
|
9
|
+
* dump shape). Karpathy's wiki spec says "frequently-read distilled
|
|
10
|
+
* knowledge" — 500 stream-of-consciousness pages violates that.
|
|
11
|
+
*
|
|
12
|
+
* Detection is **rule-based + mechanical** (OSS does this). The actual
|
|
13
|
+
* keep/delete decision can be deferred to an agent via the bridge —
|
|
14
|
+
* this service exposes both `scan(rules)` (mechanical candidate list)
|
|
15
|
+
* and `apply(pages)` (executes the explicit page list provided).
|
|
16
|
+
*
|
|
17
|
+
* Design rules (mirror WikiMigrateService):
|
|
18
|
+
* - Default DRY-RUN. Caller must pass `{ apply: true }` to delete.
|
|
19
|
+
* - Idempotent + reversible. Every deleted page body + frontmatter is
|
|
20
|
+
* archived to `<vault>/.wiki-cleanup-archive.json` BEFORE the file
|
|
21
|
+
* is removed. Re-running with the same input is a no-op.
|
|
22
|
+
* - Migrate manifest is updated so the SAME source entry is not
|
|
23
|
+
* re-imported by the next `wiki-migrate --apply` (would defeat the
|
|
24
|
+
* cleanup).
|
|
25
|
+
* - LEGACY FILES (`memory.json`, `.crewly/knowledge/*`) are NEVER
|
|
26
|
+
* touched. The cleanup ONLY removes pages from the wiki vault.
|
|
27
|
+
* - Frozen folders (`memory/`, `sop/`, `sop-overrides/`, `okr/`,
|
|
28
|
+
* `decisions/manual/`) are never scanned.
|
|
29
|
+
*
|
|
30
|
+
* @module services/wiki/wiki-cleanup.service
|
|
31
|
+
*/
|
|
32
|
+
export declare const WIKI_CLEANUP_ARCHIVE_FILENAME = ".wiki-cleanup-archive.json";
|
|
33
|
+
export declare const WIKI_CLEANUP_ARCHIVE_VERSION = 1;
|
|
34
|
+
export interface WikiCleanupRules {
|
|
35
|
+
/** Drop pages whose frontmatter `confidence` is below this. Default 0.5. */
|
|
36
|
+
minConfidence?: number;
|
|
37
|
+
/** Drop pages whose `migrated_from` starts with `agent/`. Default true. */
|
|
38
|
+
dropAgentMemoryDumps?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Keep at most N pages per `original_author`. Pages outside the top-N
|
|
41
|
+
* (sorted by confidence desc, then original_date desc) are flagged.
|
|
42
|
+
* Default: 0 (cap disabled).
|
|
43
|
+
*/
|
|
44
|
+
maxPerAgent?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface WikiCleanupCandidate {
|
|
47
|
+
/** Path relative to the vault root (e.g. `llm-curated/patterns/x.md`). */
|
|
48
|
+
relPath: string;
|
|
49
|
+
/** Why this page is a cleanup candidate (one or more rule names). */
|
|
50
|
+
reasons: string[];
|
|
51
|
+
/** Parsed `confidence` (if present in frontmatter), used for ranking. */
|
|
52
|
+
confidence: number | null;
|
|
53
|
+
/** Parsed `original_author` (if present), used by the per-agent cap. */
|
|
54
|
+
originalAuthor: string | null;
|
|
55
|
+
/** Parsed `migrated_from` (if present), used to invalidate manifest entry. */
|
|
56
|
+
migratedFrom: string | null;
|
|
57
|
+
/** Parsed `original_id` (if present), used to invalidate manifest entry. */
|
|
58
|
+
originalId: string | null;
|
|
59
|
+
/** File size in bytes. */
|
|
60
|
+
bytes: number;
|
|
61
|
+
}
|
|
62
|
+
export interface WikiCleanupScanInput {
|
|
63
|
+
/** Absolute vault path (the dir containing `SCHEMA.md`). */
|
|
64
|
+
vaultPath: string;
|
|
65
|
+
/** Rule overrides; defaults applied for any missing key. */
|
|
66
|
+
rules?: WikiCleanupRules;
|
|
67
|
+
}
|
|
68
|
+
export interface WikiCleanupScanResult {
|
|
69
|
+
ok: true;
|
|
70
|
+
vaultPath: string;
|
|
71
|
+
/** Pages flagged by at least one rule. Capped at {@link SCAN_HARD_CAP}. */
|
|
72
|
+
candidates: WikiCleanupCandidate[];
|
|
73
|
+
/** Total pages walked (whether candidate or not). */
|
|
74
|
+
scannedCount: number;
|
|
75
|
+
/** Did the scan hit {@link SCAN_HARD_CAP}? */
|
|
76
|
+
truncated: boolean;
|
|
77
|
+
/** Per-reason counts for quick eyeballing. */
|
|
78
|
+
summary: {
|
|
79
|
+
lowConfidence: number;
|
|
80
|
+
agentMemoryDump: number;
|
|
81
|
+
perAgentCapped: number;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export interface WikiCleanupApplyInput {
|
|
85
|
+
vaultPath: string;
|
|
86
|
+
/**
|
|
87
|
+
* Explicit list of relative paths to delete. The bridge / agent passes
|
|
88
|
+
* this in after deciding which scan candidates to actually act on. We
|
|
89
|
+
* deliberately do NOT take a rule set here — `apply` is the mechanical
|
|
90
|
+
* deletion step, the decision happened upstream.
|
|
91
|
+
*/
|
|
92
|
+
pages: string[];
|
|
93
|
+
}
|
|
94
|
+
export interface WikiCleanupApplyResult {
|
|
95
|
+
ok: true;
|
|
96
|
+
vaultPath: string;
|
|
97
|
+
/** Pages actually deleted in this run. */
|
|
98
|
+
deleted: string[];
|
|
99
|
+
/** Pages requested but not deleted (missing on disk, already archived, etc). */
|
|
100
|
+
skipped: Array<{
|
|
101
|
+
relPath: string;
|
|
102
|
+
reason: 'not_found' | 'outside_vault' | 'frozen';
|
|
103
|
+
}>;
|
|
104
|
+
archivePath: string;
|
|
105
|
+
/** Migrate manifest entries removed so cleanup-deleted pages don't get re-migrated. */
|
|
106
|
+
manifestEntriesInvalidated: number;
|
|
107
|
+
}
|
|
108
|
+
export type WikiCleanupOutcome = WikiCleanupScanResult | WikiCleanupApplyResult | {
|
|
109
|
+
ok: false;
|
|
110
|
+
reason: 'invalid_input' | 'vault_missing';
|
|
111
|
+
message: string;
|
|
112
|
+
};
|
|
113
|
+
export declare class WikiCleanupService {
|
|
114
|
+
private static instance;
|
|
115
|
+
private readonly logger;
|
|
116
|
+
constructor();
|
|
117
|
+
static getInstance(): WikiCleanupService;
|
|
118
|
+
/** Test-only reset. */
|
|
119
|
+
static resetInstance(): void;
|
|
120
|
+
/**
|
|
121
|
+
* Walk the vault's `llm-curated/` tree, parse frontmatter, return all
|
|
122
|
+
* pages matching at least one cleanup rule. Pure read — no writes.
|
|
123
|
+
*/
|
|
124
|
+
scan(input: WikiCleanupScanInput): Promise<WikiCleanupOutcome>;
|
|
125
|
+
/**
|
|
126
|
+
* Delete the listed pages from the vault, archive each one (body +
|
|
127
|
+
* frontmatter) to `.wiki-cleanup-archive.json`, and invalidate the
|
|
128
|
+
* corresponding entry in the migrate manifest so the same source can't
|
|
129
|
+
* resurrect the page on the next `wiki-migrate --apply`.
|
|
130
|
+
*/
|
|
131
|
+
apply(input: WikiCleanupApplyInput): Promise<WikiCleanupOutcome>;
|
|
132
|
+
private validateVault;
|
|
133
|
+
/**
|
|
134
|
+
* Best-effort safe-rel normalisation. Returns null if the path would
|
|
135
|
+
* resolve outside the vault (`..` traversal etc).
|
|
136
|
+
*/
|
|
137
|
+
private normalizeRelPath;
|
|
138
|
+
/**
|
|
139
|
+
* Walk the vault tree, parsing frontmatter on each `.md` file. Skips
|
|
140
|
+
* frozen folders + non-md files. Returns true if the scan was truncated
|
|
141
|
+
* by the hard cap.
|
|
142
|
+
*/
|
|
143
|
+
private walkPages;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parse `confidence` from frontmatter into a number, or null if absent /
|
|
147
|
+
* unparseable. Accepts both numeric (`0.3`) and string (`"0.3"`) shapes
|
|
148
|
+
* because YAML quoting is inconsistent across older migrated pages.
|
|
149
|
+
*/
|
|
150
|
+
export declare function parseConfidence(raw: unknown): number | null;
|
|
151
|
+
/**
|
|
152
|
+
* Minimal YAML frontmatter parser. Handles the shapes our migrate service
|
|
153
|
+
* emits — `key: value` lines, with optional quotes around values. NOT a
|
|
154
|
+
* general YAML parser. Returns `{}` when no frontmatter is present.
|
|
155
|
+
*/
|
|
156
|
+
export declare function parseFrontmatter(raw: string): {
|
|
157
|
+
frontmatter: Record<string, unknown>;
|
|
158
|
+
body: string;
|
|
159
|
+
};
|
|
160
|
+
//# sourceMappingURL=wiki-cleanup.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-cleanup.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-cleanup.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WikiCleanupService — detect + remove low-quality pages from a wiki vault.
|
|
3
|
+
*
|
|
4
|
+
* Origin: the 2026-05-27 migration dumped every agent's `memory.json`
|
|
5
|
+
* roleKnowledge entries as their own wiki page (~3,277 pages across 6
|
|
6
|
+
* project vaults). Many are stream-of-consciousness daily memory rather
|
|
7
|
+
* than team-level patterns. Symptom: each project vault has 500+ pages
|
|
8
|
+
* under `patterns/`, most low-quality (confidence < 0.5, verbatim memory
|
|
9
|
+
* dump shape). Karpathy's wiki spec says "frequently-read distilled
|
|
10
|
+
* knowledge" — 500 stream-of-consciousness pages violates that.
|
|
11
|
+
*
|
|
12
|
+
* Detection is **rule-based + mechanical** (OSS does this). The actual
|
|
13
|
+
* keep/delete decision can be deferred to an agent via the bridge —
|
|
14
|
+
* this service exposes both `scan(rules)` (mechanical candidate list)
|
|
15
|
+
* and `apply(pages)` (executes the explicit page list provided).
|
|
16
|
+
*
|
|
17
|
+
* Design rules (mirror WikiMigrateService):
|
|
18
|
+
* - Default DRY-RUN. Caller must pass `{ apply: true }` to delete.
|
|
19
|
+
* - Idempotent + reversible. Every deleted page body + frontmatter is
|
|
20
|
+
* archived to `<vault>/.wiki-cleanup-archive.json` BEFORE the file
|
|
21
|
+
* is removed. Re-running with the same input is a no-op.
|
|
22
|
+
* - Migrate manifest is updated so the SAME source entry is not
|
|
23
|
+
* re-imported by the next `wiki-migrate --apply` (would defeat the
|
|
24
|
+
* cleanup).
|
|
25
|
+
* - LEGACY FILES (`memory.json`, `.crewly/knowledge/*`) are NEVER
|
|
26
|
+
* touched. The cleanup ONLY removes pages from the wiki vault.
|
|
27
|
+
* - Frozen folders (`memory/`, `sop/`, `sop-overrides/`, `okr/`,
|
|
28
|
+
* `decisions/manual/`) are never scanned.
|
|
29
|
+
*
|
|
30
|
+
* @module services/wiki/wiki-cleanup.service
|
|
31
|
+
*/
|
|
32
|
+
import * as fs from 'fs/promises';
|
|
33
|
+
import * as path from 'path';
|
|
34
|
+
import { existsSync } from 'fs';
|
|
35
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
36
|
+
import { atomicWriteJson, safeReadJson, ensureDir } from '../../utils/file-io.utils.js';
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Constants
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
export const WIKI_CLEANUP_ARCHIVE_FILENAME = '.wiki-cleanup-archive.json';
|
|
41
|
+
export const WIKI_CLEANUP_ARCHIVE_VERSION = 1;
|
|
42
|
+
/** Folders we never scan — managed by OSS code path, not LLM-editable. */
|
|
43
|
+
const FROZEN_FOLDERS = new Set([
|
|
44
|
+
'memory',
|
|
45
|
+
'sop',
|
|
46
|
+
'sop-overrides',
|
|
47
|
+
'okr',
|
|
48
|
+
]);
|
|
49
|
+
/** Folder under the vault where llm-curated pages live. */
|
|
50
|
+
const LLM_CURATED_DIR = 'llm-curated';
|
|
51
|
+
/** Hard cap on candidates returned per scan — defensive (prevents OOM on a
|
|
52
|
+
* corrupted vault with 100k+ files). */
|
|
53
|
+
const SCAN_HARD_CAP = 5_000;
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Service
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
export class WikiCleanupService {
|
|
58
|
+
static instance = null;
|
|
59
|
+
logger;
|
|
60
|
+
constructor() {
|
|
61
|
+
this.logger = LoggerService.getInstance().createComponentLogger('WikiCleanup');
|
|
62
|
+
}
|
|
63
|
+
static getInstance() {
|
|
64
|
+
if (!this.instance)
|
|
65
|
+
this.instance = new WikiCleanupService();
|
|
66
|
+
return this.instance;
|
|
67
|
+
}
|
|
68
|
+
/** Test-only reset. */
|
|
69
|
+
static resetInstance() {
|
|
70
|
+
this.instance = null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Walk the vault's `llm-curated/` tree, parse frontmatter, return all
|
|
74
|
+
* pages matching at least one cleanup rule. Pure read — no writes.
|
|
75
|
+
*/
|
|
76
|
+
async scan(input) {
|
|
77
|
+
const validation = this.validateVault(input.vaultPath);
|
|
78
|
+
if (!validation.ok)
|
|
79
|
+
return validation;
|
|
80
|
+
const rules = {
|
|
81
|
+
minConfidence: input.rules?.minConfidence ?? 0.5,
|
|
82
|
+
dropAgentMemoryDumps: input.rules?.dropAgentMemoryDumps ?? true,
|
|
83
|
+
maxPerAgent: input.rules?.maxPerAgent ?? 0,
|
|
84
|
+
};
|
|
85
|
+
const llmCuratedRoot = path.join(input.vaultPath, LLM_CURATED_DIR);
|
|
86
|
+
const allPages = [];
|
|
87
|
+
let truncated = false;
|
|
88
|
+
if (existsSync(llmCuratedRoot)) {
|
|
89
|
+
truncated = await this.walkPages(llmCuratedRoot, input.vaultPath, allPages, SCAN_HARD_CAP);
|
|
90
|
+
}
|
|
91
|
+
const flagged = new Map();
|
|
92
|
+
const summary = { lowConfidence: 0, agentMemoryDump: 0, perAgentCapped: 0 };
|
|
93
|
+
for (const page of allPages) {
|
|
94
|
+
const fm = page.frontmatter;
|
|
95
|
+
const reasons = [];
|
|
96
|
+
const conf = parseConfidence(fm['confidence']);
|
|
97
|
+
if (conf !== null && conf < rules.minConfidence) {
|
|
98
|
+
reasons.push(`confidence ${conf} < ${rules.minConfidence}`);
|
|
99
|
+
summary.lowConfidence++;
|
|
100
|
+
}
|
|
101
|
+
const migratedFrom = typeof fm['migrated_from'] === 'string' ? fm['migrated_from'] : null;
|
|
102
|
+
if (rules.dropAgentMemoryDumps && migratedFrom?.startsWith('agent/') && migratedFrom.endsWith('/memory.json')) {
|
|
103
|
+
reasons.push('migrated from agent memory.json');
|
|
104
|
+
summary.agentMemoryDump++;
|
|
105
|
+
}
|
|
106
|
+
if (reasons.length > 0) {
|
|
107
|
+
flagged.set(page.relPath, {
|
|
108
|
+
reasons,
|
|
109
|
+
meta: {
|
|
110
|
+
confidence: conf,
|
|
111
|
+
originalAuthor: typeof fm['original_author'] === 'string' ? fm['original_author'] : null,
|
|
112
|
+
originalDate: typeof fm['original_date'] === 'string' ? fm['original_date'] : null,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Second pass — per-agent cap. Only considers pages NOT already flagged
|
|
118
|
+
// by other rules (so a low-confidence page doesn't take a "cap slot").
|
|
119
|
+
if (rules.maxPerAgent > 0) {
|
|
120
|
+
const byAuthor = new Map();
|
|
121
|
+
for (const page of allPages) {
|
|
122
|
+
if (flagged.has(page.relPath))
|
|
123
|
+
continue;
|
|
124
|
+
const fm = page.frontmatter;
|
|
125
|
+
const author = typeof fm['original_author'] === 'string' ? fm['original_author'] : null;
|
|
126
|
+
if (!author)
|
|
127
|
+
continue;
|
|
128
|
+
const conf = parseConfidence(fm['confidence']) ?? 0;
|
|
129
|
+
const date = typeof fm['original_date'] === 'string' ? fm['original_date'] : '';
|
|
130
|
+
const arr = byAuthor.get(author) ?? [];
|
|
131
|
+
arr.push({ relPath: page.relPath, confidence: conf, date });
|
|
132
|
+
byAuthor.set(author, arr);
|
|
133
|
+
}
|
|
134
|
+
for (const [author, arr] of byAuthor) {
|
|
135
|
+
if (arr.length <= rules.maxPerAgent)
|
|
136
|
+
continue;
|
|
137
|
+
// Keep top-N by confidence desc, then date desc.
|
|
138
|
+
arr.sort((a, b) => (b.confidence - a.confidence) || b.date.localeCompare(a.date));
|
|
139
|
+
for (const overflow of arr.slice(rules.maxPerAgent)) {
|
|
140
|
+
const existing = flagged.get(overflow.relPath);
|
|
141
|
+
if (existing) {
|
|
142
|
+
existing.reasons.push(`per-agent cap (${author}: keep ${rules.maxPerAgent})`);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
flagged.set(overflow.relPath, {
|
|
146
|
+
reasons: [`per-agent cap (${author}: keep ${rules.maxPerAgent})`],
|
|
147
|
+
meta: { confidence: overflow.confidence, originalAuthor: author, originalDate: overflow.date },
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
summary.perAgentCapped++;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const candidates = [];
|
|
155
|
+
for (const page of allPages) {
|
|
156
|
+
const flag = flagged.get(page.relPath);
|
|
157
|
+
if (!flag)
|
|
158
|
+
continue;
|
|
159
|
+
const fm = page.frontmatter;
|
|
160
|
+
candidates.push({
|
|
161
|
+
relPath: page.relPath,
|
|
162
|
+
reasons: flag.reasons,
|
|
163
|
+
confidence: flag.meta.confidence,
|
|
164
|
+
originalAuthor: flag.meta.originalAuthor,
|
|
165
|
+
migratedFrom: typeof fm['migrated_from'] === 'string' ? fm['migrated_from'] : null,
|
|
166
|
+
originalId: typeof fm['original_id'] === 'string' ? fm['original_id'] : null,
|
|
167
|
+
bytes: page.bytes,
|
|
168
|
+
});
|
|
169
|
+
if (candidates.length >= SCAN_HARD_CAP) {
|
|
170
|
+
truncated = true;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
this.logger.info('Wiki cleanup scan complete', {
|
|
175
|
+
vaultPath: input.vaultPath,
|
|
176
|
+
scannedCount: allPages.length,
|
|
177
|
+
candidateCount: candidates.length,
|
|
178
|
+
truncated,
|
|
179
|
+
summary,
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
ok: true,
|
|
183
|
+
vaultPath: input.vaultPath,
|
|
184
|
+
candidates,
|
|
185
|
+
scannedCount: allPages.length,
|
|
186
|
+
truncated,
|
|
187
|
+
summary,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Delete the listed pages from the vault, archive each one (body +
|
|
192
|
+
* frontmatter) to `.wiki-cleanup-archive.json`, and invalidate the
|
|
193
|
+
* corresponding entry in the migrate manifest so the same source can't
|
|
194
|
+
* resurrect the page on the next `wiki-migrate --apply`.
|
|
195
|
+
*/
|
|
196
|
+
async apply(input) {
|
|
197
|
+
const validation = this.validateVault(input.vaultPath);
|
|
198
|
+
if (!validation.ok)
|
|
199
|
+
return validation;
|
|
200
|
+
if (!Array.isArray(input.pages) || input.pages.length === 0) {
|
|
201
|
+
return { ok: false, reason: 'invalid_input', message: 'pages must be a non-empty array' };
|
|
202
|
+
}
|
|
203
|
+
const archivePath = path.join(input.vaultPath, WIKI_CLEANUP_ARCHIVE_FILENAME);
|
|
204
|
+
const archive = await safeReadJson(archivePath, { version: WIKI_CLEANUP_ARCHIVE_VERSION, entries: [] }, this.logger);
|
|
205
|
+
if (archive.version !== WIKI_CLEANUP_ARCHIVE_VERSION) {
|
|
206
|
+
// Migrate-style: don't trust an unknown version, just start fresh.
|
|
207
|
+
archive.version = WIKI_CLEANUP_ARCHIVE_VERSION;
|
|
208
|
+
archive.entries = [];
|
|
209
|
+
}
|
|
210
|
+
const deleted = [];
|
|
211
|
+
const skipped = [];
|
|
212
|
+
for (const relPath of input.pages) {
|
|
213
|
+
const safe = this.normalizeRelPath(relPath);
|
|
214
|
+
if (!safe) {
|
|
215
|
+
skipped.push({ relPath, reason: 'outside_vault' });
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
// Defence: even if the caller passes a frozen-folder path, refuse.
|
|
219
|
+
// The top-level segment is the folder name (`memory/secret.md` →
|
|
220
|
+
// `memory`); pages directly under the vault root are never frozen.
|
|
221
|
+
const segments = safe.split('/');
|
|
222
|
+
if (segments.length >= 2 && FROZEN_FOLDERS.has(segments[0])) {
|
|
223
|
+
skipped.push({ relPath, reason: 'frozen' });
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
const abs = path.join(input.vaultPath, safe);
|
|
227
|
+
if (!existsSync(abs)) {
|
|
228
|
+
skipped.push({ relPath, reason: 'not_found' });
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
// Read + parse before delete so we can archive shape.
|
|
232
|
+
const raw = await fs.readFile(abs, 'utf8');
|
|
233
|
+
const { frontmatter, body } = parseFrontmatter(raw);
|
|
234
|
+
archive.entries.push({
|
|
235
|
+
relPath: safe,
|
|
236
|
+
archivedAt: new Date().toISOString(),
|
|
237
|
+
reasons: ['apply-list'],
|
|
238
|
+
body,
|
|
239
|
+
frontmatter,
|
|
240
|
+
});
|
|
241
|
+
await fs.unlink(abs);
|
|
242
|
+
deleted.push(safe);
|
|
243
|
+
}
|
|
244
|
+
// Persist archive — the rollback source of truth.
|
|
245
|
+
//
|
|
246
|
+
// **Manifest is deliberately NOT modified** (2026-05-28 fix). Earlier
|
|
247
|
+
// versions removed the matching entries from `.migration-state.json`
|
|
248
|
+
// on the theory "now nothing pins the page in place." That was
|
|
249
|
+
// exactly backwards: the migrate manifest is what makes
|
|
250
|
+
// `wiki-migrate --apply` IDEMPOTENT. With the entry present + hash
|
|
251
|
+
// match, migrate sees "already migrated" → skips. With the entry
|
|
252
|
+
// removed, migrate sees "new content" → re-imports → the
|
|
253
|
+
// just-deleted page reappears on the next bridge tick. Symptom seen
|
|
254
|
+
// 2026-05-28 ~05:30: 20 pages deleted, then 20 re-imported by the
|
|
255
|
+
// next migrate tick, candidate count never dropped. The page on
|
|
256
|
+
// disk is gone; that is sufficient. Manifest stays intact.
|
|
257
|
+
await ensureDir(input.vaultPath);
|
|
258
|
+
await atomicWriteJson(archivePath, archive);
|
|
259
|
+
this.logger.info('Wiki cleanup apply complete', {
|
|
260
|
+
vaultPath: input.vaultPath,
|
|
261
|
+
requested: input.pages.length,
|
|
262
|
+
deleted: deleted.length,
|
|
263
|
+
skipped: skipped.length,
|
|
264
|
+
archivePath,
|
|
265
|
+
});
|
|
266
|
+
return {
|
|
267
|
+
ok: true,
|
|
268
|
+
vaultPath: input.vaultPath,
|
|
269
|
+
deleted,
|
|
270
|
+
skipped,
|
|
271
|
+
archivePath,
|
|
272
|
+
manifestEntriesInvalidated: 0,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
// -------------------------------------------------------------------------
|
|
276
|
+
// Internals
|
|
277
|
+
// -------------------------------------------------------------------------
|
|
278
|
+
validateVault(vaultPath) {
|
|
279
|
+
if (!vaultPath || !path.isAbsolute(vaultPath)) {
|
|
280
|
+
return { ok: false, reason: 'invalid_input', message: 'vaultPath must be an absolute path' };
|
|
281
|
+
}
|
|
282
|
+
if (!existsSync(vaultPath)) {
|
|
283
|
+
return { ok: false, reason: 'vault_missing', message: `vault not found: ${vaultPath}` };
|
|
284
|
+
}
|
|
285
|
+
return { ok: true };
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Best-effort safe-rel normalisation. Returns null if the path would
|
|
289
|
+
* resolve outside the vault (`..` traversal etc).
|
|
290
|
+
*/
|
|
291
|
+
normalizeRelPath(rel) {
|
|
292
|
+
const normalised = path.posix.normalize(rel.replace(/\\/g, '/'));
|
|
293
|
+
if (normalised.startsWith('..') || path.isAbsolute(normalised))
|
|
294
|
+
return null;
|
|
295
|
+
return normalised;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Walk the vault tree, parsing frontmatter on each `.md` file. Skips
|
|
299
|
+
* frozen folders + non-md files. Returns true if the scan was truncated
|
|
300
|
+
* by the hard cap.
|
|
301
|
+
*/
|
|
302
|
+
async walkPages(dir, vaultPath, accumulator, cap) {
|
|
303
|
+
let entries;
|
|
304
|
+
try {
|
|
305
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
for (const entry of entries) {
|
|
311
|
+
if (accumulator.length >= cap)
|
|
312
|
+
return true;
|
|
313
|
+
// Skip frozen folders only at the vault-root level (`llm-curated/`
|
|
314
|
+
// sits next to them, so we never recurse INTO sibling frozen dirs
|
|
315
|
+
// — but defence-in-depth this check covers anyone who calls
|
|
316
|
+
// `walkPages` with the vault root directly).
|
|
317
|
+
if (entry.isDirectory()) {
|
|
318
|
+
const relParent = path.relative(vaultPath, path.join(dir, entry.name));
|
|
319
|
+
const topLevel = relParent.split(path.sep)[0];
|
|
320
|
+
if (FROZEN_FOLDERS.has(topLevel))
|
|
321
|
+
continue;
|
|
322
|
+
const truncated = await this.walkPages(path.join(dir, entry.name), vaultPath, accumulator, cap);
|
|
323
|
+
if (truncated)
|
|
324
|
+
return true;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (!entry.isFile() || !entry.name.endsWith('.md'))
|
|
328
|
+
continue;
|
|
329
|
+
const abs = path.join(dir, entry.name);
|
|
330
|
+
try {
|
|
331
|
+
const stat = await fs.stat(abs);
|
|
332
|
+
const raw = await fs.readFile(abs, 'utf8');
|
|
333
|
+
const { frontmatter } = parseFrontmatter(raw);
|
|
334
|
+
accumulator.push({
|
|
335
|
+
relPath: path.relative(vaultPath, abs).split(path.sep).join('/'),
|
|
336
|
+
frontmatter,
|
|
337
|
+
bytes: stat.size,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
this.logger.debug('walkPages: skipping unreadable file', {
|
|
342
|
+
path: abs,
|
|
343
|
+
error: err instanceof Error ? err.message : String(err),
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// ---------------------------------------------------------------------------
|
|
351
|
+
// Helpers (module-private, exported for tests)
|
|
352
|
+
// ---------------------------------------------------------------------------
|
|
353
|
+
/**
|
|
354
|
+
* Parse `confidence` from frontmatter into a number, or null if absent /
|
|
355
|
+
* unparseable. Accepts both numeric (`0.3`) and string (`"0.3"`) shapes
|
|
356
|
+
* because YAML quoting is inconsistent across older migrated pages.
|
|
357
|
+
*/
|
|
358
|
+
export function parseConfidence(raw) {
|
|
359
|
+
if (typeof raw === 'number' && Number.isFinite(raw))
|
|
360
|
+
return raw;
|
|
361
|
+
if (typeof raw === 'string') {
|
|
362
|
+
const parsed = parseFloat(raw);
|
|
363
|
+
if (Number.isFinite(parsed))
|
|
364
|
+
return parsed;
|
|
365
|
+
}
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Minimal YAML frontmatter parser. Handles the shapes our migrate service
|
|
370
|
+
* emits — `key: value` lines, with optional quotes around values. NOT a
|
|
371
|
+
* general YAML parser. Returns `{}` when no frontmatter is present.
|
|
372
|
+
*/
|
|
373
|
+
export function parseFrontmatter(raw) {
|
|
374
|
+
const match = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
375
|
+
if (!match)
|
|
376
|
+
return { frontmatter: {}, body: raw };
|
|
377
|
+
const fm = {};
|
|
378
|
+
for (const line of match[1].split('\n')) {
|
|
379
|
+
const lineMatch = line.match(/^([A-Za-z_][A-Za-z0-9_]*):\s*(.*)$/);
|
|
380
|
+
if (!lineMatch)
|
|
381
|
+
continue;
|
|
382
|
+
let value = lineMatch[2].trim();
|
|
383
|
+
// Strip wrapping quotes.
|
|
384
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
385
|
+
value = value.slice(1, -1);
|
|
386
|
+
}
|
|
387
|
+
// Coerce a few common scalar shapes.
|
|
388
|
+
if (value === 'true')
|
|
389
|
+
fm[lineMatch[1]] = true;
|
|
390
|
+
else if (value === 'false')
|
|
391
|
+
fm[lineMatch[1]] = false;
|
|
392
|
+
else if (/^-?\d+(\.\d+)?$/.test(value))
|
|
393
|
+
fm[lineMatch[1]] = parseFloat(value);
|
|
394
|
+
else
|
|
395
|
+
fm[lineMatch[1]] = value;
|
|
396
|
+
}
|
|
397
|
+
return { frontmatter: fm, body: match[2] };
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=wiki-cleanup.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-cleanup.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/wiki/wiki-cleanup.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAwB,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAExF,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,CAAC,MAAM,6BAA6B,GAAG,4BAA4B,CAAC;AAC1E,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC;AAE9C,0EAA0E;AAC1E,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IAClD,QAAQ;IACR,KAAK;IACL,eAAe;IACf,KAAK;CACN,CAAC,CAAC;AAEH,2DAA2D;AAC3D,MAAM,eAAe,GAAG,aAAa,CAAC;AAEtC;yCACyC;AACzC,MAAM,aAAa,GAAG,KAAK,CAAC;AAqG5B,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,OAAO,kBAAkB;IACrB,MAAM,CAAC,QAAQ,GAA8B,IAAI,CAAC;IACzC,MAAM,CAAkB;IAEzC;QACE,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,kBAAkB,EAAE,CAAC;QAC7D,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,uBAAuB;IACvB,MAAM,CAAC,aAAa;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,CAAC,KAA2B;QACpC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,UAAU,CAAC,EAAE;YAAE,OAAO,UAAU,CAAC;QAEtC,MAAM,KAAK,GAA+B;YACxC,aAAa,EAAE,KAAK,CAAC,KAAK,EAAE,aAAa,IAAI,GAAG;YAChD,oBAAoB,EAAE,KAAK,CAAC,KAAK,EAAE,oBAAoB,IAAI,IAAI;YAC/D,WAAW,EAAE,KAAK,CAAC,KAAK,EAAE,WAAW,IAAI,CAAC;SAC3C,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAoF,EAAE,CAAC;QACrG,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QAC7F,CAAC;QAKD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAgB,CAAC;QACxC,MAAM,OAAO,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QAE5E,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;YAC5B,MAAM,OAAO,GAAa,EAAE,CAAC;YAE7B,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YAC/C,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,cAAc,IAAI,MAAM,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC;gBAC5D,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1B,CAAC;YAED,MAAM,YAAY,GAAG,OAAO,EAAE,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1F,IAAI,KAAK,CAAC,oBAAoB,IAAI,YAAY,EAAE,UAAU,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC9G,OAAO,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;gBAChD,OAAO,CAAC,eAAe,EAAE,CAAC;YAC5B,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE;oBACxB,OAAO;oBACP,IAAI,EAAE;wBACJ,UAAU,EAAE,IAAI;wBAChB,cAAc,EAAE,OAAO,EAAE,CAAC,iBAAiB,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI;wBACxF,YAAY,EAAE,OAAO,EAAE,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI;qBACnF;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,uEAAuE;QACvE,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwE,CAAC;YACjG,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC5B,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;oBAAE,SAAS;gBACxC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;gBAC5B,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,iBAAiB,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACxF,IAAI,CAAC,MAAM;oBAAE,SAAS;gBACtB,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC;gBACpD,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChF,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACvC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC5D,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC5B,CAAC;YACD,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACrC,IAAI,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,WAAW;oBAAE,SAAS;gBAC9C,iDAAiD;gBACjD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;gBAClF,KAAK,MAAM,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;oBACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;oBAC/C,IAAI,QAAQ,EAAE,CAAC;wBACb,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,MAAM,UAAU,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;oBAChF,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE;4BAC5B,OAAO,EAAE,CAAC,kBAAkB,MAAM,UAAU,KAAK,CAAC,WAAW,GAAG,CAAC;4BACjE,IAAI,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE;yBAC/F,CAAC,CAAC;oBACL,CAAC;oBACD,OAAO,CAAC,cAAc,EAAE,CAAC;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAA2B,EAAE,CAAC;QAC9C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;YAC5B,UAAU,CAAC,IAAI,CAAC;gBACd,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU;gBAChC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc;gBACxC,YAAY,EAAE,OAAO,EAAE,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI;gBAClF,UAAU,EAAE,OAAO,EAAE,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI;gBAC5E,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC,CAAC;YACH,IAAI,UAAU,CAAC,MAAM,IAAI,aAAa,EAAE,CAAC;gBACvC,SAAS,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE;YAC7C,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,YAAY,EAAE,QAAQ,CAAC,MAAM;YAC7B,cAAc,EAAE,UAAU,CAAC,MAAM;YACjC,SAAS;YACT,OAAO;SACR,CAAC,CAAC;QAEH,OAAO;YACL,EAAE,EAAE,IAAI;YACR,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,UAAU;YACV,YAAY,EAAE,QAAQ,CAAC,MAAM;YAC7B,SAAS;YACT,OAAO;SACR,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,KAA4B;QACtC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,UAAU,CAAC,EAAE;YAAE,OAAO,UAAU,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;QAC5F,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,6BAA6B,CAAC,CAAC;QAC9E,MAAM,OAAO,GAAG,MAAM,YAAY,CAChC,WAAW,EACX,EAAE,OAAO,EAAE,4BAA4B,EAAE,OAAO,EAAE,EAAE,EAAE,EACtD,IAAI,CAAC,MAAM,CACZ,CAAC;QACF,IAAI,OAAO,CAAC,OAAO,KAAK,4BAA4B,EAAE,CAAC;YACrD,mEAAmE;YACnE,OAAO,CAAC,OAAO,GAAG,4BAA4B,CAAC;YAC/C,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;QACvB,CAAC;QAED,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAsC,EAAE,CAAC;QAEtD,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;gBACnD,SAAS;YACX,CAAC;YACD,mEAAmE;YACnE,iEAAiE;YACjE,mEAAmE;YACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC5C,SAAS;YACX,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC7C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC/C,SAAS;YACX,CAAC;YAED,sDAAsD;YACtD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC3C,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACpD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,IAAI;gBACb,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,OAAO,EAAE,CAAC,YAAY,CAAC;gBACvB,IAAI;gBACJ,WAAW;aACZ,CAAC,CAAC;YAEH,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAED,kDAAkD;QAClD,EAAE;QACF,sEAAsE;QACtE,qEAAqE;QACrE,+DAA+D;QAC/D,wDAAwD;QACxD,mEAAmE;QACnE,iEAAiE;QACjE,yDAAyD;QACzD,oEAAoE;QACpE,kEAAkE;QAClE,gEAAgE;QAChE,2DAA2D;QAC3D,MAAM,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,eAAe,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;YAC9C,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;YAC7B,OAAO,EAAE,OAAO,CAAC,MAAM;YACvB,OAAO,EAAE,OAAO,CAAC,MAAM;YACvB,WAAW;SACZ,CAAC,CAAC;QAEH,OAAO;YACL,EAAE,EAAE,IAAI;YACR,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO;YACP,OAAO;YACP,WAAW;YACX,0BAA0B,EAAE,CAAC;SAC9B,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,YAAY;IACZ,4EAA4E;IAEpE,aAAa,CAAC,SAAiB;QACrC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,oCAAoC,EAAE,CAAC;QAC/F,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,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED;;;OAGG;IACK,gBAAgB,CAAC,GAAW;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QACjE,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5E,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,SAAS,CACrB,GAAW,EACX,SAAiB,EACjB,WAA4F,EAC5F,GAAW;QAEX,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,KAAK,CAAC;QACf,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,WAAW,CAAC,MAAM,IAAI,GAAG;gBAAE,OAAO,IAAI,CAAC;YAC3C,mEAAmE;YACnE,kEAAkE;YAClE,4DAA4D;YAC5D,6CAA6C;YAC7C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvE,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9C,IAAI,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBAC3C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;gBAChG,IAAI,SAAS;oBAAE,OAAO,IAAI,CAAC;gBAC3B,SAAS;YACX,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAChC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC3C,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;gBAC9C,WAAW,CAAC,IAAI,CAAC;oBACf,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;oBAChE,WAAW;oBACX,KAAK,EAAE,IAAI,CAAC,IAAI;iBACjB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE;oBACvD,IAAI,EAAE,GAAG;oBACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACxD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;;AAIH,8EAA8E;AAC9E,+CAA+C;AAC/C,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAChE,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC9D,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAClD,MAAM,EAAE,GAA4B,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACnE,IAAI,CAAC,SAAS;YAAE,SAAS;QACzB,IAAI,KAAK,GAA8B,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3D,yBAAyB;QACzB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACrG,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QACD,qCAAqC;QACrC,IAAI,KAAK,KAAK,MAAM;YAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;aACzC,IAAI,KAAK,KAAK,OAAO;YAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;aAChD,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;;YACxE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IAChC,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7C,CAAC"}
|