claude-brain 0.30.2 → 0.30.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +241 -191
- package/VERSION +1 -1
- package/assets/CLAUDE-unified.md +11 -11
- package/assets/CLAUDE.md +29 -29
- package/package.json +7 -3
- package/packs/backend/node.json +173 -173
- package/packs/core/javascript.json +176 -176
- package/packs/core/typescript.json +222 -222
- package/packs/frontend/react.json +254 -254
- package/packs/meta/testing.json +172 -172
- package/scripts/postinstall.mjs +531 -531
- package/src/automation/decision-detector.ts +452 -452
- package/src/automation/phase12-manager.ts +456 -456
- package/src/automation/proactive-recall.ts +373 -373
- package/src/automation/project-detector.ts +310 -310
- package/src/automation/repo-scanner.ts +210 -205
- package/src/cli/auto-setup.ts +75 -75
- package/src/cli/auto-start.ts +266 -266
- package/src/cli/bin.ts +264 -264
- package/src/cli/commands/autostart.ts +90 -90
- package/src/cli/commands/chroma.ts +578 -577
- package/src/cli/commands/export-training.ts +70 -70
- package/src/cli/commands/export.ts +130 -130
- package/src/cli/commands/git-hook.ts +183 -183
- package/src/cli/commands/hooks.ts +217 -217
- package/src/cli/commands/init.ts +123 -123
- package/src/cli/commands/install-mcp.ts +122 -111
- package/src/cli/commands/models.ts +979 -979
- package/src/cli/commands/pack.ts +200 -200
- package/src/cli/commands/refresh.ts +344 -339
- package/src/cli/commands/reindex.ts +120 -120
- package/src/cli/commands/serve.ts +466 -463
- package/src/cli/commands/start.ts +44 -44
- package/src/cli/commands/status.ts +220 -203
- package/src/cli/commands/uninstall-mcp.ts +45 -41
- package/src/cli/commands/update.ts +130 -124
- package/src/cli/migrate-chroma.ts +106 -106
- package/src/cli/ui/animations.ts +80 -80
- package/src/cli/ui/components.ts +82 -82
- package/src/cli/ui/index.ts +4 -4
- package/src/cli/ui/logo.ts +36 -36
- package/src/cli/ui/theme.ts +55 -55
- package/src/code-intelligence/indexer.ts +352 -352
- package/src/code-intelligence/linker.ts +178 -178
- package/src/code-intelligence/parser.ts +484 -484
- package/src/code-intelligence/query.ts +291 -291
- package/src/code-intelligence/schema.ts +83 -83
- package/src/code-intelligence/types.ts +95 -95
- package/src/config/defaults.ts +52 -52
- package/src/config/home.ts +56 -56
- package/src/config/index.ts +5 -5
- package/src/config/loader.ts +192 -192
- package/src/config/schema.ts +446 -415
- package/src/config/validator.ts +182 -182
- package/src/context/assembler.ts +407 -400
- package/src/context/index.ts +79 -79
- package/src/context/progress-tracker.ts +174 -174
- package/src/context/standards-manager.ts +287 -287
- package/src/context/validator.ts +58 -58
- package/src/diagnostics/index.ts +122 -121
- package/src/health/index.ts +233 -232
- package/src/hooks/brain-hook.ts +134 -131
- package/src/hooks/capture.ts +168 -168
- package/src/hooks/claude-code-mastery.md +112 -112
- package/src/hooks/context-hook.ts +260 -245
- package/src/hooks/deduplicator.ts +72 -72
- package/src/hooks/git-capture.ts +109 -109
- package/src/hooks/git-hook-installer.ts +211 -207
- package/src/hooks/index.ts +20 -20
- package/src/hooks/installer.ts +306 -288
- package/src/hooks/interceptor-hook.ts +204 -201
- package/src/hooks/passive-classifier.ts +397 -397
- package/src/hooks/queue.ts +160 -129
- package/src/hooks/session-tracker.ts +312 -312
- package/src/hooks/types.ts +52 -52
- package/src/index.ts +7 -7
- package/src/intelligence/cross-project/generalizer.ts +283 -283
- package/src/intelligence/cross-project/index.ts +7 -7
- package/src/intelligence/hf-downloader.ts +222 -222
- package/src/intelligence/hf-manifest.json +78 -78
- package/src/intelligence/index.ts +24 -24
- package/src/intelligence/inference-router.ts +762 -762
- package/src/intelligence/model-manager.ts +263 -245
- package/src/intelligence/optimization/index.ts +10 -10
- package/src/intelligence/optimization/precompute.ts +202 -202
- package/src/intelligence/optimization/semantic-cache.ts +213 -207
- package/src/intelligence/prediction/index.ts +7 -7
- package/src/intelligence/prediction/recommender.ts +276 -268
- package/src/intelligence/reasoning/chain-retrieval.ts +243 -247
- package/src/intelligence/reasoning/index.ts +7 -7
- package/src/intelligence/temporal/evolution.ts +193 -197
- package/src/intelligence/temporal/index.ts +16 -16
- package/src/intelligence/temporal/query-processor.ts +190 -190
- package/src/intelligence/temporal/timeline.ts +272 -259
- package/src/intelligence/temporal/trends.ts +263 -263
- package/src/intelligence/tokenizer.ts +118 -118
- package/src/knowledge/entity-extractor.ts +447 -443
- package/src/knowledge/graph/builder.ts +185 -185
- package/src/knowledge/graph/linker.ts +201 -201
- package/src/knowledge/graph/memory-graph.ts +359 -359
- package/src/knowledge/graph/schema.ts +99 -99
- package/src/knowledge/graph/search.ts +166 -166
- package/src/knowledge/relationship-extractor.ts +108 -108
- package/src/memory/chroma/client.ts +211 -192
- package/src/memory/chroma/collection-manager.ts +92 -92
- package/src/memory/chroma/config.ts +57 -57
- package/src/memory/chroma/embeddings.ts +177 -175
- package/src/memory/chroma/index.ts +82 -82
- package/src/memory/chroma/migration.ts +270 -270
- package/src/memory/chroma/schemas.ts +69 -69
- package/src/memory/chroma/search.ts +319 -315
- package/src/memory/chroma/store.ts +755 -747
- package/src/memory/compression.ts +121 -121
- package/src/memory/consolidation/archiver.ts +162 -165
- package/src/memory/consolidation/merger.ts +182 -186
- package/src/memory/consolidation/scorer.ts +136 -136
- package/src/memory/database.ts +9 -0
- package/src/memory/dual-write.ts +145 -0
- package/src/memory/embeddings.ts +226 -226
- package/src/memory/episodic/detector.ts +108 -108
- package/src/memory/episodic/manager.ts +347 -351
- package/src/memory/episodic/summarizer.ts +179 -179
- package/src/memory/episodic/types.ts +52 -52
- package/src/memory/fts5-search.ts +692 -633
- package/src/memory/index.ts +943 -1060
- package/src/memory/migrations/add-fts5.ts +118 -108
- package/src/memory/patterns.ts +438 -438
- package/src/memory/pruning.ts +60 -60
- package/src/memory/schema.ts +88 -88
- package/src/memory/store.ts +911 -787
- package/src/orchestrator/handlers/decision-handler.ts +204 -204
- package/src/packs/index.ts +9 -9
- package/src/packs/loader.ts +134 -134
- package/src/packs/manager.ts +204 -204
- package/src/packs/ranker.ts +78 -78
- package/src/packs/types.ts +81 -81
- package/src/phase12/index.ts +5 -5
- package/src/retrieval/bm25/index.ts +300 -297
- package/src/retrieval/bm25/tokenizer.ts +184 -184
- package/src/retrieval/feedback/adaptive.ts +221 -221
- package/src/retrieval/feedback/index.ts +16 -16
- package/src/retrieval/feedback/metrics.ts +221 -221
- package/src/retrieval/feedback/store.ts +283 -283
- package/src/retrieval/fusion/index.ts +194 -194
- package/src/retrieval/fusion/rrf.ts +165 -165
- package/src/retrieval/index.ts +12 -12
- package/src/retrieval/pipeline.ts +375 -375
- package/src/retrieval/query/expander.ts +203 -203
- package/src/retrieval/query/index.ts +27 -27
- package/src/retrieval/query/intent-classifier.ts +252 -252
- package/src/retrieval/query/temporal-parser.ts +295 -295
- package/src/retrieval/reranker/index.ts +189 -188
- package/src/retrieval/reranker/model.ts +99 -95
- package/src/retrieval/service.ts +125 -125
- package/src/retrieval/types.ts +162 -162
- package/src/routing/entity-extractor.ts +454 -454
- package/src/routing/handlers/exploration-handler.ts +369 -0
- package/src/routing/handlers/index.ts +19 -0
- package/src/routing/handlers/memory-handler.ts +273 -0
- package/src/routing/handlers/mutation-handler.ts +241 -0
- package/src/routing/handlers/recall-handler.ts +642 -0
- package/src/routing/handlers/shared.ts +515 -0
- package/src/routing/handlers/types.ts +48 -0
- package/src/routing/intent-classifier.ts +552 -552
- package/src/routing/response-filter.ts +399 -391
- package/src/routing/router.ts +245 -2193
- package/src/routing/search-engine.ts +521 -514
- package/src/routing/types.ts +104 -94
- package/src/scripts/health-check.ts +118 -118
- package/src/scripts/setup.ts +122 -122
- package/src/server/auto-updater.ts +283 -276
- package/src/server/handlers/call-tool.ts +159 -159
- package/src/server/handlers/list-tools.ts +35 -35
- package/src/server/handlers/tools/auto-remember.ts +165 -165
- package/src/server/handlers/tools/brain.ts +86 -86
- package/src/server/handlers/tools/create-project.ts +135 -135
- package/src/server/handlers/tools/get-code-standards.ts +123 -123
- package/src/server/handlers/tools/get-corrections.ts +152 -152
- package/src/server/handlers/tools/get-patterns.ts +156 -156
- package/src/server/handlers/tools/get-project-context.ts +75 -75
- package/src/server/handlers/tools/index.ts +30 -30
- package/src/server/handlers/tools/init-project.ts +756 -756
- package/src/server/handlers/tools/list-projects.ts +126 -126
- package/src/server/handlers/tools/recall-similar.ts +87 -87
- package/src/server/handlers/tools/recognize-pattern.ts +132 -132
- package/src/server/handlers/tools/record-correction.ts +131 -131
- package/src/server/handlers/tools/remember-decision.ts +168 -168
- package/src/server/handlers/tools/schemas.ts +179 -179
- package/src/server/handlers/tools/search-code.ts +122 -122
- package/src/server/handlers/tools/smart-context.ts +146 -146
- package/src/server/handlers/tools/update-progress.ts +131 -131
- package/src/server/http-api.ts +215 -1229
- package/src/server/mcp-proxy.ts +85 -84
- package/src/server/mcp-server.ts +285 -284
- package/src/server/middleware/auth.ts +39 -0
- package/src/server/middleware/error-handler.ts +37 -0
- package/src/server/middleware/rate-limit.ts +53 -0
- package/src/server/middleware/validate.ts +42 -0
- package/src/server/pid-manager.ts +137 -136
- package/src/server/providers/resources.ts +581 -581
- package/src/server/routes/code.ts +228 -0
- package/src/server/routes/context.ts +26 -0
- package/src/server/routes/health.ts +19 -0
- package/src/server/routes/helpers.ts +100 -0
- package/src/server/routes/hooks.ts +197 -0
- package/src/server/routes/mcp.ts +47 -0
- package/src/server/routes/memory.ts +397 -0
- package/src/server/routes/models.ts +96 -0
- package/src/server/routes/projects.ts +89 -0
- package/src/server/routes/types.ts +21 -0
- package/src/server/schemas/api-schemas.ts +202 -0
- package/src/server/services.ts +720 -720
- package/src/server/utils/memory-indicator.ts +84 -84
- package/src/server/utils/response-formatter.ts +129 -129
- package/src/server/web-viewer.ts +1145 -1115
- package/src/setup/index.ts +38 -38
- package/src/tools/registry.ts +115 -115
- package/src/tools/schemas.ts +666 -666
- package/src/tools/types.ts +412 -412
- package/src/training/data-store.ts +320 -298
- package/src/training/retrain-pipeline.ts +399 -394
- package/src/utils/error-handler.ts +136 -136
- package/src/utils/index.ts +58 -58
- package/src/utils/kill-port.ts +55 -53
- package/src/utils/phase12-helper.ts +56 -56
- package/src/utils/safe-path.ts +43 -0
- package/src/utils/timing.ts +47 -47
- package/src/utils/transaction.ts +63 -63
- package/src/vault/index.ts +4 -3
- package/src/vault/paths.ts +106 -106
- package/src/vault/query.ts +4 -1
- package/src/vault/reader.ts +44 -1
- package/src/vault/watcher.ts +24 -1
- package/src/vault/writer.ts +487 -413
- package/skills/persistent-memory/SKILL.md +0 -148
- package/skills/persistent-memory/references/tool-reference.md +0 -90
package/src/hooks/queue.ts
CHANGED
|
@@ -1,129 +1,160 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase 17: File Queue
|
|
3
|
-
* JSONL-based offline fallback when HTTP API server is unreachable.
|
|
4
|
-
* Queue file: ~/.claude-brain/data/hook-queue.jsonl
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { appendFileSync, readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs'
|
|
8
|
-
import { dirname, join, resolve } from 'node:path'
|
|
9
|
-
import { homedir } from 'node:os'
|
|
10
|
-
import type { CapturedKnowledge } from './types'
|
|
11
|
-
|
|
12
|
-
/** Inline home path resolution — avoids @/config/home dependency for <200ms hook context */
|
|
13
|
-
function getHookDataDir(): string {
|
|
14
|
-
const envHome = process.env.CLAUDE_BRAIN_HOME
|
|
15
|
-
const root = envHome ? resolve(envHome) : join(homedir(), '.claude-brain')
|
|
16
|
-
return join(root, 'data')
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** Get the queue file path */
|
|
20
|
-
export function getQueuePath(): string {
|
|
21
|
-
return join(getHookDataDir(), 'hook-queue.jsonl')
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Append captured knowledge to the offline queue.
|
|
26
|
-
* Creates the file and parent directory if needed.
|
|
27
|
-
*/
|
|
28
|
-
export function appendToQueue(items: CapturedKnowledge[]): void {
|
|
29
|
-
if (items.length === 0) return
|
|
30
|
-
|
|
31
|
-
const queuePath = getQueuePath()
|
|
32
|
-
const dir = dirname(queuePath)
|
|
33
|
-
|
|
34
|
-
if (!existsSync(dir)) {
|
|
35
|
-
mkdirSync(dir, { recursive: true })
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const lines = items.map(item => JSON.stringify(item)).join('\n') + '\n'
|
|
39
|
-
appendFileSync(queuePath, lines, 'utf-8')
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Read all items from the queue file.
|
|
44
|
-
* Returns empty array if file doesn't exist.
|
|
45
|
-
*/
|
|
46
|
-
export function readQueue(): CapturedKnowledge[] {
|
|
47
|
-
const queuePath = getQueuePath()
|
|
48
|
-
|
|
49
|
-
if (!existsSync(queuePath)) return []
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
const content = readFileSync(queuePath, 'utf-8').trim()
|
|
53
|
-
if (!content) return []
|
|
54
|
-
|
|
55
|
-
return content
|
|
56
|
-
.split('\n')
|
|
57
|
-
.filter(line => line.trim())
|
|
58
|
-
.map(line => {
|
|
59
|
-
try {
|
|
60
|
-
return JSON.parse(line) as CapturedKnowledge
|
|
61
|
-
} catch {
|
|
62
|
-
return null
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
.filter((item): item is CapturedKnowledge => item !== null)
|
|
66
|
-
} catch {
|
|
67
|
-
return []
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Clear the queue file after successful processing.
|
|
73
|
-
*/
|
|
74
|
-
export function clearQueue(): void {
|
|
75
|
-
const queuePath = getQueuePath()
|
|
76
|
-
if (existsSync(queuePath)) {
|
|
77
|
-
writeFileSync(queuePath, '', 'utf-8')
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Drain the queue by POSTing items to the ingest endpoint in batches.
|
|
83
|
-
* Called on server startup.
|
|
84
|
-
*
|
|
85
|
-
* @param port The HTTP API port
|
|
86
|
-
* @param batchSize Number of items per POST
|
|
87
|
-
* @returns Number of items drained
|
|
88
|
-
*/
|
|
89
|
-
export async function drainQueue(port: number = 3000, batchSize: number = 10): Promise<number> {
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Phase 17: File Queue
|
|
3
|
+
* JSONL-based offline fallback when HTTP API server is unreachable.
|
|
4
|
+
* Queue file: ~/.claude-brain/data/hook-queue.jsonl
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { appendFileSync, readFileSync, writeFileSync, existsSync, mkdirSync, renameSync, unlinkSync } from 'node:fs'
|
|
8
|
+
import { dirname, join, resolve } from 'node:path'
|
|
9
|
+
import { homedir } from 'node:os'
|
|
10
|
+
import type { CapturedKnowledge } from './types'
|
|
11
|
+
|
|
12
|
+
/** Inline home path resolution — avoids @/config/home dependency for <200ms hook context */
|
|
13
|
+
function getHookDataDir(): string {
|
|
14
|
+
const envHome = process.env.CLAUDE_BRAIN_HOME
|
|
15
|
+
const root = envHome ? resolve(envHome) : join(homedir(), '.claude-brain')
|
|
16
|
+
return join(root, 'data')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Get the queue file path */
|
|
20
|
+
export function getQueuePath(): string {
|
|
21
|
+
return join(getHookDataDir(), 'hook-queue.jsonl')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Append captured knowledge to the offline queue.
|
|
26
|
+
* Creates the file and parent directory if needed.
|
|
27
|
+
*/
|
|
28
|
+
export function appendToQueue(items: CapturedKnowledge[]): void {
|
|
29
|
+
if (items.length === 0) return
|
|
30
|
+
|
|
31
|
+
const queuePath = getQueuePath()
|
|
32
|
+
const dir = dirname(queuePath)
|
|
33
|
+
|
|
34
|
+
if (!existsSync(dir)) {
|
|
35
|
+
mkdirSync(dir, { recursive: true })
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const lines = items.map(item => JSON.stringify(item)).join('\n') + '\n'
|
|
39
|
+
appendFileSync(queuePath, lines, 'utf-8')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Read all items from the queue file.
|
|
44
|
+
* Returns empty array if file doesn't exist.
|
|
45
|
+
*/
|
|
46
|
+
export function readQueue(): CapturedKnowledge[] {
|
|
47
|
+
const queuePath = getQueuePath()
|
|
48
|
+
|
|
49
|
+
if (!existsSync(queuePath)) return []
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const content = readFileSync(queuePath, 'utf-8').trim()
|
|
53
|
+
if (!content) return []
|
|
54
|
+
|
|
55
|
+
return content
|
|
56
|
+
.split('\n')
|
|
57
|
+
.filter(line => line.trim())
|
|
58
|
+
.map(line => {
|
|
59
|
+
try {
|
|
60
|
+
return JSON.parse(line) as CapturedKnowledge
|
|
61
|
+
} catch {
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
.filter((item): item is CapturedKnowledge => item !== null)
|
|
66
|
+
} catch {
|
|
67
|
+
return []
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Clear the queue file after successful processing.
|
|
73
|
+
*/
|
|
74
|
+
export function clearQueue(): void {
|
|
75
|
+
const queuePath = getQueuePath()
|
|
76
|
+
if (existsSync(queuePath)) {
|
|
77
|
+
writeFileSync(queuePath, '', 'utf-8')
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Drain the queue by POSTing items to the ingest endpoint in batches.
|
|
83
|
+
* Called on server startup.
|
|
84
|
+
*
|
|
85
|
+
* @param port The HTTP API port
|
|
86
|
+
* @param batchSize Number of items per POST
|
|
87
|
+
* @returns Number of items drained
|
|
88
|
+
*/
|
|
89
|
+
export async function drainQueue(port: number = 3000, batchSize: number = 10): Promise<number> {
|
|
90
|
+
const queuePath = getQueuePath()
|
|
91
|
+
const processingPath = queuePath + '.processing'
|
|
92
|
+
|
|
93
|
+
// Atomically move queue to processing file (prevents concurrent drains)
|
|
94
|
+
try {
|
|
95
|
+
renameSync(queuePath, processingPath)
|
|
96
|
+
} catch {
|
|
97
|
+
return 0 // No queue file or already being processed
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Read from the processing file
|
|
101
|
+
let items: CapturedKnowledge[]
|
|
102
|
+
try {
|
|
103
|
+
const content = readFileSync(processingPath, 'utf-8').trim()
|
|
104
|
+
if (!content) {
|
|
105
|
+
unlinkSync(processingPath)
|
|
106
|
+
return 0
|
|
107
|
+
}
|
|
108
|
+
items = content
|
|
109
|
+
.split('\n')
|
|
110
|
+
.filter(line => line.trim())
|
|
111
|
+
.map(line => { try { return JSON.parse(line) } catch { return null } })
|
|
112
|
+
.filter((item): item is CapturedKnowledge => item !== null)
|
|
113
|
+
} catch {
|
|
114
|
+
return 0
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (items.length === 0) {
|
|
118
|
+
try { unlinkSync(processingPath) } catch {}
|
|
119
|
+
return 0
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let drained = 0
|
|
123
|
+
const url = `http://localhost:${port}/api/hooks/ingest`
|
|
124
|
+
|
|
125
|
+
for (let i = 0; i < items.length; i += batchSize) {
|
|
126
|
+
const batch = items.slice(i, i + batchSize)
|
|
127
|
+
try {
|
|
128
|
+
const res = await fetch(url, {
|
|
129
|
+
method: 'POST',
|
|
130
|
+
headers: { 'Content-Type': 'application/json' },
|
|
131
|
+
body: JSON.stringify({ knowledge: batch }),
|
|
132
|
+
signal: AbortSignal.timeout(5000),
|
|
133
|
+
})
|
|
134
|
+
if (res.ok) {
|
|
135
|
+
drained += batch.length
|
|
136
|
+
} else {
|
|
137
|
+
break
|
|
138
|
+
}
|
|
139
|
+
} catch {
|
|
140
|
+
break
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (drained === items.length) {
|
|
145
|
+
// All processed — remove processing file
|
|
146
|
+
try { unlinkSync(processingPath) } catch {}
|
|
147
|
+
} else if (drained > 0) {
|
|
148
|
+
// Partially drained — write remaining items back to queue
|
|
149
|
+
const remaining = items.slice(drained)
|
|
150
|
+
const lines = remaining.map(item => JSON.stringify(item)).join('\n') + '\n'
|
|
151
|
+
// Append to queue (new items may have been added during processing)
|
|
152
|
+
appendFileSync(queuePath, lines, 'utf-8')
|
|
153
|
+
try { unlinkSync(processingPath) } catch {}
|
|
154
|
+
} else {
|
|
155
|
+
// Nothing drained — move processing file back to queue
|
|
156
|
+
try { renameSync(processingPath, queuePath) } catch {}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return drained
|
|
160
|
+
}
|