xindex 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ai/research/2026-04-10-file-watching.md +79 -0
- package/.ai/research/2026-04-10-mcp-output-format.md +129 -0
- package/.ai/task/INDEX.md +12 -0
- package/.ai/task/done/INDEX.md +3 -0
- package/.ai/task/done/task.2026-04-09-local-ai-research-protos.log.md +98 -0
- package/.ai/task/done/task.2026-04-09-local-ai-research-protos.md +102 -0
- package/.ai/task/task.2026-04-10-cluster-config.log.md +19 -0
- package/.ai/task/task.2026-04-10-cluster-config.md +118 -0
- package/.ai/task/task.2026-04-10-dir-indexing.log.md +8 -0
- package/.ai/task/task.2026-04-10-dir-indexing.md +92 -0
- package/.ai/task/task.2026-04-10-line-clustering.log.md +50 -0
- package/.ai/task/task.2026-04-10-line-clustering.md +176 -0
- package/.ai/task/task.2026-04-10-object-store.log.md +7 -0
- package/.ai/task/task.2026-04-10-object-store.md +81 -0
- package/.ai/task/task.2026-04-10-search-config.log.md +46 -0
- package/.ai/task/task.2026-04-10-search-config.md +274 -0
- package/.ai/task/task.2026-04-10-watch-indexing.log.md +32 -0
- package/.ai/task/task.2026-04-10-watch-indexing.md +101 -0
- package/.ai/task/task.2026-04-10-xindex-mcp.log.md +5 -0
- package/.ai/task/task.2026-04-10-xindex-mcp.md +92 -0
- package/.ai/task/task.2026-04-10-xindex-mcp.report.md +113 -0
- package/.claude/settings.local.json +73 -0
- package/.claude/skills/make-hof/SKILL.md +8 -0
- package/.claude/skills/make-hof/playbook.md +38 -0
- package/.cursor/mcp.json +8 -0
- package/.mcp.json +8 -0
- package/.xindex.json +22 -0
- package/CLAUDE.md +54 -0
- package/README.md +206 -0
- package/apps/indexApp.ts +31 -0
- package/apps/mcpApp.ts +119 -0
- package/apps/run.index.ts +19 -0
- package/apps/run.mcp.ts +49 -0
- package/apps/run.reset.ts +10 -0
- package/apps/run.search.ts +21 -0
- package/apps/run.watch.ts +44 -0
- package/apps/searchApp.ts +9 -0
- package/apps/watchApp.ts +53 -0
- package/apps/watchFileEventsApp.ts +39 -0
- package/bin/xindex-index +2 -0
- package/bin/xindex-mcp +2 -0
- package/bin/xindex-reset +2 -0
- package/bin/xindex-search +2 -0
- package/bin/xindex-watch +2 -0
- package/componets/IType.ts +1 -0
- package/componets/appId.ts +3 -0
- package/componets/buildComponents.ts +27 -0
- package/componets/config/loadConfig.ts +43 -0
- package/componets/config/xindexConfig.ts +4 -0
- package/componets/index/contentIndexDriver.ts +39 -0
- package/componets/index/formatSearchResults.ts +18 -0
- package/componets/index/getIndexStats.ts +11 -0
- package/componets/index/handleFileEvent.ts +25 -0
- package/componets/index/indexApi.ts +45 -0
- package/componets/index/vectraIndex.ts +11 -0
- package/componets/index/watcherLock.ts +107 -0
- package/componets/keywords/cleanUpKeywords.ts +38 -0
- package/componets/keywords/extractKeywords.ts +14 -0
- package/componets/keywords/refineKeywords.ts +16 -0
- package/componets/llm/embed.ts +18 -0
- package/componets/llm/queryLLM.ts +20 -0
- package/componets/logger.ts +34 -0
- package/componets/walkFiles.ts +51 -0
- package/componets/watchFiles.ts +106 -0
- package/features/indexContent.ts +16 -0
- package/features/removeContent.ts +9 -0
- package/features/resetIndex.ts +9 -0
- package/features/searchIndex.ts +33 -0
- package/package.json +32 -0
- package/packages/fun/src/IType.ts +5 -0
- package/packages/fun/src/array-finder.ts +55 -0
- package/packages/fun/src/array-index.ts +35 -0
- package/packages/fun/src/array.ts +112 -0
- package/packages/fun/src/assert.ts +5 -0
- package/packages/fun/src/asyncRequest.ts +35 -0
- package/packages/fun/src/callsites.ts +18 -0
- package/packages/fun/src/case-never.ts +9 -0
- package/packages/fun/src/casting.ts +41 -0
- package/packages/fun/src/collect.ts +13 -0
- package/packages/fun/src/concurrency.ts +186 -0
- package/packages/fun/src/container.ts +86 -0
- package/packages/fun/src/counter.ts +45 -0
- package/packages/fun/src/create-map.ts +2 -0
- package/packages/fun/src/dedupe.ts +2 -0
- package/packages/fun/src/defer.ts +55 -0
- package/packages/fun/src/delay.ts +5 -0
- package/packages/fun/src/discriminate.ts +34 -0
- package/packages/fun/src/enum-values.ts +12 -0
- package/packages/fun/src/exponential-backoff.ts +20 -0
- package/packages/fun/src/flatten.ts +11 -0
- package/packages/fun/src/hash.ts +67 -0
- package/packages/fun/src/hash128.ts +6 -0
- package/packages/fun/src/hash256.ts +6 -0
- package/packages/fun/src/hub.ts +53 -0
- package/packages/fun/src/id.ts +10 -0
- package/packages/fun/src/interval.ts +76 -0
- package/packages/fun/src/is-non-nullable.ts +2 -0
- package/packages/fun/src/isIterable.ts +3 -0
- package/packages/fun/src/mailbox.ts +13 -0
- package/packages/fun/src/map-record.ts +19 -0
- package/packages/fun/src/match-collections.ts +57 -0
- package/packages/fun/src/match-left-and-right-arrays.ts +78 -0
- package/packages/fun/src/mem.ts +26 -0
- package/packages/fun/src/memos.ts +28 -0
- package/packages/fun/src/normalizeError.ts +25 -0
- package/packages/fun/src/nothing.ts +3 -0
- package/packages/fun/src/pipe.ts +18 -0
- package/packages/fun/src/prettyJson.ts +3 -0
- package/packages/fun/src/project.ts +8 -0
- package/packages/fun/src/promise.ts +27 -0
- package/packages/fun/src/pubsub.ts +128 -0
- package/packages/fun/src/randomId.ts +14 -0
- package/packages/fun/src/regexp-escape.ts +13 -0
- package/packages/fun/src/retry.ts +15 -0
- package/packages/fun/src/serial.test.ts +107 -0
- package/packages/fun/src/serial.ts +17 -0
- package/packages/fun/src/sleep.ts +3 -0
- package/packages/fun/src/sort-object.ts +46 -0
- package/packages/fun/src/speed-test.ts +56 -0
- package/packages/fun/src/tick.ts +37 -0
- package/packages/fun/src/time-behavior.ts +50 -0
- package/packages/fun/src/time.ts +22 -0
- package/packages/fun/src/timedFallback.ts +37 -0
- package/packages/fun/src/timer.ts +30 -0
- package/packages/fun/src/value.ts +33 -0
- package/packages/fun/src/waitForCounter.ts +15 -0
- package/packages/streamx/src/batch.ts +23 -0
- package/packages/streamx/src/batchTimed.ts +113 -0
- package/packages/streamx/src/buffer.ts +72 -0
- package/packages/streamx/src/concatenate.ts +33 -0
- package/packages/streamx/src/filter.ts +14 -0
- package/packages/streamx/src/flat.ts +19 -0
- package/packages/streamx/src/flatMap.ts +9 -0
- package/packages/streamx/src/from.ts +30 -0
- package/packages/streamx/src/index.ts +49 -0
- package/packages/streamx/src/interval.ts +58 -0
- package/packages/streamx/src/loop.ts +8 -0
- package/packages/streamx/src/map.ts +12 -0
- package/packages/streamx/src/merge.ts +89 -0
- package/packages/streamx/src/nodeReadable.ts +6 -0
- package/packages/streamx/src/nodeTransform.ts +9 -0
- package/packages/streamx/src/nodeWritable.ts +38 -0
- package/packages/streamx/src/objectReader.ts +16 -0
- package/packages/streamx/src/polyfill.ts +20 -0
- package/packages/streamx/src/reader.ts +38 -0
- package/packages/streamx/src/reduce.ts +15 -0
- package/packages/streamx/src/scale.ts +93 -0
- package/packages/streamx/src/scaleSync.ts +13 -0
- package/packages/streamx/src/sequence.ts +7 -0
- package/packages/streamx/src/tap.ts +9 -0
- package/packages/streamx/src/toArray.ts +9 -0
- package/packages/streamx/src/writer.ts +96 -0
- package/rnd/hf.ts +14 -0
- package/rnd/keywords-compromise.ts +18 -0
- package/rnd/keywords-pipeline.ts +79 -0
- package/rnd/keywords.ts +38 -0
- package/rnd/test-vectra-memory.ts +63 -0
- package/rnd/vectra-keywords.ts +95 -0
- package/rnd/vectra.ts +50 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(chmod +x:*)",
|
|
5
|
+
"Bash(./bin/xindex.index)",
|
|
6
|
+
"Bash(./bin/xindex.search)",
|
|
7
|
+
"Bash(npx tsx:*)",
|
|
8
|
+
"Bash(./bin/xindex-index)",
|
|
9
|
+
"Bash(./bin/xindex-search)",
|
|
10
|
+
"Bash(./bin/xindex-index:*)",
|
|
11
|
+
"Bash(./bin/xindex-search build components:*)",
|
|
12
|
+
"Bash(node:*)",
|
|
13
|
+
"Bash(./bin/xindex-search embedding model neural network:*)",
|
|
14
|
+
"Bash(./bin/xindex-search natural language processing keywords:*)",
|
|
15
|
+
"Bash(./bin/xindex-search vector database storage:*)",
|
|
16
|
+
"Bash(./bin/xindex-search file indexing pipeline:*)",
|
|
17
|
+
"Bash(./bin/xindex-search \"embedding model neural network\")",
|
|
18
|
+
"Bash(./bin/xindex-search \"natural language processing keywords\")",
|
|
19
|
+
"Bash(./bin/xindex-search \"vector database storage\")",
|
|
20
|
+
"Bash(./bin/xindex-search \"file indexing pipeline\")",
|
|
21
|
+
"Bash(./bin/xindex-search \"search query results\")",
|
|
22
|
+
"Bash(./bin/xindex-search \"embedding model\")",
|
|
23
|
+
"Bash(./bin/xindex-search \"natural language keywords\")",
|
|
24
|
+
"Bash(time ./bin/xindex-search embedding:*)",
|
|
25
|
+
"Bash(time ./bin/xindex-search \"stream batch processing\")",
|
|
26
|
+
"WebSearch",
|
|
27
|
+
"WebFetch(domain:github.com)",
|
|
28
|
+
"WebFetch(domain:www.npmjs.com)",
|
|
29
|
+
"Bash(npm install:*)",
|
|
30
|
+
"Bash(./bin/xindex-search \"embedding\")",
|
|
31
|
+
"mcp__xindex__xindex_search",
|
|
32
|
+
"mcp__xindex__xindex_index",
|
|
33
|
+
"Bash(grep -r \"IIndexRecord\\\\|IIndexStats\\\\|keywords.*join\\\\|metadata\" /Users/slava/project/xindex/componets/index/*.ts)",
|
|
34
|
+
"mcp__xindex__xindex_reset",
|
|
35
|
+
"Bash(xargs cat:*)",
|
|
36
|
+
"Bash(npx tsc:*)",
|
|
37
|
+
"Bash(npx:*)",
|
|
38
|
+
"Bash(node_modules/.bin/tsc --noEmit)",
|
|
39
|
+
"Bash(./node_modules/.bin/tsc --noEmit)",
|
|
40
|
+
"Bash(grep:*)",
|
|
41
|
+
"Bash(./bin/xindex-reset:*)",
|
|
42
|
+
"Bash(bin/xindex-search hey:*)",
|
|
43
|
+
"Bash(bin/xindex-search \"test\")",
|
|
44
|
+
"Bash(bin/xindex-index .:*)",
|
|
45
|
+
"Bash(bin/xindex-search search index:*)",
|
|
46
|
+
"Bash(bin/xindex-search stream:*)",
|
|
47
|
+
"Bash(bin/xindex-search nonexistent_xyz:*)",
|
|
48
|
+
"Bash(timeout 25 bash -c ':*)",
|
|
49
|
+
"Bash(node_modules/.bin/tsx --version)",
|
|
50
|
+
"Bash(node_modules/.bin/tsx --eval \"import './apps/mcpApp.js'\")",
|
|
51
|
+
"Bash(node_modules/.bin/tsx --eval \"import './apps/mcpApp.ts'\")",
|
|
52
|
+
"Bash(node_modules/.bin/tsx --eval \"import './apps/run.mcp.ts'\")",
|
|
53
|
+
"Bash(node_modules/.bin/tsx --eval \"import './apps/mcpApp.ts'; import './apps/watchApp.ts'; import './apps/indexApp.ts'; import './componets/indexFileContent.ts'\")",
|
|
54
|
+
"Bash(node_modules/.bin/tsx --eval \"import './componets/handleFileEvent.ts'; import './componets/indexFileContent.ts'; import './apps/watchApp.ts'; import './apps/indexApp.ts'\")",
|
|
55
|
+
"Bash(find /Users/slava/project/xindex/.xindex/objects -name \"*.json\" -exec grep -l '\"type\":\"meta\"' {} \\\\;)",
|
|
56
|
+
"Bash(find /Users/slava/project/xindex/.xindex/objects -name \"*.json\" -exec grep -l '\"type\":\"cluster\"' {} \\\\;)",
|
|
57
|
+
"Bash(find /Users/slava/project/xindex/.xindex/objects -name \"*.json\" -exec grep -l '\"type\":\"manifest\"' {} \\\\;)",
|
|
58
|
+
"Bash(read f:*)",
|
|
59
|
+
"Bash(python3 -c ':*)",
|
|
60
|
+
"Bash(wc -l /Users/slava/project/xindex/componets/index/*.ts)",
|
|
61
|
+
"Bash(yarn search:*)",
|
|
62
|
+
"Bash(npm run *)",
|
|
63
|
+
"Skill(with-cursor)",
|
|
64
|
+
"Bash(git mv *)",
|
|
65
|
+
"Bash(./bin/xindex-search \"where is MCP server\")",
|
|
66
|
+
"Bash(xindex-search where *)"
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
"enableAllProjectMcpServers": true,
|
|
70
|
+
"enabledMcpjsonServers": [
|
|
71
|
+
"xindex"
|
|
72
|
+
]
|
|
73
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: make-hof
|
|
3
|
+
description: Refactors a function/module to the HOF component pattern, or creates a new HOF from a description. Use when converting plain functions to factory + instance pattern.
|
|
4
|
+
argument-hint: "[file or description]"
|
|
5
|
+
---
|
|
6
|
+
Refactor or create HOF component: $ARGUMENTS
|
|
7
|
+
|
|
8
|
+
Read [playbook.md](playbook.md) for full instructions, then follow them.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## Pattern
|
|
2
|
+
|
|
3
|
+
HOF component = factory function that returns a configured function instance.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
// 1. Type — named I<Name>, describes the returned function signature
|
|
7
|
+
export type IDoThing = (a: string, b: number) => Promise<string>;
|
|
8
|
+
|
|
9
|
+
// 2. Factory — PascalCase, takes config, returns typed function
|
|
10
|
+
export function DoThing(config: Config): IDoThing {
|
|
11
|
+
return async function doThing(a, b) { /* uses config */ }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Caller constructs their own:
|
|
15
|
+
// const doThing = DoThing(myConfig);
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Exports: `IDoThing` (type), `DoThing` (factory). No default instance — callers configure at point of use.
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
1. **Read** the target file (or understand the description if creating new)
|
|
23
|
+
2. **Identify** what becomes config — values that are currently hardcoded, passed at init time, or vary between use cases
|
|
24
|
+
3. **Apply pattern**:
|
|
25
|
+
- Extract `type I<Name>` for the inner function signature
|
|
26
|
+
- Wrap in `function <Name>(config): I<Name>` factory
|
|
27
|
+
- Move hardcoded values to factory params
|
|
28
|
+
- Inner function uses closure over factory params
|
|
29
|
+
4. **Preserve** module-level init (e.g. `await pipeline(...)`) outside the factory — these are singletons
|
|
30
|
+
5. **Refactor callers** — find all imports of the old function, replace with factory import + local construction (`const fn = Factory(config)`)
|
|
31
|
+
|
|
32
|
+
## Rules
|
|
33
|
+
|
|
34
|
+
- Keep module-level side effects (model loading, index creation) outside the factory
|
|
35
|
+
- Factory params should be the minimal set that varies — don't over-parameterize
|
|
36
|
+
- Inner function name = camelCase of factory name
|
|
37
|
+
- If the file has multiple related functions, group under one factory only if they share config
|
|
38
|
+
- Use specific types over `string` when possible (e.g. union types for known values)
|
package/.cursor/mcp.json
ADDED
package/.mcp.json
ADDED
package/.xindex.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ignoreKeywords": [
|
|
3
|
+
"import", "export", "const", "function", "return", "async", "await", "type", "string", "number",
|
|
4
|
+
"from", "default", "let", "var",
|
|
5
|
+
"if", "else", "switch", "case", "break", "continue",
|
|
6
|
+
"for", "of", "in",
|
|
7
|
+
"try", "catch", "finally", "throw",
|
|
8
|
+
"new", "delete", "as", "is", "typeof", "instanceof", "void",
|
|
9
|
+
"this", "super",
|
|
10
|
+
"interface", "class", "extends", "implements",
|
|
11
|
+
"public", "private", "protected", "static", "abstract", "readonly",
|
|
12
|
+
"declare", "namespace", "module", "enum",
|
|
13
|
+
"boolean", "any", "unknown", "never",
|
|
14
|
+
"undefined", "null", "object",
|
|
15
|
+
"record", "array", "readonlyarray", "promise",
|
|
16
|
+
"true", "false",
|
|
17
|
+
"src", "packages", "fun", "componets", "streamx", "apps", "run", "rnd", "tsx",
|
|
18
|
+
"utf8", "length", "map", "slice", "push", "join", "resolve", "stringify",
|
|
19
|
+
"json", "settimeout", "path", "readfile"
|
|
20
|
+
],
|
|
21
|
+
"ignoreFiles": ["rnd/**", ".xindex"]
|
|
22
|
+
}
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
## Shorthand
|
|
4
|
+
|
|
5
|
+
- **NxM** — N parts × M sub-parts, title + 1 sentence each. Include text diagrams when M ≥ 3. E.g., `3x3` = 3 parts × 3 sub-parts
|
|
6
|
+
- **NxMxD** — same as NxM but D sentences per sub-part. E.g., `3x3x2` = 3×3 with 2 sentences each
|
|
7
|
+
- **Nxx** — N parts, title + 1 sentence each (no sub-parts). E.g., `3xx`
|
|
8
|
+
- **unpack** — 3-5 parts × 3-5 sub-parts with text diagrams
|
|
9
|
+
- **Text diagrams** — ASCII flows, hierarchies, tables. Keep minimal.
|
|
10
|
+
- **research/search/ground** — search the Internet using DuckDuckGo MCP
|
|
11
|
+
- **plan dev / go / dev / implement** — start implementation → triggers Pre-implementation check
|
|
12
|
+
- **recover** — find most recent `task.*.md` in `.ai/task/` (by date+mtime, exclude `*.log.md`/`*.report.md`), summarize state and next steps
|
|
13
|
+
- **pull details / expand / flesh out** — enrich task with full detail while preserving shape (see Detail expansion)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Task Management
|
|
17
|
+
|
|
18
|
+
- **Location**: `.ai/task/`. Naming: `task.<yyyy-mm-dd>-<slug>.md` (date = creation date, slug includes roadmap number when applicable)
|
|
19
|
+
- **Structure**: Context (why + links) → Goal → Diagram → Steps (NxM plan). Default: text diagram + 3x3 plan; scale up only if complexity demands it
|
|
20
|
+
- **Diagram ↔ Steps consistency**: must always reflect each other. Update both in the same pass. Inconsistency = bug.
|
|
21
|
+
- **Task kickoff**: user provides notes → create task file + log → notes into Context → draft Goal + structure → ask 3–5 clarifying questions (`[MUST]` = blocker, `[SHOULD]` = design risk) → iterate until MUSTs resolved, SHOULDs answered or defaulted → finalize with diagram + steps
|
|
22
|
+
- **Pre-implementation**: reread task → identify gaps → research (parallel agents for independent questions) → verify diagram ↔ steps → ask user if changes are significant → identify parallel tracks → start
|
|
23
|
+
- **Post-implementation**: recheck task vs actual code. Mark completed steps, note deviations, sync diagram. Drift = bug.
|
|
24
|
+
- **Logs**: `task.<...slug>.log.md` alongside task. Format: `### <date>` + bullets. Log decisions, blockers, outcomes, deviations — sufficient to reconstruct context. Parallel agents get own logs: `task.<...slug>.track-<name>.log.md`; merge outcomes back to main log.
|
|
25
|
+
- **Log splitting**: at ~500+ lines, split into `task.<...slug>.1.log.md`, `*.2.log.md`, etc. Original becomes index. Use bash `sed -n` for extraction.
|
|
26
|
+
- **Reports**: `task.<...slug>.report.md` — consolidates research findings after completion
|
|
27
|
+
- **Section splitting**: large `.md` files → `*.1.*`, `*.2.*` parts. Original becomes index with bullet summaries.
|
|
28
|
+
- **Detail expansion**: reread task → research every step (files, APIs, deps) → expand with concrete details (paths, functions, tables, exact changes) → preserve NxM shape → no info loss → update diagram → keep balanced detail density
|
|
29
|
+
- **Context recovery**: when chat compacts, reread active task's log to recover direction
|
|
30
|
+
- **Completed tasks**: move done tasks (+ their logs, maps, reports) to `.ai/task/done/`. Update `done/INDEX.md` (relative links, newest-first). Root `INDEX.md` lists only active/pending tasks + a link to `done/INDEX.md`.
|
|
31
|
+
|
|
32
|
+
## Code Patterns
|
|
33
|
+
|
|
34
|
+
- **HOF component** — factory function that returns a configured function instance. Export only the factory (`DoThing`) and type (`IDoThing`). Callers construct their own instance — no default export.
|
|
35
|
+
```ts
|
|
36
|
+
export type IDoThing = (a: string, b: number) => Promise<string>;
|
|
37
|
+
export function DoThing(config: Config): IDoThing {
|
|
38
|
+
return async function doThing(a, b) { ... }
|
|
39
|
+
}
|
|
40
|
+
// caller: const doThing = DoThing({dep1, dep2});
|
|
41
|
+
```
|
|
42
|
+
- **HOF dependencies** — when a factory depends on other components, pass them as a destructured object: `DoThing({embed, index}: {embed: IEmbed, index: LocalIndex})`. This makes dependencies explicit and order-independent.
|
|
43
|
+
- **Tagged union** — use `IType<{type: string, ...}>` from `componets/IType.ts` for discriminated unions. Each variant gets a `type` literal, the union is `|`-joined.
|
|
44
|
+
```ts
|
|
45
|
+
export type IFileEvent =
|
|
46
|
+
| IType<{ type: "index", path: string }>
|
|
47
|
+
| IType<{ type: "remove", path: string }>;
|
|
48
|
+
```
|
|
49
|
+
- **Logger** — never use `console.log`/`console.error` directly in components or apps. Use `ILogger` from `componets/logger.ts`. Create at the `run.*` entry point level: `Logger(console.log)` for CLI apps, `Logger(console.error)` for MCP (stdout is the protocol channel). Inject as a dependency where needed.
|
|
50
|
+
|
|
51
|
+
## Git Rules
|
|
52
|
+
|
|
53
|
+
- **No Co-Authored-By** — never add `Co-Authored-By` lines to commit messages
|
|
54
|
+
- **No tool-origin footers** — never add lines like `Made-with: Cursor`, `Generated with …`, or similar branding/attribution footers to commit messages, PR descriptions, or docs unless the user explicitly asks
|
package/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# xindex
|
|
2
|
+
|
|
3
|
+
Local semantic code search. Index your codebase, search by meaning — no cloud, no API keys. Also runs as an MCP server so Claude Code (and other MCP clients) can search your repo directly.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Local** — everything runs on your machine; embeddings cached on disk
|
|
8
|
+
- **Semantic search** — natural-language queries, not just substring match
|
|
9
|
+
- **MCP server** — plug into Claude Code via `.mcp.json`
|
|
10
|
+
- **Watch mode** — keep the index warm while you code
|
|
11
|
+
- **Gitignore-aware** — respects `.gitignore` + custom ignore rules
|
|
12
|
+
- **Zero config** — works with defaults; `.xindex.json` is optional
|
|
13
|
+
|
|
14
|
+
## How it fits together
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
your repo xindex
|
|
18
|
+
───────── ──────
|
|
19
|
+
*.ts / *.md ──► walk ──► keywords ──► embed ──► .xindex/
|
|
20
|
+
.gitignore (vectra index)
|
|
21
|
+
▲
|
|
22
|
+
CLI / MCP ◄── search ◄── embed query ◄── "question" ┘
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone <repo-url> xindex
|
|
29
|
+
cd xindex
|
|
30
|
+
yarn install # or npm install
|
|
31
|
+
npm link # makes xindex-* binaries + xindex-mcp available on PATH
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Requires Node.js. First run downloads the embedding model (`all-MiniLM-L6-v2`, ~25MB) — after that, fully offline.
|
|
35
|
+
|
|
36
|
+
## Quick start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cd /path/to/your/project
|
|
40
|
+
xindex-index . # build the index
|
|
41
|
+
xindex-search "where is auth handled" # ask a question
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Index lives in `./.xindex/` — add it to `.gitignore`.
|
|
45
|
+
|
|
46
|
+
## CLI
|
|
47
|
+
|
|
48
|
+
All five binaries run from any directory; they index/search the current working directory.
|
|
49
|
+
|
|
50
|
+
### `xindex-index [paths...]`
|
|
51
|
+
Build or update the index. Defaults to `.` if no paths given.
|
|
52
|
+
```bash
|
|
53
|
+
xindex-index .
|
|
54
|
+
xindex-index apps features
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `xindex-search <query...>`
|
|
58
|
+
Search the index. All args are joined into one query. Default limit: 10.
|
|
59
|
+
```bash
|
|
60
|
+
xindex-search "database migration logic"
|
|
61
|
+
xindex-search file watcher debounce
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `xindex-watch [paths...]`
|
|
65
|
+
Initial index + filesystem watch for incremental updates. Uses a lock file so only one watcher owns updates at a time. Ctrl+C releases cleanly.
|
|
66
|
+
```bash
|
|
67
|
+
xindex-watch .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### `xindex-reset`
|
|
71
|
+
Wipe and recreate the index. Destructive.
|
|
72
|
+
```bash
|
|
73
|
+
xindex-reset
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `xindex-mcp`
|
|
77
|
+
Run as an MCP stdio server. Starts a background watcher by default.
|
|
78
|
+
```bash
|
|
79
|
+
xindex-mcp # with watch
|
|
80
|
+
xindex-mcp --watch-disabled # no watch
|
|
81
|
+
xindex-mcp --watch-dir=./src # watch a specific dir
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## MCP (Claude Code & others)
|
|
85
|
+
|
|
86
|
+
Drop this into `.mcp.json` at your project root:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"xindex": {
|
|
92
|
+
"command": "xindex-mcp",
|
|
93
|
+
"args": []
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Requires `xindex-mcp` on PATH (`npm link` inside this repo does it). If you'd rather pin to an absolute path, use `/absolute/path/to/bin/xindex-mcp`.
|
|
100
|
+
|
|
101
|
+
### Tools exposed
|
|
102
|
+
|
|
103
|
+
| Tool | What it does | Input |
|
|
104
|
+
|------|--------------|-------|
|
|
105
|
+
| `xindex_search` | Semantic search | `query: string`, `limit?: number` (default 5, max 100) |
|
|
106
|
+
| `xindex_index` | Index paths | `inputs: string[]` (at least one) |
|
|
107
|
+
| `xindex_reset` | Wipe index (destructive) | — |
|
|
108
|
+
|
|
109
|
+
Note: CLI `xindex-search` defaults to 10 results; MCP `xindex_search` defaults to 5.
|
|
110
|
+
|
|
111
|
+
### Typical Claude Code flow
|
|
112
|
+
|
|
113
|
+
1. Commit `.mcp.json` to your repo.
|
|
114
|
+
2. Open the project in Claude Code — it picks up the xindex MCP server.
|
|
115
|
+
3. Ask it to call `xindex_index` once with `inputs: ["."]`.
|
|
116
|
+
4. From then on, it uses `xindex_search` for natural-language lookups.
|
|
117
|
+
5. Watch mode keeps the index fresh as you edit.
|
|
118
|
+
|
|
119
|
+
## Configuration
|
|
120
|
+
|
|
121
|
+
### `.xindex.json` (optional)
|
|
122
|
+
|
|
123
|
+
Place at your project root. Both fields are optional arrays; unknown keys are ignored.
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"ignoreKeywords": ["import", "export", "function", "const"],
|
|
128
|
+
"ignoreFiles": ["dist/**", "node_modules/**", ".xindex"]
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- **`ignoreKeywords`** — tokens stripped before embedding (noise words, language keywords, project slang). Keeps search focused on meaningful terms.
|
|
133
|
+
- **`ignoreFiles`** — extra glob patterns excluded during walk/watch, on top of `.gitignore`.
|
|
134
|
+
|
|
135
|
+
### `.xindex/` folder
|
|
136
|
+
|
|
137
|
+
Created automatically. Contains:
|
|
138
|
+
- `semantic/` — the vectra index (vectors + metadata)
|
|
139
|
+
- `lock.json` — watcher lock (coordinates watch/MCP processes)
|
|
140
|
+
|
|
141
|
+
**Always gitignore it.**
|
|
142
|
+
|
|
143
|
+
### `.gitignore`
|
|
144
|
+
|
|
145
|
+
Minimum:
|
|
146
|
+
```
|
|
147
|
+
.xindex
|
|
148
|
+
node_modules/
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Examples
|
|
152
|
+
|
|
153
|
+
### Index + search from the terminal
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
cd my-app
|
|
157
|
+
xindex-index .
|
|
158
|
+
xindex-search "rate limiter implementation"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Keep the index warm while coding
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
xindex-watch .
|
|
165
|
+
# edit files in another terminal; index updates incrementally
|
|
166
|
+
# Ctrl+C to stop
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Use from Claude Code via MCP
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# one-time setup
|
|
173
|
+
cd xindex && npm link
|
|
174
|
+
|
|
175
|
+
# in your project
|
|
176
|
+
echo '{"mcpServers":{"xindex":{"command":"xindex-mcp","args":[]}}}' > .mcp.json
|
|
177
|
+
|
|
178
|
+
# open project in Claude Code — xindex tools are available
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Run MCP without watching
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
xindex-mcp --watch-disabled
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
You control when reindexing happens via explicit `xindex_index` calls.
|
|
188
|
+
|
|
189
|
+
## Project layout
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
apps/ entry points (run.*.ts) + app composers (IndexApp, SearchApp, McpApp, ...)
|
|
193
|
+
bin/ shebang wrappers invoked by npm/yarn and .mcp.json
|
|
194
|
+
componets/ shared building blocks: config, walk, watch, embed, vectra adapter, logger
|
|
195
|
+
features/ domain operations: indexContent, searchIndex, removeContent, resetIndex
|
|
196
|
+
packages/ small internal libs (streamx, fun)
|
|
197
|
+
.xindex/ runtime data (gitignored)
|
|
198
|
+
.xindex.json optional config
|
|
199
|
+
.mcp.json MCP registration for Claude Code / compatible clients
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
See [CLAUDE.md](CLAUDE.md) for contributor conventions (HOF pattern, logger rules, task workflow).
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
MIT
|
package/apps/indexApp.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {readFile} from "fs/promises";
|
|
2
|
+
import {from} from "../packages/streamx/src/from.js";
|
|
3
|
+
import {map} from "../packages/streamx/src/map.js";
|
|
4
|
+
import {tap} from "../packages/streamx/src/tap.js";
|
|
5
|
+
import {run} from "../packages/streamx/src/index.js";
|
|
6
|
+
import {IWalkFiles} from "../componets/walkFiles.js";
|
|
7
|
+
import {IIndexContent} from "../features/indexContent.js";
|
|
8
|
+
import {IRemoveContent} from "../features/removeContent.js";
|
|
9
|
+
import {ILogger} from "../componets/logger.js";
|
|
10
|
+
|
|
11
|
+
export type IIndexApp = (inputs: string[]) => Promise<void>;
|
|
12
|
+
|
|
13
|
+
export function IndexApp({walkFiles, indexContent, removeContent, log}: {
|
|
14
|
+
walkFiles: IWalkFiles,
|
|
15
|
+
indexContent: IIndexContent,
|
|
16
|
+
removeContent: IRemoveContent,
|
|
17
|
+
log: ILogger,
|
|
18
|
+
}): IIndexApp {
|
|
19
|
+
return async function indexApp(inputs) {
|
|
20
|
+
await run(
|
|
21
|
+
from(walkFiles(inputs))
|
|
22
|
+
.pipe(tap(id => log(`indexing: ${id}`)))
|
|
23
|
+
.pipe(map<string, string>(async (id) => {
|
|
24
|
+
try { await removeContent(id); } catch (e) { log(`remove failed: ${id} — ${(e as any)?.message ?? e}`); }
|
|
25
|
+
const text = await readFile(id, "utf8");
|
|
26
|
+
await indexContent(id, `${text}. ${id}`);
|
|
27
|
+
return id;
|
|
28
|
+
}))
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
package/apps/mcpApp.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {McpServer} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import {StdioServerTransport} from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import {z} from "zod";
|
|
4
|
+
import {ISearchIndex} from "../features/searchIndex.js";
|
|
5
|
+
import {IIndexApp} from "./indexApp.js";
|
|
6
|
+
import {IGetIndexStats} from "../componets/index/getIndexStats.js";
|
|
7
|
+
import {IResetIndex} from "../features/resetIndex.js";
|
|
8
|
+
import {IWatchFiles} from "../componets/watchFiles.js";
|
|
9
|
+
import {IHandleFileEvent} from "../componets/index/handleFileEvent.js";
|
|
10
|
+
import {ILogger} from "../componets/logger.js";
|
|
11
|
+
import {WatchFileEventsApp} from "./watchFileEventsApp.js";
|
|
12
|
+
import {IWatcherLock} from "../componets/index/watcherLock.js";
|
|
13
|
+
import {IXindexConfig} from "../componets/config/xindexConfig.js";
|
|
14
|
+
import {FormatSearchResults} from "../componets/index/formatSearchResults.js";
|
|
15
|
+
|
|
16
|
+
export type IMcpApp = () => Promise<void>;
|
|
17
|
+
|
|
18
|
+
export type IMcpWatch = {
|
|
19
|
+
watchFiles: IWatchFiles,
|
|
20
|
+
watchDir: string,
|
|
21
|
+
handleFileEvent: IHandleFileEvent,
|
|
22
|
+
watcherLock: IWatcherLock,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function McpApp({
|
|
26
|
+
searchContentIndex, indexApp, getIndexStats, resetIndex, log, watch, config,
|
|
27
|
+
}: {
|
|
28
|
+
searchContentIndex: ISearchIndex,
|
|
29
|
+
indexApp: IIndexApp,
|
|
30
|
+
getIndexStats: IGetIndexStats,
|
|
31
|
+
resetIndex: IResetIndex,
|
|
32
|
+
log: ILogger,
|
|
33
|
+
watch?: IMcpWatch,
|
|
34
|
+
config: IXindexConfig,
|
|
35
|
+
}): IMcpApp {
|
|
36
|
+
return async function mcpApp() {
|
|
37
|
+
const server = new McpServer({name: "xindex", version: "0.1.0"});
|
|
38
|
+
|
|
39
|
+
// --- search ---
|
|
40
|
+
|
|
41
|
+
server.registerTool("xindex_search", {
|
|
42
|
+
title: "Search codebase",
|
|
43
|
+
description: "Semantic search over indexed codebase files. Returns scored results with file paths and keywords.",
|
|
44
|
+
inputSchema: z.object({
|
|
45
|
+
query: z.string()
|
|
46
|
+
.describe("Natural language search query"),
|
|
47
|
+
limit: z.number().int().min(1).max(100).default(5)
|
|
48
|
+
.describe("Max results to return, 5 by default, 100 max"),
|
|
49
|
+
}),
|
|
50
|
+
annotations: {readOnlyHint: true},
|
|
51
|
+
}, async ({query, limit}) => {
|
|
52
|
+
try {
|
|
53
|
+
const format = FormatSearchResults();
|
|
54
|
+
const results = await searchContentIndex(query, limit);
|
|
55
|
+
const text = await format(query, results);
|
|
56
|
+
return {content: [{type: "text" as const, text}]};
|
|
57
|
+
} catch (e) {
|
|
58
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
59
|
+
log("xindex_search error:", msg);
|
|
60
|
+
return {content: [{type: "text" as const, text: msg}], isError: true};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// --- index ---
|
|
65
|
+
|
|
66
|
+
server.registerTool("xindex_index", {
|
|
67
|
+
title: "Index files or directories",
|
|
68
|
+
description: "Index files or directories for semantic search. " +
|
|
69
|
+
"Accepts file paths or directory paths. Directories are walked recursively, respecting .gitignore.",
|
|
70
|
+
inputSchema: z.object({
|
|
71
|
+
inputs: z.array(z.string()).min(1)
|
|
72
|
+
.describe("File or directory paths to index"),
|
|
73
|
+
}),
|
|
74
|
+
}, async ({inputs}) => {
|
|
75
|
+
try {
|
|
76
|
+
await indexApp(inputs);
|
|
77
|
+
const stats = await getIndexStats();
|
|
78
|
+
return {content: [{
|
|
79
|
+
type: "text" as const,
|
|
80
|
+
text: `Indexed successfully. Total files: ${stats.indexedAmount}`,
|
|
81
|
+
}]};
|
|
82
|
+
} catch (e) {
|
|
83
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
84
|
+
log("xindex_index error:", msg);
|
|
85
|
+
return {content: [{type: "text" as const, text: msg}], isError: true};
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// --- reset ---
|
|
90
|
+
|
|
91
|
+
server.registerTool("xindex_reset", {
|
|
92
|
+
title: "Reset index",
|
|
93
|
+
description: "Delete and recreate the search index. " +
|
|
94
|
+
"Always ask the user for explicit confirmation before running this tool.",
|
|
95
|
+
inputSchema: z.object({}),
|
|
96
|
+
annotations: {destructiveHint: true},
|
|
97
|
+
}, async () => {
|
|
98
|
+
try {
|
|
99
|
+
await resetIndex();
|
|
100
|
+
return {content: [{type: "text" as const, text: "Index reset successfully"}]};
|
|
101
|
+
} catch (e) {
|
|
102
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
103
|
+
log("xindex_reset error:", msg);
|
|
104
|
+
return {content: [{type: "text" as const, text: msg}], isError: true};
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// --- start ---
|
|
109
|
+
|
|
110
|
+
const transport = new StdioServerTransport();
|
|
111
|
+
await server.connect(transport);
|
|
112
|
+
log("xindex MCP server running on stdio");
|
|
113
|
+
|
|
114
|
+
if (watch) {
|
|
115
|
+
const startWatch = WatchFileEventsApp({...watch, log});
|
|
116
|
+
startWatch();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {BuildComponents} from "../componets/buildComponents.js";
|
|
2
|
+
import {BufferedLoggerToStdOut} from "../componets/logger.js";
|
|
3
|
+
import {WalkFiles} from "../componets/walkFiles.js";
|
|
4
|
+
import {IndexApp} from "./indexApp.js";
|
|
5
|
+
import {AppId} from "../componets/appId.js";
|
|
6
|
+
|
|
7
|
+
const appId = AppId();
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
const log = BufferedLoggerToStdOut();
|
|
10
|
+
const {indexContent, removeContent, getIndexStats, config} = await BuildComponents({log});
|
|
11
|
+
const walkFiles = WalkFiles({cwd, log, ignoreFiles: config.ignoreFiles});
|
|
12
|
+
const indexApp = IndexApp({walkFiles, indexContent, removeContent, log});
|
|
13
|
+
|
|
14
|
+
const inputs = process.argv.slice(2);
|
|
15
|
+
if (!inputs.length) inputs.push(".");
|
|
16
|
+
|
|
17
|
+
log(`[${appId}] started, indexing: ${inputs.join(", ")}`);
|
|
18
|
+
await indexApp(inputs);
|
|
19
|
+
log(`[${appId}] done:`, await getIndexStats());
|
package/apps/run.mcp.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {BuildComponents} from "../componets/buildComponents.js";
|
|
2
|
+
import {HandleFileEvent} from "../componets/index/handleFileEvent.js";
|
|
3
|
+
import {BufferedLoggerToStdErr} from "../componets/logger.js";
|
|
4
|
+
import {WalkFiles} from "../componets/walkFiles.js";
|
|
5
|
+
import {WatchFiles} from "../componets/watchFiles.js";
|
|
6
|
+
import {WatcherLock} from "../componets/index/watcherLock.js";
|
|
7
|
+
import {IndexApp} from "./indexApp.js";
|
|
8
|
+
import {McpApp} from "./mcpApp.js";
|
|
9
|
+
import {join} from "path";
|
|
10
|
+
import {AppId} from "../componets/appId.js";
|
|
11
|
+
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
const watchDirArg = args.find(a => a.startsWith("--watch-dir="));
|
|
14
|
+
const watchDisabled = args.includes("--watch-disabled");
|
|
15
|
+
|
|
16
|
+
const cwd = process.cwd();
|
|
17
|
+
const log = BufferedLoggerToStdErr();
|
|
18
|
+
const {indexContent, removeContent, getIndexStats, searchContentIndex, resetIndex, config} = await BuildComponents({log});
|
|
19
|
+
const walkFiles = WalkFiles({cwd, log, ignoreFiles: config.ignoreFiles});
|
|
20
|
+
const indexApp = IndexApp({walkFiles, indexContent, removeContent, log});
|
|
21
|
+
|
|
22
|
+
const appId = AppId();
|
|
23
|
+
const watcherLock = WatcherLock({
|
|
24
|
+
lockPath: join(cwd, ".xindex", "lock.json"),
|
|
25
|
+
appId,
|
|
26
|
+
log,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const watch = watchDisabled ? undefined : {
|
|
30
|
+
watchFiles: WatchFiles({cwd, log, ignoreFiles: config.ignoreFiles}),
|
|
31
|
+
watchDir: watchDirArg ? watchDirArg.split("=")[1] : ".",
|
|
32
|
+
handleFileEvent: HandleFileEvent({indexContent, removeContent, log}),
|
|
33
|
+
watcherLock,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
process.on("SIGINT", async () => {
|
|
37
|
+
log(`[${appId}] shutting down — stopping heartbeat...`);
|
|
38
|
+
watcherLock.stopHeartbeat();
|
|
39
|
+
log(`[${appId}] releasing lock...`);
|
|
40
|
+
await watcherLock.release();
|
|
41
|
+
log(`[${appId}] waiting 7s for another watcher to take over...`);
|
|
42
|
+
await new Promise(r => setTimeout(r, 7000));
|
|
43
|
+
log(`[${appId}] exiting`);
|
|
44
|
+
process.exit(0);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
log(`[${appId}] started`);
|
|
48
|
+
const mcpApp = McpApp({searchContentIndex, indexApp, getIndexStats, resetIndex, log, watch, config});
|
|
49
|
+
await mcpApp();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {BuildComponents} from "../componets/buildComponents.js";
|
|
2
|
+
import {BufferedLoggerToStdOut} from "../componets/logger.js";
|
|
3
|
+
import {AppId} from "../componets/appId.js";
|
|
4
|
+
|
|
5
|
+
const appId = AppId();
|
|
6
|
+
const log = BufferedLoggerToStdOut();
|
|
7
|
+
const {resetIndex} = await BuildComponents({log});
|
|
8
|
+
log(`[${appId}] resetting index...`);
|
|
9
|
+
await resetIndex();
|
|
10
|
+
log(`[${appId}] done`);
|