doc2vec 2.14.1 → 2.15.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/README.md +42 -0
- package/dist/content-processor.js +29 -9
- package/dist/doc2vec.js +86 -68
- package/dist/types.js +12 -0
- package/dist/ui/assets/{index-JQ3zqQ_O.js → index-DCnbYtxb.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/dist/utils.js +88 -0
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -218,6 +218,7 @@ Configuration is managed through two files:
|
|
|
218
218
|
* `branch`: (Optional) Branch to clone for GitHub sources.
|
|
219
219
|
* `include_extensions`: (Optional) Array of file extensions to include (defaults to common code extensions).
|
|
220
220
|
* `exclude_extensions`: (Optional) Array of file extensions to exclude.
|
|
221
|
+
* `exclude_paths`: (Optional) Array of glob patterns, relative to the source root, that the scanner skips. See [Excluding paths from code sources](#excluding-paths-from-code-sources).
|
|
221
222
|
* `recursive`: (Optional) Whether to traverse subdirectories (defaults to `true`).
|
|
222
223
|
* `url_rewrite_prefix`: (Optional) URL prefix to rewrite `file://` URLs for local sources.
|
|
223
224
|
* `encoding`: (Optional) File encoding to use (defaults to `'utf8'`).
|
|
@@ -359,6 +360,10 @@ Configuration is managed through two files:
|
|
|
359
360
|
repo: 'kagent-dev/doc2vec'
|
|
360
361
|
branch: 'main'
|
|
361
362
|
include_extensions: ['.ts', '.tsx', '.md']
|
|
363
|
+
exclude_paths:
|
|
364
|
+
- 'node_modules/**'
|
|
365
|
+
- 'dist/**'
|
|
366
|
+
- '**/*.test.ts'
|
|
362
367
|
max_size: 1048576
|
|
363
368
|
chunk_size: 2048
|
|
364
369
|
database_config:
|
|
@@ -415,6 +420,43 @@ Configuration is managed through two files:
|
|
|
415
420
|
# ... more sources
|
|
416
421
|
```
|
|
417
422
|
|
|
423
|
+
### Excluding paths from code sources
|
|
424
|
+
|
|
425
|
+
Code sources (`type: 'code'`) accept `exclude_paths`. Each entry is a glob pattern that the scanner matches against the path of the file, relative to the source root. The root is the `path` directory for a local source, or the clone root for a GitHub source. Use it to keep vendored trees, generated code, and test files out of the index.
|
|
426
|
+
|
|
427
|
+
```yaml
|
|
428
|
+
- type: 'code'
|
|
429
|
+
source: 'github'
|
|
430
|
+
product_name: 'my-product'
|
|
431
|
+
repo: 'my-org/my-repo'
|
|
432
|
+
branch: 'main'
|
|
433
|
+
include_extensions: ['.go', '.md', '.yaml', '.sh', '.py', '.proto']
|
|
434
|
+
exclude_paths:
|
|
435
|
+
- 'vendor/**' # vendored dependencies
|
|
436
|
+
- 'LICENSES/**' # go-licenses output
|
|
437
|
+
- 'pkg/client/**' # k8s code-generator output
|
|
438
|
+
- '**/*.pb.go' # protobuf output
|
|
439
|
+
- '**/zz_generated.*.go' # controller-gen output
|
|
440
|
+
- '**/*_test.go' # tests
|
|
441
|
+
- 'hack/tools/**'
|
|
442
|
+
max_size: 1048576
|
|
443
|
+
database_config:
|
|
444
|
+
type: 'sqlite'
|
|
445
|
+
params:
|
|
446
|
+
db_path: './my-product-code.db'
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Pattern rules:
|
|
450
|
+
|
|
451
|
+
* `*` matches any characters inside one path segment. It does not cross a `/`.
|
|
452
|
+
* `**` matches any characters, and it crosses `/`. `vendor/**` therefore matches every file below `vendor/`.
|
|
453
|
+
* A leading `**/` also matches zero directories, so `**/*_test.go` matches `main_test.go` at the root and `pkg/a/main_test.go` below it.
|
|
454
|
+
* `?` matches one character inside a segment.
|
|
455
|
+
* A pattern that names a directory (`vendor` or `vendor/**`) prunes the whole subtree. The scanner does not walk it.
|
|
456
|
+
* Matching is case-sensitive, and a pattern must match the whole relative path. Use `**/build/**`, not `build`, to exclude a directory at any depth.
|
|
457
|
+
|
|
458
|
+
The scanner treats an excluded file as if it does not exist. A full scan therefore removes the chunks of files you newly excluded. For GitHub sources in incremental mode, the removal happens on the next full scan.
|
|
459
|
+
|
|
418
460
|
## Usage
|
|
419
461
|
|
|
420
462
|
Run the script from the command line using the `start` script defined in `package.json`. This uses `ts-node` to execute the TypeScript code directly.
|
|
@@ -72,12 +72,12 @@ exports.BrowserLaunchError = BrowserLaunchError;
|
|
|
72
72
|
* Chrome for Testing is not published)
|
|
73
73
|
* 4. undefined — let puppeteer decide
|
|
74
74
|
*/
|
|
75
|
-
function resolveBrowserExecutablePath() {
|
|
75
|
+
async function resolveBrowserExecutablePath() {
|
|
76
76
|
const override = process.env.PUPPETEER_EXECUTABLE_PATH;
|
|
77
77
|
if (override)
|
|
78
78
|
return override;
|
|
79
79
|
try {
|
|
80
|
-
const bundled = puppeteer_1.default.executablePath();
|
|
80
|
+
const bundled = await puppeteer_1.default.executablePath();
|
|
81
81
|
if (bundled && fs.existsSync(bundled))
|
|
82
82
|
return bundled;
|
|
83
83
|
}
|
|
@@ -421,7 +421,7 @@ class ContentProcessor {
|
|
|
421
421
|
let browser = null;
|
|
422
422
|
let page = null;
|
|
423
423
|
const launchBrowser = async () => {
|
|
424
|
-
const executablePath = resolveBrowserExecutablePath();
|
|
424
|
+
const executablePath = await resolveBrowserExecutablePath();
|
|
425
425
|
const launchOptions = {
|
|
426
426
|
executablePath,
|
|
427
427
|
args: [
|
|
@@ -487,7 +487,7 @@ class ContentProcessor {
|
|
|
487
487
|
// If protocol errors are persisting after page recreation, the browser
|
|
488
488
|
// process itself is degraded — a full restart is needed.
|
|
489
489
|
const needsBrowserRestart = pageNeedsRecreation && consecutiveProtocolErrors >= 1;
|
|
490
|
-
if (!browser || !browser.
|
|
490
|
+
if (!browser || !browser.connected || needsBrowserRestart) {
|
|
491
491
|
const reason = needsBrowserRestart
|
|
492
492
|
? `protocol errors persisting after page recreation (${consecutiveProtocolErrors} consecutive)`
|
|
493
493
|
: browser ? 'browser disconnected' : 'initial launch';
|
|
@@ -793,7 +793,9 @@ class ContentProcessor {
|
|
|
793
793
|
// A browser that cannot launch is fatal for the whole crawl —
|
|
794
794
|
// rethrow so the source (and the run) is reported as failed
|
|
795
795
|
// rather than logging an error per URL and finishing "green".
|
|
796
|
-
|
|
796
|
+
// Same for a permanent embedding failure (bad API key):
|
|
797
|
+
// every remaining page would fail identically.
|
|
798
|
+
if (error instanceof BrowserLaunchError || error?.name === 'FatalEmbeddingError') {
|
|
797
799
|
logger.error(`Aborting crawl of ${baseUrl}: ${error.message}`);
|
|
798
800
|
throw error;
|
|
799
801
|
}
|
|
@@ -858,7 +860,7 @@ class ContentProcessor {
|
|
|
858
860
|
finally {
|
|
859
861
|
// Close the shared browser instance when the crawl is done
|
|
860
862
|
const browserToClose = browser;
|
|
861
|
-
if (browserToClose && browserToClose.
|
|
863
|
+
if (browserToClose && browserToClose.connected) {
|
|
862
864
|
await browserToClose.close();
|
|
863
865
|
logger.debug('Shared browser closed after crawl completed');
|
|
864
866
|
}
|
|
@@ -962,7 +964,7 @@ class ContentProcessor {
|
|
|
962
964
|
else {
|
|
963
965
|
// Standalone mode: launch a browser for this single page
|
|
964
966
|
browser = await puppeteer_1.default.launch({
|
|
965
|
-
executablePath: resolveBrowserExecutablePath(),
|
|
967
|
+
executablePath: await resolveBrowserExecutablePath(),
|
|
966
968
|
args: [
|
|
967
969
|
'--no-sandbox',
|
|
968
970
|
'--disable-setuid-sandbox',
|
|
@@ -1143,7 +1145,7 @@ class ContentProcessor {
|
|
|
1143
1145
|
}
|
|
1144
1146
|
finally {
|
|
1145
1147
|
// Only close the browser if we launched it ourselves (standalone mode)
|
|
1146
|
-
if (ownsTheBrowser && browser && browser.
|
|
1148
|
+
if (ownsTheBrowser && browser && browser.connected) {
|
|
1147
1149
|
await browser.close();
|
|
1148
1150
|
logger.debug(`Browser closed for ${url}`);
|
|
1149
1151
|
}
|
|
@@ -1643,7 +1645,10 @@ class ContentProcessor {
|
|
|
1643
1645
|
'.json', '.yaml', '.yml', '.md'
|
|
1644
1646
|
];
|
|
1645
1647
|
const excludeExtensions = config.exclude_extensions || [];
|
|
1648
|
+
const excludePaths = config.exclude_paths || [];
|
|
1646
1649
|
const encoding = config.encoding || 'utf8';
|
|
1650
|
+
const rootPath = options?.rootPath ?? dirPath;
|
|
1651
|
+
const childOptions = { ...options, rootPath };
|
|
1647
1652
|
let maxMtime = 0;
|
|
1648
1653
|
let incomplete = false;
|
|
1649
1654
|
try {
|
|
@@ -1673,9 +1678,24 @@ class ContentProcessor {
|
|
|
1673
1678
|
continue;
|
|
1674
1679
|
}
|
|
1675
1680
|
visitedPaths.add(filePath);
|
|
1681
|
+
// An excluded path never reaches trackFiles or maxMtime, so the
|
|
1682
|
+
// caller treats it like a deleted file and removes its chunks
|
|
1683
|
+
if (excludePaths.length > 0) {
|
|
1684
|
+
const relativePath = path.relative(rootPath, filePath).replace(/\\/g, '/');
|
|
1685
|
+
const excluded = stat.isDirectory()
|
|
1686
|
+
? utils_1.Utils.isDirectoryExcluded(relativePath, excludePaths)
|
|
1687
|
+
: utils_1.Utils.matchesAnyGlob(relativePath, excludePaths);
|
|
1688
|
+
if (excluded) {
|
|
1689
|
+
logger.debug(`Skipping excluded path: ${relativePath}`);
|
|
1690
|
+
if (!stat.isDirectory()) {
|
|
1691
|
+
skippedFiles++;
|
|
1692
|
+
}
|
|
1693
|
+
continue;
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1676
1696
|
if (stat.isDirectory()) {
|
|
1677
1697
|
if (recursive) {
|
|
1678
|
-
const childResult = await this.processCodeDirectory(filePath, config, processFileContent, logger, visitedPaths,
|
|
1698
|
+
const childResult = await this.processCodeDirectory(filePath, config, processFileContent, logger, visitedPaths, childOptions);
|
|
1679
1699
|
processedFiles += childResult.processedFiles;
|
|
1680
1700
|
skippedFiles += childResult.skippedFiles;
|
|
1681
1701
|
maxMtime = Math.max(maxMtime, childResult.maxMtime);
|
package/dist/doc2vec.js
CHANGED
|
@@ -39,7 +39,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
exports.Doc2Vec = void 0;
|
|
41
41
|
const axios_1 = __importDefault(require("axios"));
|
|
42
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
43
42
|
const yaml = __importStar(require("js-yaml"));
|
|
44
43
|
const fs = __importStar(require("fs"));
|
|
45
44
|
const path = __importStar(require("path"));
|
|
@@ -481,6 +480,30 @@ class Doc2Vec {
|
|
|
481
480
|
};
|
|
482
481
|
const chunks = await this.contentProcessor.chunkMarkdown(markdown, issueConfig, url);
|
|
483
482
|
logger.info(`Issue #${issueNumber}: Created ${chunks.length} chunks`);
|
|
483
|
+
// Embed every chunk BEFORE touching stored data, so an embedding
|
|
484
|
+
// failure can't purge the issue's existing chunks and store nothing
|
|
485
|
+
// back. A FatalEmbeddingError (bad API key) propagates and aborts
|
|
486
|
+
// the source; transient failures skip this issue but count toward
|
|
487
|
+
// failedChunks so the last-run date is not advanced.
|
|
488
|
+
const embedded = [];
|
|
489
|
+
let failedEmbeddings = 0;
|
|
490
|
+
for (const chunk of chunks) {
|
|
491
|
+
const chunkId = chunk.metadata.chunk_id.substring(0, 8) + '...';
|
|
492
|
+
const embeddings = await this.createEmbeddings([chunk.content]);
|
|
493
|
+
if (embeddings.length) {
|
|
494
|
+
embedded.push(embeddings[0]);
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
failedEmbeddings++;
|
|
498
|
+
logger.error(`Embedding failed for chunk: ${chunkId}`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (failedEmbeddings > 0) {
|
|
502
|
+
failedChunks += failedEmbeddings;
|
|
503
|
+
logger.error(`Issue #${issueNumber}: ${failedEmbeddings}/${chunks.length} chunks failed to embed; ` +
|
|
504
|
+
`keeping its existing chunks so the next run retries`);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
484
507
|
// Purge the issue's existing chunks before inserting the fresh set.
|
|
485
508
|
// chunk_id is a content hash, so when an issue changes (closed/reopened,
|
|
486
509
|
// edited, new comments) the regenerated chunks get new ids and the old
|
|
@@ -501,57 +524,21 @@ class Doc2Vec {
|
|
|
501
524
|
else {
|
|
502
525
|
this.counters.items_new++;
|
|
503
526
|
}
|
|
504
|
-
//
|
|
505
|
-
for (
|
|
527
|
+
// Store each chunk
|
|
528
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
529
|
+
const chunk = chunks[i];
|
|
506
530
|
const chunkHash = utils_1.Utils.generateHash(chunk.content);
|
|
507
531
|
const chunkId = chunk.metadata.chunk_id.substring(0, 8) + '...';
|
|
508
532
|
if (dbConnection.type === 'sqlite') {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
logger.info(`Skipping unchanged chunk: ${chunkId}`);
|
|
513
|
-
continue;
|
|
514
|
-
}
|
|
515
|
-
const embeddings = await this.createEmbeddings([chunk.content]);
|
|
516
|
-
if (embeddings.length) {
|
|
517
|
-
database_1.DatabaseManager.insertVectorsSQLite(dbConnection.db, chunk, embeddings[0], logger, chunkHash);
|
|
518
|
-
this.counters.chunks_added++;
|
|
519
|
-
logger.debug(`Stored chunk ${chunkId} in SQLite`);
|
|
520
|
-
}
|
|
521
|
-
else {
|
|
522
|
-
logger.error(`Embedding failed for chunk: ${chunkId}`);
|
|
523
|
-
}
|
|
533
|
+
database_1.DatabaseManager.insertVectorsSQLite(dbConnection.db, chunk, embedded[i], logger, chunkHash);
|
|
534
|
+
this.counters.chunks_added++;
|
|
535
|
+
logger.debug(`Stored chunk ${chunkId} in SQLite`);
|
|
524
536
|
}
|
|
525
537
|
else if (dbConnection.type === 'qdrant') {
|
|
526
538
|
try {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (!utils_1.Utils.isValidUuid(pointId)) {
|
|
531
|
-
pointId = utils_1.Utils.hashToUuid(chunk.metadata.chunk_id);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
catch (e) {
|
|
535
|
-
pointId = crypto_1.default.randomUUID();
|
|
536
|
-
}
|
|
537
|
-
const existingPoints = await dbConnection.client.retrieve(dbConnection.collectionName, {
|
|
538
|
-
ids: [pointId],
|
|
539
|
-
with_payload: true,
|
|
540
|
-
with_vector: false,
|
|
541
|
-
});
|
|
542
|
-
if (existingPoints.length > 0 && existingPoints[0].payload && existingPoints[0].payload.hash === chunkHash) {
|
|
543
|
-
logger.info(`Skipping unchanged chunk: ${chunkId}`);
|
|
544
|
-
continue;
|
|
545
|
-
}
|
|
546
|
-
const embeddings = await this.createEmbeddings([chunk.content]);
|
|
547
|
-
if (embeddings.length) {
|
|
548
|
-
await database_1.DatabaseManager.storeChunkInQdrant(dbConnection, chunk, embeddings[0], chunkHash);
|
|
549
|
-
this.counters.chunks_added++;
|
|
550
|
-
logger.debug(`Stored chunk ${chunkId} in Qdrant (${dbConnection.collectionName})`);
|
|
551
|
-
}
|
|
552
|
-
else {
|
|
553
|
-
logger.error(`Embedding failed for chunk: ${chunkId}`);
|
|
554
|
-
}
|
|
539
|
+
await database_1.DatabaseManager.storeChunkInQdrant(dbConnection, chunk, embedded[i], chunkHash);
|
|
540
|
+
this.counters.chunks_added++;
|
|
541
|
+
logger.debug(`Stored chunk ${chunkId} in Qdrant (${dbConnection.collectionName})`);
|
|
555
542
|
}
|
|
556
543
|
catch (error) {
|
|
557
544
|
// Keep going so one bad chunk can't cost the whole repo,
|
|
@@ -680,6 +667,8 @@ class Doc2Vec {
|
|
|
680
667
|
return true;
|
|
681
668
|
}
|
|
682
669
|
catch (error) {
|
|
670
|
+
if (error instanceof types_1.FatalEmbeddingError)
|
|
671
|
+
throw error;
|
|
683
672
|
logger.error(`Error during chunking or embedding for ${url}:`, error);
|
|
684
673
|
return false;
|
|
685
674
|
}
|
|
@@ -829,6 +818,8 @@ class Doc2Vec {
|
|
|
829
818
|
await this.processChunksForUrl(chunks, fileUrl, dbConnection, logger);
|
|
830
819
|
}
|
|
831
820
|
catch (error) {
|
|
821
|
+
if (error instanceof types_1.FatalEmbeddingError)
|
|
822
|
+
throw error;
|
|
832
823
|
logger.error(`Error during chunking or embedding for ${filePath}:`, error);
|
|
833
824
|
}
|
|
834
825
|
}, logger);
|
|
@@ -999,6 +990,8 @@ class Doc2Vec {
|
|
|
999
990
|
processedCount++;
|
|
1000
991
|
}
|
|
1001
992
|
catch (error) {
|
|
993
|
+
if (error instanceof types_1.FatalEmbeddingError)
|
|
994
|
+
throw error;
|
|
1002
995
|
logger.error(`Error processing S3 object ${obj.key}:`, error);
|
|
1003
996
|
}
|
|
1004
997
|
}
|
|
@@ -1155,6 +1148,8 @@ class Doc2Vec {
|
|
|
1155
1148
|
await this.processChunksForUrl(chunks, fileUrl, dbConnection, logger);
|
|
1156
1149
|
}
|
|
1157
1150
|
catch (error) {
|
|
1151
|
+
if (error instanceof types_1.FatalEmbeddingError)
|
|
1152
|
+
throw error;
|
|
1158
1153
|
logger.error(`Error during code chunking or embedding for ${filePath}:`, error);
|
|
1159
1154
|
}
|
|
1160
1155
|
}, logger, undefined, {
|
|
@@ -1594,6 +1589,8 @@ class Doc2Vec {
|
|
|
1594
1589
|
totalTickets++;
|
|
1595
1590
|
}
|
|
1596
1591
|
catch (error) {
|
|
1592
|
+
if (error instanceof types_1.FatalEmbeddingError)
|
|
1593
|
+
throw error;
|
|
1597
1594
|
failedTickets++;
|
|
1598
1595
|
logger.error(`Failed to process ticket #${ticket.id}, will retry next run: ${error.message}`);
|
|
1599
1596
|
}
|
|
@@ -1781,9 +1778,36 @@ class Doc2Vec {
|
|
|
1781
1778
|
this.counters.items_unchanged++;
|
|
1782
1779
|
return 0;
|
|
1783
1780
|
}
|
|
1784
|
-
// 4. Content changed —
|
|
1781
|
+
// 4. Content changed — embed all new chunks BEFORE touching stored
|
|
1782
|
+
// data, so an embedding failure (e.g. a bad API key) can't delete the
|
|
1783
|
+
// existing chunks and then store nothing back. Throwing here also
|
|
1784
|
+
// signals the caller that the item failed: for websites that means the
|
|
1785
|
+
// ETag/lastmod is not stored and the page is retried next run.
|
|
1786
|
+
const chunkProgress = logger.progress(`Embedding chunks for ${url}`, chunks.length);
|
|
1787
|
+
const embedded = [];
|
|
1788
|
+
let failedEmbeddings = 0;
|
|
1789
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
1790
|
+
const chunk = chunks[i];
|
|
1791
|
+
const chunkId = chunk.metadata.chunk_id.substring(0, 8) + '...';
|
|
1792
|
+
const embeddings = await this.createEmbeddings([chunk.content]);
|
|
1793
|
+
if (embeddings.length > 0) {
|
|
1794
|
+
embedded[i] = embeddings[0];
|
|
1795
|
+
chunkProgress.update(1, `Embedded chunk ${chunkId}`);
|
|
1796
|
+
}
|
|
1797
|
+
else {
|
|
1798
|
+
failedEmbeddings++;
|
|
1799
|
+
logger.error(`Embedding failed for chunk: ${chunkId}`);
|
|
1800
|
+
chunkProgress.update(1, `Failed to embed chunk ${chunkId}`);
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
if (failedEmbeddings > 0) {
|
|
1804
|
+
chunkProgress.complete();
|
|
1805
|
+
throw new Error(`embedding failed for ${failedEmbeddings}/${chunks.length} chunks of ${url}; ` +
|
|
1806
|
+
`keeping the ${existingHashesSorted.length} existing chunks so the next run retries`);
|
|
1807
|
+
}
|
|
1808
|
+
// 5. All embeddings succeeded — delete the old chunks and insert the new set
|
|
1785
1809
|
if (existingHashesSorted.length > 0) {
|
|
1786
|
-
logger.info(`Content changed for ${url} (${existingHashesSorted.length} old chunks → ${chunks.length} new chunks),
|
|
1810
|
+
logger.info(`Content changed for ${url} (${existingHashesSorted.length} old chunks → ${chunks.length} new chunks), replacing all`);
|
|
1787
1811
|
if (dbConnection.type === 'sqlite') {
|
|
1788
1812
|
database_1.DatabaseManager.removeChunksByUrlSQLite(dbConnection.db, url, logger);
|
|
1789
1813
|
}
|
|
@@ -1796,34 +1820,22 @@ class Doc2Vec {
|
|
|
1796
1820
|
else {
|
|
1797
1821
|
this.counters.items_new++;
|
|
1798
1822
|
}
|
|
1799
|
-
// 5. Embed and insert all new chunks
|
|
1800
|
-
let embeddedCount = 0;
|
|
1801
|
-
const chunkProgress = logger.progress(`Embedding chunks for ${url}`, chunks.length);
|
|
1802
1823
|
for (let i = 0; i < chunks.length; i++) {
|
|
1803
1824
|
const chunk = chunks[i];
|
|
1804
1825
|
const chunkHash = newHashes[i];
|
|
1805
1826
|
const chunkId = chunk.metadata.chunk_id.substring(0, 8) + '...';
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
if (dbConnection.type === 'sqlite') {
|
|
1810
|
-
database_1.DatabaseManager.insertVectorsSQLite(dbConnection.db, chunk, embedding, logger, chunkHash);
|
|
1811
|
-
chunkProgress.update(1, `Stored chunk ${chunkId} in SQLite`);
|
|
1812
|
-
}
|
|
1813
|
-
else if (dbConnection.type === 'qdrant') {
|
|
1814
|
-
await database_1.DatabaseManager.storeChunkInQdrant(dbConnection, chunk, embedding, chunkHash);
|
|
1815
|
-
chunkProgress.update(1, `Stored chunk ${chunkId} in Qdrant (${dbConnection.collectionName})`);
|
|
1816
|
-
}
|
|
1817
|
-
embeddedCount++;
|
|
1827
|
+
if (dbConnection.type === 'sqlite') {
|
|
1828
|
+
database_1.DatabaseManager.insertVectorsSQLite(dbConnection.db, chunk, embedded[i], logger, chunkHash);
|
|
1829
|
+
logger.debug(`Stored chunk ${chunkId} in SQLite`);
|
|
1818
1830
|
}
|
|
1819
|
-
else {
|
|
1820
|
-
|
|
1821
|
-
|
|
1831
|
+
else if (dbConnection.type === 'qdrant') {
|
|
1832
|
+
await database_1.DatabaseManager.storeChunkInQdrant(dbConnection, chunk, embedded[i], chunkHash);
|
|
1833
|
+
logger.debug(`Stored chunk ${chunkId} in Qdrant (${dbConnection.collectionName})`);
|
|
1822
1834
|
}
|
|
1823
1835
|
}
|
|
1824
1836
|
chunkProgress.complete();
|
|
1825
|
-
this.counters.chunks_added +=
|
|
1826
|
-
return
|
|
1837
|
+
this.counters.chunks_added += chunks.length;
|
|
1838
|
+
return chunks.length;
|
|
1827
1839
|
}
|
|
1828
1840
|
async createEmbeddings(texts) {
|
|
1829
1841
|
const logger = this.logger.child('embeddings');
|
|
@@ -1852,6 +1864,12 @@ class Doc2Vec {
|
|
|
1852
1864
|
}
|
|
1853
1865
|
catch (error) {
|
|
1854
1866
|
logger.error('Failed to create embeddings:', error);
|
|
1867
|
+
// An auth rejection is permanent: every later request in this run
|
|
1868
|
+
// fails the same way, so abort the source instead of returning []
|
|
1869
|
+
// and letting each chunk degrade into a logged-and-skipped failure.
|
|
1870
|
+
if (error?.status === 401 || error?.status === 403) {
|
|
1871
|
+
throw new types_1.FatalEmbeddingError(`embedding request rejected with HTTP ${error.status}: ${error?.message ?? error}`);
|
|
1872
|
+
}
|
|
1855
1873
|
return [];
|
|
1856
1874
|
}
|
|
1857
1875
|
}
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FatalEmbeddingError = void 0;
|
|
3
4
|
exports.newSourceRunCounters = newSourceRunCounters;
|
|
5
|
+
// A permanent embedding failure (e.g. an invalid API key): every subsequent
|
|
6
|
+
// request in the run would fail identically, so callers must abort the source
|
|
7
|
+
// instead of degrading each chunk into a logged-and-skipped failure.
|
|
8
|
+
class FatalEmbeddingError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = 'FatalEmbeddingError';
|
|
12
|
+
Object.setPrototypeOf(this, FatalEmbeddingError.prototype);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.FatalEmbeddingError = FatalEmbeddingError;
|
|
4
16
|
function newSourceRunCounters(itemsKind) {
|
|
5
17
|
return {
|
|
6
18
|
items_kind: itemsKind,
|
|
@@ -52,7 +52,7 @@ ${e.slice(l+1)}`:c+=e.slice(i),c.slice(1)}function u7(e){let t="",n=0;for(let r=
|
|
|
52
52
|
`:" ";r+=`---${p}${d}
|
|
53
53
|
`}else r+=La(n,0,l.contents,{block:!0,compact:!0})+`
|
|
54
54
|
`;i=l.explicitEnd||l.contents!==null&&p7(l.contents),i&&(r+=`...
|
|
55
|
-
`)}return r}var v7=WW.withTags({...U1,resolve:(e,t,n)=>{const r=U1.resolve(e,t,n);return r===Ke?PL.resolve(e,t,n):r}},{...H1,resolve:(e,t,n)=>{const r=H1.resolve(e,t,n);return r===Ke?_L.resolve(e,t,n):r}}),y7={...vO,schema:v7,skipInvalid:!1,noRefs:!1,flowLevel:-1,transform:()=>{}};function b7(e,t={}){const n={...y7,...t},r=IV(e,n.schema,{noRefs:n.noRefs,skipInvalid:n.skipInvalid});return n.flowLevel>=0&&zV(r,(i,a)=>{if(!(a.depth<n.flowLevel))return i.style.flow=!0,VL}),n.transform(r),g7(r,{...F1(n,Object.keys(vO)),schema:n.schema})}const RM=[{key:"product_name",label:"Product name",type:"string",required:!0,placeholder:"istio",help:"Stored in chunk metadata; used to identify the source"},{key:"version",label:"Version",type:"string",required:!0,placeholder:"latest",help:"Required for all types except code (defaults to branch)"},{key:"max_size",label:"Max page size (bytes)",type:"number",placeholder:"1048576",help:"Pages/files larger than this are skipped"}],zp={website:{label:"Website",fields:[{key:"url",label:"Base URL",type:"string",required:!0,placeholder:"https://docs.example.com/"},{key:"sitemap_url",label:"Sitemap URL",type:"string",placeholder:"https://docs.example.com/sitemap.xml",help:"Discovers pages not linked in navigation; lastmod dates enable cheap change detection"},{key:"markdown_store",label:"Store markdown in Postgres",type:"boolean",help:"Requires the top-level markdown store to be configured"}]},github:{label:"GitHub issues",fields:[{key:"repo",label:"Repository",type:"string",required:!0,placeholder:"owner/repo"},{key:"start_date",label:"Start date",type:"string",placeholder:"2025-01-01",help:"Only issues updated after this date (first run)"}]},local_directory:{label:"Local directory",fields:[{key:"path",label:"Directory path",type:"string",required:!0,placeholder:"/data/docs"},{key:"include_extensions",label:"Include extensions",type:"string_list",placeholder:".md, .txt, .pdf"},{key:"exclude_extensions",label:"Exclude extensions",type:"string_list",placeholder:".log, .tmp"},{key:"recursive",label:"Recurse into subdirectories",type:"boolean"},{key:"encoding",label:"File encoding",type:"string",placeholder:"utf8"},{key:"url_rewrite_prefix",label:"URL rewrite prefix",type:"string",placeholder:"https://mydomain.com",help:"Rewrites file:// URLs in chunk metadata"}]},zendesk:{label:"Zendesk",fields:[{key:"zendesk_subdomain",label:"Subdomain",type:"string",required:!0,placeholder:"mycompany",help:"mycompany.zendesk.com"},{key:"email",label:"User email",type:"string",required:!0,placeholder:"agent@company.com"},{key:"api_token",label:"API token",type:"string",required:!0,secret:!0,placeholder:"${ZENDESK_API_TOKEN}"},{key:"fetch_tickets",label:"Fetch tickets",type:"boolean"},{key:"fetch_articles",label:"Fetch help center articles",type:"boolean"},{key:"start_date",label:"Start date",type:"string",placeholder:"2025-01-01"},{key:"ticket_status",label:"Ticket statuses",type:"string_list",placeholder:"new, open, pending, hold, solved"},{key:"ticket_priority",label:"Ticket priorities",type:"string_list",placeholder:"urgent, high"},{key:"excluded_organizations",label:"Excluded organizations",type:"string_list"},{key:"include_internal_comments",label:"Include internal comments",type:"boolean"}]},code:{label:"Code",fields:[{key:"source",label:"Code source",type:"select",required:!0,options:["github","local_directory"]},{key:"repo",label:"Repository",type:"string",placeholder:"owner/repo",help:"When source is github"},{key:"branch",label:"Branch",type:"string",placeholder:"main",help:"When source is github"},{key:"path",label:"Directory path",type:"string",placeholder:"/data/src",help:"When source is local_directory"},{key:"include_extensions",label:"Include extensions",type:"string_list",placeholder:".ts, .go, .py"},{key:"exclude_extensions",label:"Exclude extensions",type:"string_list"},{key:"recursive",label:"Recurse into subdirectories",type:"boolean"},{key:"chunk_size",label:"Chunk size (tokens)",type:"number",placeholder:"1500"},{key:"url_rewrite_prefix",label:"URL rewrite prefix",type:"string"}]},s3:{label:"S3 bucket",fields:[{key:"bucket",label:"Bucket",type:"string",required:!0,placeholder:"my-docs-bucket"},{key:"prefix",label:"Key prefix",type:"string",placeholder:"docs/"},{key:"region",label:"Region",type:"string",placeholder:"us-east-1"},{key:"endpoint",label:"Custom endpoint",type:"string",placeholder:"https://minio.local:9000",help:"For S3-compatible services (MinIO, LocalStack)"},{key:"include_extensions",label:"Include extensions",type:"string_list",placeholder:".md, .txt, .pdf"},{key:"exclude_extensions",label:"Exclude extensions",type:"string_list"},{key:"encoding",label:"Text encoding",type:"string",placeholder:"utf8"},{key:"url_rewrite_prefix",label:"URL rewrite prefix",type:"string",help:"Rewrites s3:// URLs in chunk metadata"}]}},mx={sqlite:{label:"SQLite (sqlite-vec)",fields:[{key:"db_path",label:"Database file",type:"string",placeholder:"./my-product.db"}]},qdrant:{label:"Qdrant",fields:[{key:"qdrant_url",label:"Qdrant URL",type:"string",placeholder:"http://localhost"},{key:"qdrant_port",label:"Port",type:"number",placeholder:"6333"},{key:"collection_name",label:"Collection",type:"string",placeholder:"my-product"}]}},jM={openai:{label:"OpenAI (or compatible)",fields:[{key:"api_key",label:"API key",type:"string",secret:!0,placeholder:"${OPENAI_API_KEY}",help:"Falls back to the OPENAI_API_KEY env var"},{key:"model",label:"Model",type:"string",placeholder:"text-embedding-3-large"},{key:"base_url",label:"Base URL",type:"string",placeholder:"http://localhost:11434/v1",help:"For Ollama or other OpenAI-compatible endpoints"}]},azure:{label:"Azure OpenAI",fields:[{key:"api_key",label:"API key",type:"string",secret:!0,placeholder:"${AZURE_OPENAI_KEY}"},{key:"endpoint",label:"Endpoint",type:"string",placeholder:"https://myresource.openai.azure.com"},{key:"deployment_name",label:"Deployment name",type:"string",placeholder:"text-embedding-3-large"},{key:"api_version",label:"API version",type:"string",placeholder:"2024-10-21"}]}},x7=[{key:"connection_string",label:"Connection string",type:"string",secret:!0,placeholder:"postgres://user:${PG_PASSWORD}@host:5432/db",help:"Either this, or the discrete fields below"},{key:"host",label:"Host",type:"string"},{key:"port",label:"Port",type:"number",placeholder:"5432"},{key:"database",label:"Database",type:"string"},{key:"user",label:"User",type:"string"},{key:"password",label:"Password",type:"string",secret:!0,placeholder:"${PG_PASSWORD}"},{key:"table_name",label:"Table name",type:"string",placeholder:"markdown_pages"}];function $p(e){const t={type:e,product_name:"",version:"latest",max_size:1048576};return e==="code"&&delete t.version,t.database_config={type:"sqlite",params:{db_path:""}},t}function S7(e,t){return t.reduce((n,r)=>n?.[r],e)}function iI(e,t,n){if(t.length===0)return n;const[r,...i]=t,a=Array.isArray(e)?[...e??[]]:{...e??{}};return i.length===0?n===void 0||n===""||Array.isArray(n)&&n.length===0?delete a[r]:a[r]=n:a[r]=iI(a[r],i,n),a}const Uo="w-full rounded-md border border-edge bg-page px-3 py-1.5 text-sm outline-none focus:border-accent placeholder:text-ink-muted/60";function gu({field:e,value:t,onChange:n}){const[r,i]=O.useState(null);return e.type==="boolean"?T.jsxs("label",{className:"flex items-center gap-2 py-1.5 text-sm text-ink-secondary",children:[T.jsx("input",{type:"checkbox",checked:!!t,onChange:a=>n(a.target.checked||void 0),className:"h-4 w-4 accent-(--accent)"}),e.label,e.help&&T.jsxs("span",{className:"text-xs text-ink-muted",children:["— ",e.help]})]}):T.jsxs("label",{className:"block",children:[T.jsxs("span",{className:"mb-1 flex items-baseline gap-2 text-xs font-medium text-ink-secondary",children:[e.label,e.required&&T.jsx("span",{className:"text-critical",children:"*"}),e.secret&&T.jsxs("span",{className:"text-ink-muted",children:["use a ",T.jsx("code",{children:"${ENV_VAR}"})," placeholder"]})]}),e.type==="select"?T.jsxs("select",{value:t??"",onChange:a=>n(a.target.value||void 0),className:Uo,children:[T.jsx("option",{value:"",children:"—"}),e.options.map(a=>T.jsx("option",{value:a,children:a},a))]}):e.type==="string_list"?T.jsx("input",{value:r??(Array.isArray(t)?t.join(", "):""),placeholder:e.placeholder,onChange:a=>i(a.target.value),onBlur:()=>{r!==null&&(n(r.split(",").map(a=>a.trim()).filter(Boolean)),i(null))},className:Uo}):T.jsx("input",{type:"text",inputMode:e.type==="number"?"numeric":void 0,value:t??"",placeholder:e.placeholder,onChange:a=>{const l=a.target.value;e.type==="number"?n(l===""?void 0:Number(l)):n(l)},className:Uo}),e.help&&T.jsx("span",{className:"mt-1 block text-xs text-ink-muted",children:e.help})]})}function gx({fields:e,doc:t,basePath:n,onSet:r}){return T.jsx("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:e.map(i=>T.jsx("div",{className:i.type==="boolean"?"sm:col-span-2":"",children:T.jsx(gu,{field:i,value:S7(t,[...n,i.key]),onChange:a=>r([...n,i.key],a)})},i.key))})}function Up({title:e,subtitle:t,action:n,children:r}){return T.jsxs("section",{className:"rounded-lg border border-edge bg-surface p-4",children:[T.jsxs("div",{className:"mb-3 flex items-center gap-2",children:[T.jsx("h3",{className:"text-sm font-semibold",children:e}),t&&T.jsx("span",{className:"text-xs text-ink-muted",children:t}),T.jsx("div",{className:"ml-auto",children:n})]}),r]})}function aI(e){const t=io(),n=O.useMemo(()=>{if(e.mode==="edit"&&e.config)try{const A=RV(e.config.content);return A&&typeof A=="object"?{doc:A,parseError:null}:{doc:null,parseError:"config is not a YAML mapping"}}catch(A){return{doc:null,parseError:A instanceof Error?A.message:String(A)}}return{doc:{name:"",schedule:"",sources:[$p("website")]},parseError:null}},[e.mode,e.config]),[r,i]=O.useState(n.doc),[a,l]=O.useState(""),[s,c]=O.useState(null),f=Uh({mutationFn:async()=>{const A=b7(r,{lineWidth:120,noRefs:!0}),E=await Ct.validateConfig(A);if(!E.valid)throw new oh(400,E.error??"invalid config");if(e.mode==="create"){const k=a.trim()||`${(r.name||"config").toString().replace(/[^A-Za-z0-9._-]+/g,"-")}.yaml`;return Ct.createConfig(k,A)}return Ct.updateConfig(e.config.id,A,e.config.content_hash)},onSuccess:A=>{c(null),t.invalidateQueries({queryKey:["configs"]}),e.onSaved?.(A)},onError:A=>c(A.message)});if(n.parseError||!r)return T.jsxs("p",{className:"rounded-md border border-warning/50 bg-surface px-3 py-2 text-sm text-ink-secondary",children:["⚠ This config can't be edited as a form (",n.parseError,") — use the YAML view."]});const d=(A,E)=>i(k=>iI(k,A,E)),p=Array.isArray(r.sources)?r.sources:[],g=[];p.forEach((A,E)=>{const k=zp[A?.type];for(const M of[...RM,...k?.fields??[]]){if(!M.required||A?.type==="code"&&M.key==="version")continue;const P=A?.[M.key];(P===void 0||P==="")&&g.push(`source ${E+1}: ${M.label}`)}});const v=r.embedding!==void 0,y=r.markdown_store!==void 0,x=f.error instanceof oh&&f.error.status===409,w=r.schedule??"";return T.jsxs("div",{className:"space-y-4",children:[x&&T.jsx("div",{className:"rounded-md border border-warning/50 bg-surface px-3 py-2 text-sm text-ink-secondary",children:"⚠ The file changed on disk since you loaded it. Reload the page and reapply your edits."}),s&&!x&&T.jsx("div",{className:"rounded-md border border-critical/50 bg-surface px-3 py-2 text-sm text-critical",children:s}),T.jsx(Up,{title:"General",children:T.jsxs("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:[e.mode==="create"&&T.jsxs("label",{className:"block",children:[T.jsx("span",{className:"mb-1 block text-xs font-medium text-ink-secondary",children:"Filename"}),T.jsx("input",{value:a,onChange:A=>l(A.target.value),placeholder:`${(r.name||"my-config").toString().replace(/[^A-Za-z0-9._-]+/g,"-")}.yaml`,className:`${Uo} font-mono`})]}),T.jsx(gu,{field:{key:"name",label:"Display name",type:"string",placeholder:"product-docs"},value:r.name,onChange:A=>d(["name"],A)}),T.jsxs("div",{children:[T.jsx(gu,{field:{key:"schedule",label:"Schedule (cron)",type:"string",placeholder:"0 2 * * *",help:"Leave empty for manual runs only"},value:w,onChange:A=>d(["schedule"],A)}),w&&T.jsx("p",{className:"mt-1 text-xs text-accent",children:sO(w)})]})]})}),p.map((A,E)=>{const k=zp[A?.type]??zp.website,M=A?.database_config?.type??"sqlite",P=mx[M]??mx.sqlite;return T.jsx(Up,{title:`Source ${E+1}`,subtitle:A?.product_name||void 0,action:T.jsx("button",{onClick:()=>d(["sources"],p.filter((D,N)=>N!==E)),className:"text-xs text-ink-muted transition hover:text-critical",children:"Remove"}),children:T.jsxs("div",{className:"space-y-4",children:[T.jsxs("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:[T.jsxs("label",{className:"block",children:[T.jsx("span",{className:"mb-1 block text-xs font-medium text-ink-secondary",children:"Type"}),T.jsx("select",{value:A?.type??"website",onChange:D=>{const N={...$p(D.target.value),product_name:A?.product_name??"",...A?.version!==void 0&&D.target.value!=="code"&&{version:A.version},...A?.max_size!==void 0&&{max_size:A.max_size},database_config:A?.database_config??$p(D.target.value).database_config};d(["sources",E],N)},className:Uo,children:Object.entries(zp).map(([D,N])=>T.jsx("option",{value:D,children:N.label},D))})]}),RM.map(D=>T.jsx(gu,{field:A?.type==="code"&&D.key==="version"?{...D,required:!1,help:"Defaults to the branch name"}:D,value:A?.[D.key],onChange:N=>d(["sources",E,D.key],N)},D.key))]}),T.jsxs("div",{children:[T.jsxs("p",{className:"mb-2 text-xs font-semibold uppercase tracking-wide text-ink-muted",children:[k.label," options"]}),T.jsx(gx,{fields:k.fields,doc:r,basePath:["sources",E],onSet:d})]}),T.jsxs("div",{children:[T.jsx("p",{className:"mb-2 text-xs font-semibold uppercase tracking-wide text-ink-muted",children:"Vector database"}),T.jsxs("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:[T.jsxs("label",{className:"block",children:[T.jsx("span",{className:"mb-1 block text-xs font-medium text-ink-secondary",children:"Type"}),T.jsx("select",{value:M,onChange:D=>d(["sources",E,"database_config"],{type:D.target.value,params:{}}),className:Uo,children:Object.entries(mx).map(([D,N])=>T.jsx("option",{value:D,children:N.label},D))})]}),P.fields.map(D=>T.jsx(gu,{field:D,value:A?.database_config?.params?.[D.key],onChange:N=>d(["sources",E,"database_config","params",D.key],N)},D.key))]})]})]})},E)}),T.jsx("button",{onClick:()=>d(["sources"],[...p,$p("website")]),className:"w-full rounded-lg border border-dashed border-edge py-2.5 text-sm font-medium text-ink-muted transition hover:border-accent hover:text-accent",children:"+ Add source"}),T.jsx(Up,{title:"Embedding",subtitle:"optional — defaults to OpenAI text-embedding-3-large",action:T.jsxs("label",{className:"flex items-center gap-2 text-xs text-ink-secondary",children:[T.jsx("input",{type:"checkbox",checked:v,onChange:A=>d(["embedding"],A.target.checked?{provider:"openai"}:void 0),className:"h-4 w-4 accent-(--accent)"}),"customize"]}),children:v?T.jsxs("div",{className:"space-y-3",children:[T.jsxs("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:[T.jsxs("label",{className:"block",children:[T.jsx("span",{className:"mb-1 block text-xs font-medium text-ink-secondary",children:"Provider"}),T.jsx("select",{value:r.embedding?.provider??"openai",onChange:A=>d(["embedding"],{provider:A.target.value}),className:Uo,children:Object.entries(jM).map(([A,E])=>T.jsx("option",{value:A,children:E.label},A))})]}),T.jsx(gu,{field:{key:"dimension",label:"Dimension",type:"number",placeholder:"3072"},value:r.embedding?.dimension,onChange:A=>d(["embedding","dimension"],A)})]}),T.jsx(gx,{fields:jM[r.embedding?.provider??"openai"].fields,doc:r,basePath:["embedding",r.embedding?.provider??"openai"],onSet:d})]}):T.jsx("p",{className:"text-xs text-ink-muted",children:"Using defaults (OPENAI_API_KEY env var, text-embedding-3-large, 3072 dimensions)."})}),T.jsx(Up,{title:"Markdown store",subtitle:"optional — store crawled markdown in Postgres",action:T.jsxs("label",{className:"flex items-center gap-2 text-xs text-ink-secondary",children:[T.jsx("input",{type:"checkbox",checked:y,onChange:A=>d(["markdown_store"],A.target.checked?{}:void 0),className:"h-4 w-4 accent-(--accent)"}),"enable"]}),children:y?T.jsx(gx,{fields:x7,doc:r,basePath:["markdown_store"],onSet:d}):T.jsx("p",{className:"text-xs text-ink-muted",children:"Disabled."})}),T.jsxs("div",{className:"flex items-center gap-3",children:[T.jsx("button",{onClick:()=>f.mutate(),disabled:f.isPending||p.length===0||g.length>0,className:"rounded-md bg-accent px-4 py-2 text-sm font-medium text-white transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40",children:f.isPending?"Saving…":e.mode==="create"?"Create config":"Save changes"}),e.onCancel&&T.jsx("button",{onClick:e.onCancel,className:"text-sm text-ink-muted hover:text-ink-secondary",children:"Cancel"}),g.length>0&&T.jsxs("span",{className:"text-xs text-warning",children:["missing: ",g.slice(0,3).join(", "),g.length>3?"…":""]}),p.length===0&&T.jsx("span",{className:"text-xs text-warning",children:"add at least one source"}),e.mode==="edit"&&T.jsx("span",{className:"ml-auto text-xs text-ink-muted",children:"Saving rewrites the YAML file (comments are not preserved)."})]})]})}function lI({config:e,variant:t="subtle"}){const n=io(),[r,i]=O.useState(!1),[a,l]=O.useState(new Set),[s,c]=O.useState(""),f=Uh({mutationFn:k=>Ct.triggerRun(e.id,k,e.content_hash),onSuccess:()=>{i(!1),l(new Set),c("")},onSettled:()=>n.invalidateQueries({queryKey:["configs"]})}),d=O.useMemo(()=>e.source_summary.map((k,M)=>({...k,index:M})),[e.source_summary]),p=O.useMemo(()=>{const k=s.trim().toLowerCase();return k?d.filter(M=>M.product_name.toLowerCase().includes(k)||M.type.toLowerCase().includes(k)):d},[d,s]),g=e.busy||!!e.parse_error||f.isPending,v=k=>{k.preventDefault(),k.stopPropagation()},y=k=>{l(M=>{const P=new Set(M);return P.has(k)?P.delete(k):P.add(k),P})},x=p.length>0&&p.every(k=>a.has(k.index)),w=()=>{l(k=>{const M=new Set(k);return x?p.forEach(P=>M.delete(P.index)):p.forEach(P=>M.add(P.index)),M})},A=t==="primary"?"bg-accent text-white transition hover:opacity-90 px-3.5 py-1.5 text-sm font-medium":"border border-edge bg-surface text-ink-secondary transition hover:border-accent hover:text-accent px-3 py-1 text-xs font-medium",E=t==="primary"?"bg-accent text-white transition hover:opacity-90 border-l border-white/25 px-2 py-1.5 text-sm":"border border-l-0 border-edge bg-surface text-ink-secondary transition hover:border-accent hover:text-accent px-1.5 py-1 text-xs";return T.jsxs("div",{className:"relative inline-flex items-center gap-2",onClick:v,children:[T.jsxs("span",{className:"inline-flex",children:[T.jsx("button",{onClick:k=>{v(k),f.mutate(void 0)},disabled:g,className:`${d.length>1?"rounded-l-md":"rounded-md"} ${A} disabled:cursor-not-allowed disabled:opacity-40`,children:e.busy?"Running…":"Run now"}),d.length>1&&T.jsx("button",{onClick:k=>{v(k),i(M=>!M)},disabled:g,"aria-label":"Choose sources to run",title:"Choose sources to run",className:`rounded-r-md ${E} disabled:cursor-not-allowed disabled:opacity-40`,children:"▾"})]}),f.error&&T.jsx("span",{className:"text-xs text-critical",children:f.error.message}),r&&T.jsxs(T.Fragment,{children:[T.jsx("div",{className:"fixed inset-0 z-10",onClick:k=>{v(k),i(!1)}}),T.jsxs("div",{className:"absolute right-0 top-full z-20 mt-1.5 w-80 rounded-md border border-edge bg-surface shadow-lg",children:[T.jsxs("div",{className:"flex items-center justify-between border-b border-edge px-3 py-2",children:[T.jsxs("span",{className:"text-xs font-semibold uppercase tracking-wide text-ink-muted",children:["Run sources",a.size>0&&` (${a.size}/${d.length})`]}),T.jsxs("button",{onClick:k=>{v(k),w()},className:"text-xs text-accent hover:underline",children:[x?"Clear":"Select all",s.trim()&&" shown"]})]}),d.length>8&&T.jsx("div",{className:"border-b border-edge px-3 py-2",children:T.jsx("input",{type:"text",value:s,onChange:k=>c(k.target.value),onClick:k=>k.stopPropagation(),placeholder:"Filter sources…",className:"w-full rounded-md border border-edge bg-page px-2 py-1 text-xs text-ink-secondary placeholder:text-ink-muted focus:border-accent focus:outline-none"})}),T.jsxs("ul",{className:"max-h-64 overflow-y-auto py-1",children:[p.map(k=>T.jsx("li",{children:T.jsxs("label",{className:"flex cursor-pointer items-center gap-2 px-3 py-1.5 text-sm text-ink-secondary hover:bg-edge/20",onClick:M=>M.stopPropagation(),children:[T.jsx("input",{type:"checkbox",checked:a.has(k.index),onChange:()=>y(k.index),className:"accent-accent"}),T.jsx("span",{className:"truncate",children:k.product_name}),T.jsxs("span",{className:"ml-auto shrink-0 text-xs text-ink-muted",children:[k.type,k.version?` · ${k.version}`:""]})]})},k.index)),p.length===0&&T.jsxs("li",{className:"px-3 py-2 text-xs text-ink-muted",children:["No sources match “",s,"”."]})]}),T.jsx("div",{className:"border-t border-edge px-3 py-2",children:T.jsxs("button",{onClick:k=>{v(k),f.mutate([...a])},disabled:a.size===0||g,className:"w-full rounded-md bg-accent px-3 py-1.5 text-xs font-medium text-white transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40",children:["Run ",a.size>0?`${a.size} selected`:"selected"," source",a.size===1?"":"s"]})})]})]})]})}const w7={website:"🌐",github:"🐙",zendesk:"🎫",local_directory:"📁",code:"⌨️",s3:"🪣"};function oI({sources:e,max:t}){const[n,r]=O.useState(!1);if(e.length===0)return T.jsx("span",{className:"text-xs text-ink-muted",children:"no sources"});const i=n||t===void 0?e.length:t,a=e.slice(0,i),l=e.length-a.length;return T.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[a.map((s,c)=>T.jsxs("span",{title:`${s.type}${s.version?` · ${s.version}`:""}`,className:"inline-flex items-center gap-1 rounded-full border border-edge bg-page px-2 py-0.5 text-xs text-ink-secondary",children:[T.jsx("span",{"aria-hidden":!0,className:"text-[10px]",children:w7[s.type]??"•"}),s.product_name,T.jsx("span",{className:"text-ink-muted",children:s.type})]},`${s.product_name}-${s.type}-${c}`)),l>0&&T.jsxs("button",{onClick:s=>{s.preventDefault(),r(!0)},className:"rounded-full border border-edge px-2 py-0.5 text-xs text-ink-muted transition hover:border-accent hover:text-accent",children:["+",l," more"]})]})}function O7(){const e=Cv(),{data:t,isLoading:n,error:r}=Fi({queryKey:["configs"],queryFn:Ct.configs}),{data:i}=Fi({queryKey:["health"],queryFn:Ct.health}),[a,l]=O.useState(!1),s=t?.filter(c=>c.last_run?.status==="running"||c.last_run?.status==="queued")??[];return n?T.jsx("p",{className:"text-ink-muted",children:"Loading…"}):r?T.jsxs("p",{className:"text-critical",children:["Failed to load configs: ",String(r.message)]}):T.jsxs("div",{className:"space-y-6",children:[s.length>0&&T.jsx("div",{className:"rounded-lg border border-accent/30 bg-surface px-4 py-3",children:T.jsxs("p",{className:"text-sm text-ink-secondary",children:[T.jsxs("span",{className:"font-medium text-accent",children:["● ",s.length," config",s.length>1?"s":""," syncing now"]})," — ",s.map((c,f)=>T.jsxs("span",{children:[f>0&&", ",T.jsx(gi,{to:`/runs/${c.last_run.id}`,className:"text-accent hover:underline",children:c.name})]},c.id))]})}),T.jsxs("div",{className:"flex items-center justify-between",children:[T.jsx("h1",{className:"text-xl font-semibold tracking-tight",children:"Configurations"}),i?.mode==="rw"&&T.jsx("button",{onClick:()=>l(!0),className:"rounded-md bg-accent px-3.5 py-1.5 text-sm font-medium text-white transition hover:opacity-90",children:"New config"})]}),a&&T.jsxs("div",{className:"rounded-lg border border-edge bg-page p-4",children:[T.jsx("h2",{className:"mb-4 text-sm font-semibold",children:"Create a new config"}),T.jsx(aI,{mode:"create",onSaved:c=>{l(!1),e(`/configs/${c.id}`)},onCancel:()=>l(!1)})]}),t&&t.length===0&&T.jsxs("p",{className:"rounded-lg border border-edge bg-surface px-4 py-8 text-center text-sm text-ink-muted",children:["No configs loaded. Pass config files to ",T.jsx("code",{className:"text-ink-secondary",children:"doc2vec controller"}),i?.mode==="rw"&&" or create one with the button above","."]}),T.jsx("div",{className:"grid gap-4",children:t?.map(c=>T.jsx(gi,{to:`/configs/${c.id}`,className:"block rounded-lg border border-edge bg-surface p-4 transition hover:border-accent/50",children:T.jsxs("div",{className:"flex flex-col gap-3 md:grid md:grid-cols-[minmax(9rem,1fr)_12rem_15rem_8rem_auto] md:items-start md:gap-x-6",children:[T.jsxs("div",{className:"min-w-0",children:[T.jsxs("div",{className:"flex items-center gap-2",children:[T.jsx("h2",{className:"truncate font-semibold",children:c.name}),c.parse_error&&T.jsx("span",{className:"shrink-0 rounded-full border border-critical/40 px-2 py-0.5 text-xs text-critical",title:c.parse_error,children:"invalid"})]}),T.jsx("div",{className:"mt-1.5",children:T.jsx(oI,{sources:c.source_summary,max:4})})]}),T.jsxs("div",{className:"text-sm",children:[T.jsx("p",{className:"text-xs uppercase tracking-wide text-ink-muted",children:"Schedule"}),T.jsx("p",{className:"mt-0.5 text-ink-secondary",title:c.schedule??void 0,children:sO(c.schedule)})]}),T.jsxs("div",{className:"text-sm",children:[T.jsx("p",{className:"text-xs uppercase tracking-wide text-ink-muted",children:"Last run"}),T.jsx("div",{className:"mt-0.5 flex flex-wrap items-center gap-2",children:c.last_run?T.jsxs(T.Fragment,{children:[T.jsx(Mv,{status:c.last_run.status}),T.jsxs("span",{className:"text-xs text-ink-muted",title:Ua(c.last_run.queued_at),children:[$1(c.last_run.finished_at??c.last_run.queued_at),c.last_run.finished_at&&c.last_run.started_at&&` · ${oO(c.last_run.started_at,c.last_run.finished_at)}`]})]}):T.jsx("span",{className:"text-xs text-ink-muted",children:"never"})})]}),T.jsxs("div",{className:"text-sm",children:[T.jsx("p",{className:"text-xs uppercase tracking-wide text-ink-muted",children:"Next run"}),T.jsx("p",{className:"mt-0.5 text-ink-secondary",title:c.next_run?Ua(c.next_run):void 0,children:c.next_run?$1(c.next_run):"—"})]}),T.jsx("div",{className:"md:self-center",children:T.jsx(lI,{config:c})})]})},c.id))})]})}function G1(){return G1=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},G1.apply(null,arguments)}function A7(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}let Z1=[],sI=[];(()=>{let e="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(t=>t?parseInt(t,36):1);for(let t=0,n=0;t<e.length;t++)(t%2?sI:Z1).push(n=n+e[t])})();function k7(e){if(e<768)return!1;for(let t=0,n=Z1.length;;){let r=t+n>>1;if(e<Z1[r])n=r;else if(e>=sI[r])t=r+1;else return!0;if(t==n)return!1}}function LM(e){return e>=127462&&e<=127487}const IM=8205;function C7(e,t,n=!0,r=!0){return(n?uI:E7)(e,t,r)}function uI(e,t,n){if(t==e.length)return t;t&&cI(e.charCodeAt(t))&&fI(e.charCodeAt(t-1))&&t--;let r=vx(e,t);for(t+=BM(r);t<e.length;){let i=vx(e,t);if(r==IM||i==IM||n&&k7(i))t+=BM(i),r=i;else if(LM(i)){let a=0,l=t-2;for(;l>=0&&LM(vx(e,l));)a++,l-=2;if(a%2==0)break;t+=2}else break}return t}function E7(e,t,n){for(;t>1;){let r=uI(e,t-2,n);if(r<t)return r;t--}return 0}function vx(e,t){let n=e.charCodeAt(t);if(!fI(n)||t+1==e.length)return n;let r=e.charCodeAt(t+1);return cI(r)?(n-55296<<10)+(r-56320)+65536:n}function cI(e){return e>=56320&&e<57344}function fI(e){return e>=55296&&e<56320}function BM(e){return e<65536?1:2}let Je=class hI{lineAt(t){if(t<0||t>this.length)throw new RangeError(`Invalid position ${t} in document of length ${this.length}`);return this.lineInner(t,!1,1,0)}line(t){if(t<1||t>this.lines)throw new RangeError(`Invalid line number ${t} in ${this.lines}-line document`);return this.lineInner(t,!0,1,0)}replace(t,n,r){[t,n]=Fu(this,t,n);let i=[];return this.decompose(0,t,i,2),r.length&&r.decompose(0,r.length,i,3),this.decompose(n,this.length,i,1),$i.from(i,this.length-(n-t)+r.length)}append(t){return this.replace(this.length,this.length,t)}slice(t,n=this.length){[t,n]=Fu(this,t,n);let r=[];return this.decompose(t,n,r,0),$i.from(r,n-t)}eq(t){if(t==this)return!0;if(t.length!=this.length||t.lines!=this.lines)return!1;let n=this.scanIdentical(t,1),r=this.length-this.scanIdentical(t,-1),i=new Kf(this),a=new Kf(t);for(let l=n,s=n;;){if(i.next(l),a.next(l),l=0,i.lineBreak!=a.lineBreak||i.done!=a.done||i.value!=a.value)return!1;if(s+=i.value.length,i.done||s>=r)return!0}}iter(t=1){return new Kf(this,t)}iterRange(t,n=this.length){return new dI(this,t,n)}iterLines(t,n){let r;if(t==null)r=this.iter();else{n==null&&(n=this.lines+1);let i=this.line(t).from;r=this.iterRange(i,Math.max(i,n==this.lines+1?this.length:n<=1?0:this.line(n-1).to))}return new pI(r)}toString(){return this.sliceString(0)}toJSON(){let t=[];return this.flatten(t),t}constructor(){}static of(t){if(t.length==0)throw new RangeError("A document must have at least one line");return t.length==1&&!t[0]?hI.empty:t.length<=32?new It(t):$i.from(It.split(t,[]))}};class It extends Je{constructor(t,n=T7(t)){super(),this.text=t,this.length=n}get lines(){return this.text.length}get children(){return null}lineInner(t,n,r,i){for(let a=0;;a++){let l=this.text[a],s=i+l.length;if((n?r:s)>=t)return new M7(i,s,r,l);i=s+1,r++}}decompose(t,n,r,i){let a=t<=0&&n>=this.length?this:new It(zM(this.text,t,n),Math.min(n,this.length)-Math.max(0,t));if(i&1){let l=r.pop(),s=Rm(a.text,l.text.slice(),0,a.length);if(s.length<=32)r.push(new It(s,l.length+a.length));else{let c=s.length>>1;r.push(new It(s.slice(0,c)),new It(s.slice(c)))}}else r.push(a)}replace(t,n,r){if(!(r instanceof It))return super.replace(t,n,r);[t,n]=Fu(this,t,n);let i=Rm(this.text,Rm(r.text,zM(this.text,0,t)),n),a=this.length+r.length-(n-t);return i.length<=32?new It(i,a):$i.from(It.split(i,[]),a)}sliceString(t,n=this.length,r=`
|
|
55
|
+
`)}return r}var v7=WW.withTags({...U1,resolve:(e,t,n)=>{const r=U1.resolve(e,t,n);return r===Ke?PL.resolve(e,t,n):r}},{...H1,resolve:(e,t,n)=>{const r=H1.resolve(e,t,n);return r===Ke?_L.resolve(e,t,n):r}}),y7={...vO,schema:v7,skipInvalid:!1,noRefs:!1,flowLevel:-1,transform:()=>{}};function b7(e,t={}){const n={...y7,...t},r=IV(e,n.schema,{noRefs:n.noRefs,skipInvalid:n.skipInvalid});return n.flowLevel>=0&&zV(r,(i,a)=>{if(!(a.depth<n.flowLevel))return i.style.flow=!0,VL}),n.transform(r),g7(r,{...F1(n,Object.keys(vO)),schema:n.schema})}const RM=[{key:"product_name",label:"Product name",type:"string",required:!0,placeholder:"istio",help:"Stored in chunk metadata; used to identify the source"},{key:"version",label:"Version",type:"string",required:!0,placeholder:"latest",help:"Required for all types except code (defaults to branch)"},{key:"max_size",label:"Max page size (bytes)",type:"number",placeholder:"1048576",help:"Pages/files larger than this are skipped"}],zp={website:{label:"Website",fields:[{key:"url",label:"Base URL",type:"string",required:!0,placeholder:"https://docs.example.com/"},{key:"sitemap_url",label:"Sitemap URL",type:"string",placeholder:"https://docs.example.com/sitemap.xml",help:"Discovers pages not linked in navigation; lastmod dates enable cheap change detection"},{key:"markdown_store",label:"Store markdown in Postgres",type:"boolean",help:"Requires the top-level markdown store to be configured"}]},github:{label:"GitHub issues",fields:[{key:"repo",label:"Repository",type:"string",required:!0,placeholder:"owner/repo"},{key:"start_date",label:"Start date",type:"string",placeholder:"2025-01-01",help:"Only issues updated after this date (first run)"}]},local_directory:{label:"Local directory",fields:[{key:"path",label:"Directory path",type:"string",required:!0,placeholder:"/data/docs"},{key:"include_extensions",label:"Include extensions",type:"string_list",placeholder:".md, .txt, .pdf"},{key:"exclude_extensions",label:"Exclude extensions",type:"string_list",placeholder:".log, .tmp"},{key:"recursive",label:"Recurse into subdirectories",type:"boolean"},{key:"encoding",label:"File encoding",type:"string",placeholder:"utf8"},{key:"url_rewrite_prefix",label:"URL rewrite prefix",type:"string",placeholder:"https://mydomain.com",help:"Rewrites file:// URLs in chunk metadata"}]},zendesk:{label:"Zendesk",fields:[{key:"zendesk_subdomain",label:"Subdomain",type:"string",required:!0,placeholder:"mycompany",help:"mycompany.zendesk.com"},{key:"email",label:"User email",type:"string",required:!0,placeholder:"agent@company.com"},{key:"api_token",label:"API token",type:"string",required:!0,secret:!0,placeholder:"${ZENDESK_API_TOKEN}"},{key:"fetch_tickets",label:"Fetch tickets",type:"boolean"},{key:"fetch_articles",label:"Fetch help center articles",type:"boolean"},{key:"start_date",label:"Start date",type:"string",placeholder:"2025-01-01"},{key:"ticket_status",label:"Ticket statuses",type:"string_list",placeholder:"new, open, pending, hold, solved"},{key:"ticket_priority",label:"Ticket priorities",type:"string_list",placeholder:"urgent, high"},{key:"excluded_organizations",label:"Excluded organizations",type:"string_list"},{key:"include_internal_comments",label:"Include internal comments",type:"boolean"}]},code:{label:"Code",fields:[{key:"source",label:"Code source",type:"select",required:!0,options:["github","local_directory"]},{key:"repo",label:"Repository",type:"string",placeholder:"owner/repo",help:"When source is github"},{key:"branch",label:"Branch",type:"string",placeholder:"main",help:"When source is github"},{key:"path",label:"Directory path",type:"string",placeholder:"/data/src",help:"When source is local_directory"},{key:"include_extensions",label:"Include extensions",type:"string_list",placeholder:".ts, .go, .py"},{key:"exclude_extensions",label:"Exclude extensions",type:"string_list"},{key:"exclude_paths",label:"Exclude paths",type:"string_list",placeholder:"vendor/**, **/*_test.go",help:"Glob patterns relative to the source root"},{key:"recursive",label:"Recurse into subdirectories",type:"boolean"},{key:"chunk_size",label:"Chunk size (tokens)",type:"number",placeholder:"1500"},{key:"url_rewrite_prefix",label:"URL rewrite prefix",type:"string"}]},s3:{label:"S3 bucket",fields:[{key:"bucket",label:"Bucket",type:"string",required:!0,placeholder:"my-docs-bucket"},{key:"prefix",label:"Key prefix",type:"string",placeholder:"docs/"},{key:"region",label:"Region",type:"string",placeholder:"us-east-1"},{key:"endpoint",label:"Custom endpoint",type:"string",placeholder:"https://minio.local:9000",help:"For S3-compatible services (MinIO, LocalStack)"},{key:"include_extensions",label:"Include extensions",type:"string_list",placeholder:".md, .txt, .pdf"},{key:"exclude_extensions",label:"Exclude extensions",type:"string_list"},{key:"encoding",label:"Text encoding",type:"string",placeholder:"utf8"},{key:"url_rewrite_prefix",label:"URL rewrite prefix",type:"string",help:"Rewrites s3:// URLs in chunk metadata"}]}},mx={sqlite:{label:"SQLite (sqlite-vec)",fields:[{key:"db_path",label:"Database file",type:"string",placeholder:"./my-product.db"}]},qdrant:{label:"Qdrant",fields:[{key:"qdrant_url",label:"Qdrant URL",type:"string",placeholder:"http://localhost"},{key:"qdrant_port",label:"Port",type:"number",placeholder:"6333"},{key:"collection_name",label:"Collection",type:"string",placeholder:"my-product"}]}},jM={openai:{label:"OpenAI (or compatible)",fields:[{key:"api_key",label:"API key",type:"string",secret:!0,placeholder:"${OPENAI_API_KEY}",help:"Falls back to the OPENAI_API_KEY env var"},{key:"model",label:"Model",type:"string",placeholder:"text-embedding-3-large"},{key:"base_url",label:"Base URL",type:"string",placeholder:"http://localhost:11434/v1",help:"For Ollama or other OpenAI-compatible endpoints"}]},azure:{label:"Azure OpenAI",fields:[{key:"api_key",label:"API key",type:"string",secret:!0,placeholder:"${AZURE_OPENAI_KEY}"},{key:"endpoint",label:"Endpoint",type:"string",placeholder:"https://myresource.openai.azure.com"},{key:"deployment_name",label:"Deployment name",type:"string",placeholder:"text-embedding-3-large"},{key:"api_version",label:"API version",type:"string",placeholder:"2024-10-21"}]}},x7=[{key:"connection_string",label:"Connection string",type:"string",secret:!0,placeholder:"postgres://user:${PG_PASSWORD}@host:5432/db",help:"Either this, or the discrete fields below"},{key:"host",label:"Host",type:"string"},{key:"port",label:"Port",type:"number",placeholder:"5432"},{key:"database",label:"Database",type:"string"},{key:"user",label:"User",type:"string"},{key:"password",label:"Password",type:"string",secret:!0,placeholder:"${PG_PASSWORD}"},{key:"table_name",label:"Table name",type:"string",placeholder:"markdown_pages"}];function $p(e){const t={type:e,product_name:"",version:"latest",max_size:1048576};return e==="code"&&delete t.version,t.database_config={type:"sqlite",params:{db_path:""}},t}function S7(e,t){return t.reduce((n,r)=>n?.[r],e)}function iI(e,t,n){if(t.length===0)return n;const[r,...i]=t,a=Array.isArray(e)?[...e??[]]:{...e??{}};return i.length===0?n===void 0||n===""||Array.isArray(n)&&n.length===0?delete a[r]:a[r]=n:a[r]=iI(a[r],i,n),a}const Uo="w-full rounded-md border border-edge bg-page px-3 py-1.5 text-sm outline-none focus:border-accent placeholder:text-ink-muted/60";function gu({field:e,value:t,onChange:n}){const[r,i]=O.useState(null);return e.type==="boolean"?T.jsxs("label",{className:"flex items-center gap-2 py-1.5 text-sm text-ink-secondary",children:[T.jsx("input",{type:"checkbox",checked:!!t,onChange:a=>n(a.target.checked||void 0),className:"h-4 w-4 accent-(--accent)"}),e.label,e.help&&T.jsxs("span",{className:"text-xs text-ink-muted",children:["— ",e.help]})]}):T.jsxs("label",{className:"block",children:[T.jsxs("span",{className:"mb-1 flex items-baseline gap-2 text-xs font-medium text-ink-secondary",children:[e.label,e.required&&T.jsx("span",{className:"text-critical",children:"*"}),e.secret&&T.jsxs("span",{className:"text-ink-muted",children:["use a ",T.jsx("code",{children:"${ENV_VAR}"})," placeholder"]})]}),e.type==="select"?T.jsxs("select",{value:t??"",onChange:a=>n(a.target.value||void 0),className:Uo,children:[T.jsx("option",{value:"",children:"—"}),e.options.map(a=>T.jsx("option",{value:a,children:a},a))]}):e.type==="string_list"?T.jsx("input",{value:r??(Array.isArray(t)?t.join(", "):""),placeholder:e.placeholder,onChange:a=>i(a.target.value),onBlur:()=>{r!==null&&(n(r.split(",").map(a=>a.trim()).filter(Boolean)),i(null))},className:Uo}):T.jsx("input",{type:"text",inputMode:e.type==="number"?"numeric":void 0,value:t??"",placeholder:e.placeholder,onChange:a=>{const l=a.target.value;e.type==="number"?n(l===""?void 0:Number(l)):n(l)},className:Uo}),e.help&&T.jsx("span",{className:"mt-1 block text-xs text-ink-muted",children:e.help})]})}function gx({fields:e,doc:t,basePath:n,onSet:r}){return T.jsx("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:e.map(i=>T.jsx("div",{className:i.type==="boolean"?"sm:col-span-2":"",children:T.jsx(gu,{field:i,value:S7(t,[...n,i.key]),onChange:a=>r([...n,i.key],a)})},i.key))})}function Up({title:e,subtitle:t,action:n,children:r}){return T.jsxs("section",{className:"rounded-lg border border-edge bg-surface p-4",children:[T.jsxs("div",{className:"mb-3 flex items-center gap-2",children:[T.jsx("h3",{className:"text-sm font-semibold",children:e}),t&&T.jsx("span",{className:"text-xs text-ink-muted",children:t}),T.jsx("div",{className:"ml-auto",children:n})]}),r]})}function aI(e){const t=io(),n=O.useMemo(()=>{if(e.mode==="edit"&&e.config)try{const A=RV(e.config.content);return A&&typeof A=="object"?{doc:A,parseError:null}:{doc:null,parseError:"config is not a YAML mapping"}}catch(A){return{doc:null,parseError:A instanceof Error?A.message:String(A)}}return{doc:{name:"",schedule:"",sources:[$p("website")]},parseError:null}},[e.mode,e.config]),[r,i]=O.useState(n.doc),[a,l]=O.useState(""),[s,c]=O.useState(null),f=Uh({mutationFn:async()=>{const A=b7(r,{lineWidth:120,noRefs:!0}),E=await Ct.validateConfig(A);if(!E.valid)throw new oh(400,E.error??"invalid config");if(e.mode==="create"){const k=a.trim()||`${(r.name||"config").toString().replace(/[^A-Za-z0-9._-]+/g,"-")}.yaml`;return Ct.createConfig(k,A)}return Ct.updateConfig(e.config.id,A,e.config.content_hash)},onSuccess:A=>{c(null),t.invalidateQueries({queryKey:["configs"]}),e.onSaved?.(A)},onError:A=>c(A.message)});if(n.parseError||!r)return T.jsxs("p",{className:"rounded-md border border-warning/50 bg-surface px-3 py-2 text-sm text-ink-secondary",children:["⚠ This config can't be edited as a form (",n.parseError,") — use the YAML view."]});const d=(A,E)=>i(k=>iI(k,A,E)),p=Array.isArray(r.sources)?r.sources:[],g=[];p.forEach((A,E)=>{const k=zp[A?.type];for(const M of[...RM,...k?.fields??[]]){if(!M.required||A?.type==="code"&&M.key==="version")continue;const P=A?.[M.key];(P===void 0||P==="")&&g.push(`source ${E+1}: ${M.label}`)}});const v=r.embedding!==void 0,y=r.markdown_store!==void 0,x=f.error instanceof oh&&f.error.status===409,w=r.schedule??"";return T.jsxs("div",{className:"space-y-4",children:[x&&T.jsx("div",{className:"rounded-md border border-warning/50 bg-surface px-3 py-2 text-sm text-ink-secondary",children:"⚠ The file changed on disk since you loaded it. Reload the page and reapply your edits."}),s&&!x&&T.jsx("div",{className:"rounded-md border border-critical/50 bg-surface px-3 py-2 text-sm text-critical",children:s}),T.jsx(Up,{title:"General",children:T.jsxs("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:[e.mode==="create"&&T.jsxs("label",{className:"block",children:[T.jsx("span",{className:"mb-1 block text-xs font-medium text-ink-secondary",children:"Filename"}),T.jsx("input",{value:a,onChange:A=>l(A.target.value),placeholder:`${(r.name||"my-config").toString().replace(/[^A-Za-z0-9._-]+/g,"-")}.yaml`,className:`${Uo} font-mono`})]}),T.jsx(gu,{field:{key:"name",label:"Display name",type:"string",placeholder:"product-docs"},value:r.name,onChange:A=>d(["name"],A)}),T.jsxs("div",{children:[T.jsx(gu,{field:{key:"schedule",label:"Schedule (cron)",type:"string",placeholder:"0 2 * * *",help:"Leave empty for manual runs only"},value:w,onChange:A=>d(["schedule"],A)}),w&&T.jsx("p",{className:"mt-1 text-xs text-accent",children:sO(w)})]})]})}),p.map((A,E)=>{const k=zp[A?.type]??zp.website,M=A?.database_config?.type??"sqlite",P=mx[M]??mx.sqlite;return T.jsx(Up,{title:`Source ${E+1}`,subtitle:A?.product_name||void 0,action:T.jsx("button",{onClick:()=>d(["sources"],p.filter((D,N)=>N!==E)),className:"text-xs text-ink-muted transition hover:text-critical",children:"Remove"}),children:T.jsxs("div",{className:"space-y-4",children:[T.jsxs("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:[T.jsxs("label",{className:"block",children:[T.jsx("span",{className:"mb-1 block text-xs font-medium text-ink-secondary",children:"Type"}),T.jsx("select",{value:A?.type??"website",onChange:D=>{const N={...$p(D.target.value),product_name:A?.product_name??"",...A?.version!==void 0&&D.target.value!=="code"&&{version:A.version},...A?.max_size!==void 0&&{max_size:A.max_size},database_config:A?.database_config??$p(D.target.value).database_config};d(["sources",E],N)},className:Uo,children:Object.entries(zp).map(([D,N])=>T.jsx("option",{value:D,children:N.label},D))})]}),RM.map(D=>T.jsx(gu,{field:A?.type==="code"&&D.key==="version"?{...D,required:!1,help:"Defaults to the branch name"}:D,value:A?.[D.key],onChange:N=>d(["sources",E,D.key],N)},D.key))]}),T.jsxs("div",{children:[T.jsxs("p",{className:"mb-2 text-xs font-semibold uppercase tracking-wide text-ink-muted",children:[k.label," options"]}),T.jsx(gx,{fields:k.fields,doc:r,basePath:["sources",E],onSet:d})]}),T.jsxs("div",{children:[T.jsx("p",{className:"mb-2 text-xs font-semibold uppercase tracking-wide text-ink-muted",children:"Vector database"}),T.jsxs("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:[T.jsxs("label",{className:"block",children:[T.jsx("span",{className:"mb-1 block text-xs font-medium text-ink-secondary",children:"Type"}),T.jsx("select",{value:M,onChange:D=>d(["sources",E,"database_config"],{type:D.target.value,params:{}}),className:Uo,children:Object.entries(mx).map(([D,N])=>T.jsx("option",{value:D,children:N.label},D))})]}),P.fields.map(D=>T.jsx(gu,{field:D,value:A?.database_config?.params?.[D.key],onChange:N=>d(["sources",E,"database_config","params",D.key],N)},D.key))]})]})]})},E)}),T.jsx("button",{onClick:()=>d(["sources"],[...p,$p("website")]),className:"w-full rounded-lg border border-dashed border-edge py-2.5 text-sm font-medium text-ink-muted transition hover:border-accent hover:text-accent",children:"+ Add source"}),T.jsx(Up,{title:"Embedding",subtitle:"optional — defaults to OpenAI text-embedding-3-large",action:T.jsxs("label",{className:"flex items-center gap-2 text-xs text-ink-secondary",children:[T.jsx("input",{type:"checkbox",checked:v,onChange:A=>d(["embedding"],A.target.checked?{provider:"openai"}:void 0),className:"h-4 w-4 accent-(--accent)"}),"customize"]}),children:v?T.jsxs("div",{className:"space-y-3",children:[T.jsxs("div",{className:"grid gap-x-4 gap-y-3 sm:grid-cols-2",children:[T.jsxs("label",{className:"block",children:[T.jsx("span",{className:"mb-1 block text-xs font-medium text-ink-secondary",children:"Provider"}),T.jsx("select",{value:r.embedding?.provider??"openai",onChange:A=>d(["embedding"],{provider:A.target.value}),className:Uo,children:Object.entries(jM).map(([A,E])=>T.jsx("option",{value:A,children:E.label},A))})]}),T.jsx(gu,{field:{key:"dimension",label:"Dimension",type:"number",placeholder:"3072"},value:r.embedding?.dimension,onChange:A=>d(["embedding","dimension"],A)})]}),T.jsx(gx,{fields:jM[r.embedding?.provider??"openai"].fields,doc:r,basePath:["embedding",r.embedding?.provider??"openai"],onSet:d})]}):T.jsx("p",{className:"text-xs text-ink-muted",children:"Using defaults (OPENAI_API_KEY env var, text-embedding-3-large, 3072 dimensions)."})}),T.jsx(Up,{title:"Markdown store",subtitle:"optional — store crawled markdown in Postgres",action:T.jsxs("label",{className:"flex items-center gap-2 text-xs text-ink-secondary",children:[T.jsx("input",{type:"checkbox",checked:y,onChange:A=>d(["markdown_store"],A.target.checked?{}:void 0),className:"h-4 w-4 accent-(--accent)"}),"enable"]}),children:y?T.jsx(gx,{fields:x7,doc:r,basePath:["markdown_store"],onSet:d}):T.jsx("p",{className:"text-xs text-ink-muted",children:"Disabled."})}),T.jsxs("div",{className:"flex items-center gap-3",children:[T.jsx("button",{onClick:()=>f.mutate(),disabled:f.isPending||p.length===0||g.length>0,className:"rounded-md bg-accent px-4 py-2 text-sm font-medium text-white transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40",children:f.isPending?"Saving…":e.mode==="create"?"Create config":"Save changes"}),e.onCancel&&T.jsx("button",{onClick:e.onCancel,className:"text-sm text-ink-muted hover:text-ink-secondary",children:"Cancel"}),g.length>0&&T.jsxs("span",{className:"text-xs text-warning",children:["missing: ",g.slice(0,3).join(", "),g.length>3?"…":""]}),p.length===0&&T.jsx("span",{className:"text-xs text-warning",children:"add at least one source"}),e.mode==="edit"&&T.jsx("span",{className:"ml-auto text-xs text-ink-muted",children:"Saving rewrites the YAML file (comments are not preserved)."})]})]})}function lI({config:e,variant:t="subtle"}){const n=io(),[r,i]=O.useState(!1),[a,l]=O.useState(new Set),[s,c]=O.useState(""),f=Uh({mutationFn:k=>Ct.triggerRun(e.id,k,e.content_hash),onSuccess:()=>{i(!1),l(new Set),c("")},onSettled:()=>n.invalidateQueries({queryKey:["configs"]})}),d=O.useMemo(()=>e.source_summary.map((k,M)=>({...k,index:M})),[e.source_summary]),p=O.useMemo(()=>{const k=s.trim().toLowerCase();return k?d.filter(M=>M.product_name.toLowerCase().includes(k)||M.type.toLowerCase().includes(k)):d},[d,s]),g=e.busy||!!e.parse_error||f.isPending,v=k=>{k.preventDefault(),k.stopPropagation()},y=k=>{l(M=>{const P=new Set(M);return P.has(k)?P.delete(k):P.add(k),P})},x=p.length>0&&p.every(k=>a.has(k.index)),w=()=>{l(k=>{const M=new Set(k);return x?p.forEach(P=>M.delete(P.index)):p.forEach(P=>M.add(P.index)),M})},A=t==="primary"?"bg-accent text-white transition hover:opacity-90 px-3.5 py-1.5 text-sm font-medium":"border border-edge bg-surface text-ink-secondary transition hover:border-accent hover:text-accent px-3 py-1 text-xs font-medium",E=t==="primary"?"bg-accent text-white transition hover:opacity-90 border-l border-white/25 px-2 py-1.5 text-sm":"border border-l-0 border-edge bg-surface text-ink-secondary transition hover:border-accent hover:text-accent px-1.5 py-1 text-xs";return T.jsxs("div",{className:"relative inline-flex items-center gap-2",onClick:v,children:[T.jsxs("span",{className:"inline-flex",children:[T.jsx("button",{onClick:k=>{v(k),f.mutate(void 0)},disabled:g,className:`${d.length>1?"rounded-l-md":"rounded-md"} ${A} disabled:cursor-not-allowed disabled:opacity-40`,children:e.busy?"Running…":"Run now"}),d.length>1&&T.jsx("button",{onClick:k=>{v(k),i(M=>!M)},disabled:g,"aria-label":"Choose sources to run",title:"Choose sources to run",className:`rounded-r-md ${E} disabled:cursor-not-allowed disabled:opacity-40`,children:"▾"})]}),f.error&&T.jsx("span",{className:"text-xs text-critical",children:f.error.message}),r&&T.jsxs(T.Fragment,{children:[T.jsx("div",{className:"fixed inset-0 z-10",onClick:k=>{v(k),i(!1)}}),T.jsxs("div",{className:"absolute right-0 top-full z-20 mt-1.5 w-80 rounded-md border border-edge bg-surface shadow-lg",children:[T.jsxs("div",{className:"flex items-center justify-between border-b border-edge px-3 py-2",children:[T.jsxs("span",{className:"text-xs font-semibold uppercase tracking-wide text-ink-muted",children:["Run sources",a.size>0&&` (${a.size}/${d.length})`]}),T.jsxs("button",{onClick:k=>{v(k),w()},className:"text-xs text-accent hover:underline",children:[x?"Clear":"Select all",s.trim()&&" shown"]})]}),d.length>8&&T.jsx("div",{className:"border-b border-edge px-3 py-2",children:T.jsx("input",{type:"text",value:s,onChange:k=>c(k.target.value),onClick:k=>k.stopPropagation(),placeholder:"Filter sources…",className:"w-full rounded-md border border-edge bg-page px-2 py-1 text-xs text-ink-secondary placeholder:text-ink-muted focus:border-accent focus:outline-none"})}),T.jsxs("ul",{className:"max-h-64 overflow-y-auto py-1",children:[p.map(k=>T.jsx("li",{children:T.jsxs("label",{className:"flex cursor-pointer items-center gap-2 px-3 py-1.5 text-sm text-ink-secondary hover:bg-edge/20",onClick:M=>M.stopPropagation(),children:[T.jsx("input",{type:"checkbox",checked:a.has(k.index),onChange:()=>y(k.index),className:"accent-accent"}),T.jsx("span",{className:"truncate",children:k.product_name}),T.jsxs("span",{className:"ml-auto shrink-0 text-xs text-ink-muted",children:[k.type,k.version?` · ${k.version}`:""]})]})},k.index)),p.length===0&&T.jsxs("li",{className:"px-3 py-2 text-xs text-ink-muted",children:["No sources match “",s,"”."]})]}),T.jsx("div",{className:"border-t border-edge px-3 py-2",children:T.jsxs("button",{onClick:k=>{v(k),f.mutate([...a])},disabled:a.size===0||g,className:"w-full rounded-md bg-accent px-3 py-1.5 text-xs font-medium text-white transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40",children:["Run ",a.size>0?`${a.size} selected`:"selected"," source",a.size===1?"":"s"]})})]})]})]})}const w7={website:"🌐",github:"🐙",zendesk:"🎫",local_directory:"📁",code:"⌨️",s3:"🪣"};function oI({sources:e,max:t}){const[n,r]=O.useState(!1);if(e.length===0)return T.jsx("span",{className:"text-xs text-ink-muted",children:"no sources"});const i=n||t===void 0?e.length:t,a=e.slice(0,i),l=e.length-a.length;return T.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[a.map((s,c)=>T.jsxs("span",{title:`${s.type}${s.version?` · ${s.version}`:""}`,className:"inline-flex items-center gap-1 rounded-full border border-edge bg-page px-2 py-0.5 text-xs text-ink-secondary",children:[T.jsx("span",{"aria-hidden":!0,className:"text-[10px]",children:w7[s.type]??"•"}),s.product_name,T.jsx("span",{className:"text-ink-muted",children:s.type})]},`${s.product_name}-${s.type}-${c}`)),l>0&&T.jsxs("button",{onClick:s=>{s.preventDefault(),r(!0)},className:"rounded-full border border-edge px-2 py-0.5 text-xs text-ink-muted transition hover:border-accent hover:text-accent",children:["+",l," more"]})]})}function O7(){const e=Cv(),{data:t,isLoading:n,error:r}=Fi({queryKey:["configs"],queryFn:Ct.configs}),{data:i}=Fi({queryKey:["health"],queryFn:Ct.health}),[a,l]=O.useState(!1),s=t?.filter(c=>c.last_run?.status==="running"||c.last_run?.status==="queued")??[];return n?T.jsx("p",{className:"text-ink-muted",children:"Loading…"}):r?T.jsxs("p",{className:"text-critical",children:["Failed to load configs: ",String(r.message)]}):T.jsxs("div",{className:"space-y-6",children:[s.length>0&&T.jsx("div",{className:"rounded-lg border border-accent/30 bg-surface px-4 py-3",children:T.jsxs("p",{className:"text-sm text-ink-secondary",children:[T.jsxs("span",{className:"font-medium text-accent",children:["● ",s.length," config",s.length>1?"s":""," syncing now"]})," — ",s.map((c,f)=>T.jsxs("span",{children:[f>0&&", ",T.jsx(gi,{to:`/runs/${c.last_run.id}`,className:"text-accent hover:underline",children:c.name})]},c.id))]})}),T.jsxs("div",{className:"flex items-center justify-between",children:[T.jsx("h1",{className:"text-xl font-semibold tracking-tight",children:"Configurations"}),i?.mode==="rw"&&T.jsx("button",{onClick:()=>l(!0),className:"rounded-md bg-accent px-3.5 py-1.5 text-sm font-medium text-white transition hover:opacity-90",children:"New config"})]}),a&&T.jsxs("div",{className:"rounded-lg border border-edge bg-page p-4",children:[T.jsx("h2",{className:"mb-4 text-sm font-semibold",children:"Create a new config"}),T.jsx(aI,{mode:"create",onSaved:c=>{l(!1),e(`/configs/${c.id}`)},onCancel:()=>l(!1)})]}),t&&t.length===0&&T.jsxs("p",{className:"rounded-lg border border-edge bg-surface px-4 py-8 text-center text-sm text-ink-muted",children:["No configs loaded. Pass config files to ",T.jsx("code",{className:"text-ink-secondary",children:"doc2vec controller"}),i?.mode==="rw"&&" or create one with the button above","."]}),T.jsx("div",{className:"grid gap-4",children:t?.map(c=>T.jsx(gi,{to:`/configs/${c.id}`,className:"block rounded-lg border border-edge bg-surface p-4 transition hover:border-accent/50",children:T.jsxs("div",{className:"flex flex-col gap-3 md:grid md:grid-cols-[minmax(9rem,1fr)_12rem_15rem_8rem_auto] md:items-start md:gap-x-6",children:[T.jsxs("div",{className:"min-w-0",children:[T.jsxs("div",{className:"flex items-center gap-2",children:[T.jsx("h2",{className:"truncate font-semibold",children:c.name}),c.parse_error&&T.jsx("span",{className:"shrink-0 rounded-full border border-critical/40 px-2 py-0.5 text-xs text-critical",title:c.parse_error,children:"invalid"})]}),T.jsx("div",{className:"mt-1.5",children:T.jsx(oI,{sources:c.source_summary,max:4})})]}),T.jsxs("div",{className:"text-sm",children:[T.jsx("p",{className:"text-xs uppercase tracking-wide text-ink-muted",children:"Schedule"}),T.jsx("p",{className:"mt-0.5 text-ink-secondary",title:c.schedule??void 0,children:sO(c.schedule)})]}),T.jsxs("div",{className:"text-sm",children:[T.jsx("p",{className:"text-xs uppercase tracking-wide text-ink-muted",children:"Last run"}),T.jsx("div",{className:"mt-0.5 flex flex-wrap items-center gap-2",children:c.last_run?T.jsxs(T.Fragment,{children:[T.jsx(Mv,{status:c.last_run.status}),T.jsxs("span",{className:"text-xs text-ink-muted",title:Ua(c.last_run.queued_at),children:[$1(c.last_run.finished_at??c.last_run.queued_at),c.last_run.finished_at&&c.last_run.started_at&&` · ${oO(c.last_run.started_at,c.last_run.finished_at)}`]})]}):T.jsx("span",{className:"text-xs text-ink-muted",children:"never"})})]}),T.jsxs("div",{className:"text-sm",children:[T.jsx("p",{className:"text-xs uppercase tracking-wide text-ink-muted",children:"Next run"}),T.jsx("p",{className:"mt-0.5 text-ink-secondary",title:c.next_run?Ua(c.next_run):void 0,children:c.next_run?$1(c.next_run):"—"})]}),T.jsx("div",{className:"md:self-center",children:T.jsx(lI,{config:c})})]})},c.id))})]})}function G1(){return G1=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},G1.apply(null,arguments)}function A7(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}let Z1=[],sI=[];(()=>{let e="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(t=>t?parseInt(t,36):1);for(let t=0,n=0;t<e.length;t++)(t%2?sI:Z1).push(n=n+e[t])})();function k7(e){if(e<768)return!1;for(let t=0,n=Z1.length;;){let r=t+n>>1;if(e<Z1[r])n=r;else if(e>=sI[r])t=r+1;else return!0;if(t==n)return!1}}function LM(e){return e>=127462&&e<=127487}const IM=8205;function C7(e,t,n=!0,r=!0){return(n?uI:E7)(e,t,r)}function uI(e,t,n){if(t==e.length)return t;t&&cI(e.charCodeAt(t))&&fI(e.charCodeAt(t-1))&&t--;let r=vx(e,t);for(t+=BM(r);t<e.length;){let i=vx(e,t);if(r==IM||i==IM||n&&k7(i))t+=BM(i),r=i;else if(LM(i)){let a=0,l=t-2;for(;l>=0&&LM(vx(e,l));)a++,l-=2;if(a%2==0)break;t+=2}else break}return t}function E7(e,t,n){for(;t>1;){let r=uI(e,t-2,n);if(r<t)return r;t--}return 0}function vx(e,t){let n=e.charCodeAt(t);if(!fI(n)||t+1==e.length)return n;let r=e.charCodeAt(t+1);return cI(r)?(n-55296<<10)+(r-56320)+65536:n}function cI(e){return e>=56320&&e<57344}function fI(e){return e>=55296&&e<56320}function BM(e){return e<65536?1:2}let Je=class hI{lineAt(t){if(t<0||t>this.length)throw new RangeError(`Invalid position ${t} in document of length ${this.length}`);return this.lineInner(t,!1,1,0)}line(t){if(t<1||t>this.lines)throw new RangeError(`Invalid line number ${t} in ${this.lines}-line document`);return this.lineInner(t,!0,1,0)}replace(t,n,r){[t,n]=Fu(this,t,n);let i=[];return this.decompose(0,t,i,2),r.length&&r.decompose(0,r.length,i,3),this.decompose(n,this.length,i,1),$i.from(i,this.length-(n-t)+r.length)}append(t){return this.replace(this.length,this.length,t)}slice(t,n=this.length){[t,n]=Fu(this,t,n);let r=[];return this.decompose(t,n,r,0),$i.from(r,n-t)}eq(t){if(t==this)return!0;if(t.length!=this.length||t.lines!=this.lines)return!1;let n=this.scanIdentical(t,1),r=this.length-this.scanIdentical(t,-1),i=new Kf(this),a=new Kf(t);for(let l=n,s=n;;){if(i.next(l),a.next(l),l=0,i.lineBreak!=a.lineBreak||i.done!=a.done||i.value!=a.value)return!1;if(s+=i.value.length,i.done||s>=r)return!0}}iter(t=1){return new Kf(this,t)}iterRange(t,n=this.length){return new dI(this,t,n)}iterLines(t,n){let r;if(t==null)r=this.iter();else{n==null&&(n=this.lines+1);let i=this.line(t).from;r=this.iterRange(i,Math.max(i,n==this.lines+1?this.length:n<=1?0:this.line(n-1).to))}return new pI(r)}toString(){return this.sliceString(0)}toJSON(){let t=[];return this.flatten(t),t}constructor(){}static of(t){if(t.length==0)throw new RangeError("A document must have at least one line");return t.length==1&&!t[0]?hI.empty:t.length<=32?new It(t):$i.from(It.split(t,[]))}};class It extends Je{constructor(t,n=T7(t)){super(),this.text=t,this.length=n}get lines(){return this.text.length}get children(){return null}lineInner(t,n,r,i){for(let a=0;;a++){let l=this.text[a],s=i+l.length;if((n?r:s)>=t)return new M7(i,s,r,l);i=s+1,r++}}decompose(t,n,r,i){let a=t<=0&&n>=this.length?this:new It(zM(this.text,t,n),Math.min(n,this.length)-Math.max(0,t));if(i&1){let l=r.pop(),s=Rm(a.text,l.text.slice(),0,a.length);if(s.length<=32)r.push(new It(s,l.length+a.length));else{let c=s.length>>1;r.push(new It(s.slice(0,c)),new It(s.slice(c)))}}else r.push(a)}replace(t,n,r){if(!(r instanceof It))return super.replace(t,n,r);[t,n]=Fu(this,t,n);let i=Rm(this.text,Rm(r.text,zM(this.text,0,t)),n),a=this.length+r.length-(n-t);return i.length<=32?new It(i,a):$i.from(It.split(i,[]),a)}sliceString(t,n=this.length,r=`
|
|
56
56
|
`){[t,n]=Fu(this,t,n);let i="";for(let a=0,l=0;a<=n&&l<this.text.length;l++){let s=this.text[l],c=a+s.length;a>t&&l&&(i+=r),t<c&&n>a&&(i+=s.slice(Math.max(0,t-a),n-a)),a=c+1}return i}flatten(t){for(let n of this.text)t.push(n)}scanIdentical(){return 0}static split(t,n){let r=[],i=-1;for(let a of t)r.push(a),i+=a.length+1,r.length==32&&(n.push(new It(r,i)),r=[],i=-1);return i>-1&&n.push(new It(r,i)),n}}class $i extends Je{constructor(t,n){super(),this.children=t,this.length=n,this.lines=0;for(let r of t)this.lines+=r.lines}lineInner(t,n,r,i){for(let a=0;;a++){let l=this.children[a],s=i+l.length,c=r+l.lines-1;if((n?c:s)>=t)return l.lineInner(t,n,r,i);i=s+1,r=c+1}}decompose(t,n,r,i){for(let a=0,l=0;l<=n&&a<this.children.length;a++){let s=this.children[a],c=l+s.length;if(t<=c&&n>=l){let f=i&((l<=t?1:0)|(c>=n?2:0));l>=t&&c<=n&&!f?r.push(s):s.decompose(t-l,n-l,r,f)}l=c+1}}replace(t,n,r){if([t,n]=Fu(this,t,n),r.lines<this.lines)for(let i=0,a=0;i<this.children.length;i++){let l=this.children[i],s=a+l.length;if(t>=a&&n<=s){let c=l.replace(t-a,n-a,r),f=this.lines-l.lines+c.lines;if(c.lines<f>>4&&c.lines>f>>6){let d=this.children.slice();return d[i]=c,new $i(d,this.length-(n-t)+r.length)}return super.replace(a,s,c)}a=s+1}return super.replace(t,n,r)}sliceString(t,n=this.length,r=`
|
|
57
57
|
`){[t,n]=Fu(this,t,n);let i="";for(let a=0,l=0;a<this.children.length&&l<=n;a++){let s=this.children[a],c=l+s.length;l>t&&a&&(i+=r),t<c&&n>l&&(i+=s.sliceString(t-l,n-l,r)),l=c+1}return i}flatten(t){for(let n of this.children)n.flatten(t)}scanIdentical(t,n){if(!(t instanceof $i))return 0;let r=0,[i,a,l,s]=n>0?[0,0,this.children.length,t.children.length]:[this.children.length-1,t.children.length-1,-1,-1];for(;;i+=n,a+=n){if(i==l||a==s)return r;let c=this.children[i],f=t.children[a];if(c!=f)return r+c.scanIdentical(f,n);r+=c.length+1}}static from(t,n=t.reduce((r,i)=>r+i.length+1,-1)){let r=0;for(let v of t)r+=v.lines;if(r<32){let v=[];for(let y of t)y.flatten(v);return new It(v,n)}let i=Math.max(32,r>>5),a=i<<1,l=i>>1,s=[],c=0,f=-1,d=[];function p(v){let y;if(v.lines>a&&v instanceof $i)for(let x of v.children)p(x);else v.lines>l&&(c>l||!c)?(g(),s.push(v)):v instanceof It&&c&&(y=d[d.length-1])instanceof It&&v.lines+y.lines<=32?(c+=v.lines,f+=v.length+1,d[d.length-1]=new It(y.text.concat(v.text),y.length+1+v.length)):(c+v.lines>i&&g(),c+=v.lines,f+=v.length+1,d.push(v))}function g(){c!=0&&(s.push(d.length==1?d[0]:$i.from(d,f)),f=-1,c=d.length=0)}for(let v of t)p(v);return g(),s.length==1?s[0]:new $i(s,n)}}Je.empty=new It([""],0);function T7(e){let t=-1;for(let n of e)t+=n.length+1;return t}function Rm(e,t,n=0,r=1e9){for(let i=0,a=0,l=!0;a<e.length&&i<=r;a++){let s=e[a],c=i+s.length;c>=n&&(c>r&&(s=s.slice(0,r-i)),i<n&&(s=s.slice(n-i)),l?(t[t.length-1]+=s,l=!1):t.push(s)),i=c+1}return t}function zM(e,t,n){return Rm(e,[""],t,n)}class Kf{constructor(t,n=1){this.dir=n,this.done=!1,this.lineBreak=!1,this.value="",this.nodes=[t],this.offsets=[n>0?1:(t instanceof It?t.text.length:t.children.length)<<1]}nextInner(t,n){for(this.done=this.lineBreak=!1;;){let r=this.nodes.length-1,i=this.nodes[r],a=this.offsets[r],l=a>>1,s=i instanceof It?i.text.length:i.children.length;if(l==(n>0?s:0)){if(r==0)return this.done=!0,this.value="",this;n>0&&this.offsets[r-1]++,this.nodes.pop(),this.offsets.pop()}else if((a&1)==(n>0?0:1)){if(this.offsets[r]+=n,t==0)return this.lineBreak=!0,this.value=`
|
|
58
58
|
`,this;t--}else if(i instanceof It){let c=i.text[l+(n<0?-1:0)];if(this.offsets[r]+=n,c.length>Math.max(0,t))return this.value=t==0?c:n>0?c.slice(t):c.slice(0,c.length-t),this;t-=c.length}else{let c=i.children[l+(n<0?-1:0)];t>c.length?(t-=c.length,this.offsets[r]+=n):(n<0&&this.offsets[r]--,this.nodes.push(c),this.offsets.push(n>0?1:(c instanceof It?c.text.length:c.children.length)<<1))}}}next(t=0){return t<0&&(this.nextInner(-t,-this.dir),t=this.value.length),this.nextInner(t,this.dir)}}class dI{constructor(t,n,r){this.value="",this.done=!1,this.cursor=new Kf(t,n>r?-1:1),this.pos=n>r?t.length:0,this.from=Math.min(n,r),this.to=Math.max(n,r)}nextInner(t,n){if(n<0?this.pos<=this.from:this.pos>=this.to)return this.value="",this.done=!0,this;t+=Math.max(0,n<0?this.pos-this.to:this.from-this.pos);let r=n<0?this.pos-this.from:this.to-this.pos;t>r&&(t=r),r-=t;let{value:i}=this.cursor.next(t);return this.pos+=(i.length+t)*n,this.value=i.length<=r?i:n<0?i.slice(i.length-r):i.slice(0,r),this.done=!this.value,this}next(t=0){return t<0?t=Math.max(t,this.from-this.pos):t>0&&(t=Math.min(t,this.to-this.pos)),this.nextInner(t,this.cursor.dir)}get lineBreak(){return this.cursor.lineBreak&&this.value!=""}}class pI{constructor(t){this.inner=t,this.afterBreak=!0,this.value="",this.done=!1}next(t=0){let{done:n,lineBreak:r,value:i}=this.inner.next(t);return n&&this.afterBreak?(this.value="",this.afterBreak=!1):n?(this.done=!0,this.value=""):r?this.afterBreak?this.value="":(this.afterBreak=!0,this.next()):(this.value=i,this.afterBreak=!1),this}get lineBreak(){return!1}}typeof Symbol<"u"&&(Je.prototype[Symbol.iterator]=function(){return this.iter()},Kf.prototype[Symbol.iterator]=dI.prototype[Symbol.iterator]=pI.prototype[Symbol.iterator]=function(){return this});let M7=class{constructor(t,n,r,i){this.from=t,this.to=n,this.number=r,this.text=i}get length(){return this.to-this.from}};function Fu(e,t,n){return t=Math.max(0,Math.min(e.length,t)),[t,Math.max(t,Math.min(e.length,n))]}function on(e,t,n=!0,r=!0){return C7(e,t,n,r)}function D7(e){return e>=56320&&e<57344}function P7(e){return e>=55296&&e<56320}function rr(e,t){let n=e.charCodeAt(t);if(!P7(n)||t+1==e.length)return n;let r=e.charCodeAt(t+1);return D7(r)?(n-55296<<10)+(r-56320)+65536:n}function xO(e){return e<=65535?String.fromCharCode(e):(e-=65536,String.fromCharCode((e>>10)+55296,(e&1023)+56320))}function Ui(e){return e<65536?1:2}const J1=/\r\n?|\n/;var qn=(function(e){return e[e.Simple=0]="Simple",e[e.TrackDel=1]="TrackDel",e[e.TrackBefore=2]="TrackBefore",e[e.TrackAfter=3]="TrackAfter",e})(qn||(qn={}));class Qi{constructor(t){this.sections=t}get length(){let t=0;for(let n=0;n<this.sections.length;n+=2)t+=this.sections[n];return t}get newLength(){let t=0;for(let n=0;n<this.sections.length;n+=2){let r=this.sections[n+1];t+=r<0?this.sections[n]:r}return t}get empty(){return this.sections.length==0||this.sections.length==2&&this.sections[1]<0}iterGaps(t){for(let n=0,r=0,i=0;n<this.sections.length;){let a=this.sections[n++],l=this.sections[n++];l<0?(t(r,i,a),i+=a):i+=l,r+=a}}iterChangedRanges(t,n=!1){eS(this,t,n)}get invertedDesc(){let t=[];for(let n=0;n<this.sections.length;){let r=this.sections[n++],i=this.sections[n++];i<0?t.push(r,i):t.push(i,r)}return new Qi(t)}composeDesc(t){return this.empty?t:t.empty?this:mI(this,t)}mapDesc(t,n=!1){return t.empty?this:tS(this,t,n)}mapPos(t,n=-1,r=qn.Simple){let i=0,a=0;for(let l=0;l<this.sections.length;){let s=this.sections[l++],c=this.sections[l++],f=i+s;if(c<0){if(f>t)return a+(t-i);a+=s}else{if(r!=qn.Simple&&f>=t&&(r==qn.TrackDel&&i<t&&f>t||r==qn.TrackBefore&&i<t||r==qn.TrackAfter&&f>t))return null;if(f>t||f==t&&n<0&&!s)return t==i||n<0?a:a+c;a+=c}i=f}if(t>i)throw new RangeError(`Position ${t} is out of range for changeset of length ${i}`);return a}touchesRange(t,n=t){for(let r=0,i=0;r<this.sections.length&&i<=n;){let a=this.sections[r++],l=this.sections[r++],s=i+a;if(l>=0&&i<=n&&s>=t)return i<t&&s>n?"cover":!0;i=s}return!1}toString(){let t="";for(let n=0;n<this.sections.length;){let r=this.sections[n++],i=this.sections[n++];t+=(t?" ":"")+r+(i>=0?":"+i:"")}return t}toJSON(){return this.sections}static fromJSON(t){if(!Array.isArray(t)||t.length%2||t.some(n=>typeof n!="number"))throw new RangeError("Invalid JSON representation of ChangeDesc");return new Qi(t)}static create(t){return new Qi(t)}}class Yt extends Qi{constructor(t,n){super(t),this.inserted=n}apply(t){if(this.length!=t.length)throw new RangeError("Applying change set to a document with the wrong length");return eS(this,(n,r,i,a,l)=>t=t.replace(i,i+(r-n),l),!1),t}mapDesc(t,n=!1){return tS(this,t,n,!0)}invert(t){let n=this.sections.slice(),r=[];for(let i=0,a=0;i<n.length;i+=2){let l=n[i],s=n[i+1];if(s>=0){n[i]=s,n[i+1]=l;let c=i>>1;for(;r.length<c;)r.push(Je.empty);r.push(l?t.slice(a,a+l):Je.empty)}a+=l}return new Yt(n,r)}compose(t){return this.empty?t:t.empty?this:mI(this,t,!0)}map(t,n=!1){return t.empty?this:tS(this,t,n,!0)}iterChanges(t,n=!1){eS(this,t,n)}get desc(){return Qi.create(this.sections)}filter(t){let n=[],r=[],i=[],a=new hh(this);e:for(let l=0,s=0;;){let c=l==t.length?1e9:t[l++];for(;s<c||s==c&&a.len==0;){if(a.done)break e;let d=Math.min(a.len,c-s);Tn(i,d,-1);let p=a.ins==-1?-1:a.off==0?a.ins:0;Tn(n,d,p),p>0&&$l(r,n,a.text),a.forward(d),s+=d}let f=t[l++];for(;s<f;){if(a.done)break e;let d=Math.min(a.len,f-s);Tn(n,d,-1),Tn(i,d,a.ins==-1?-1:a.off==0?a.ins:0),a.forward(d),s+=d}}return{changes:new Yt(n,r),filtered:Qi.create(i)}}toJSON(){let t=[];for(let n=0;n<this.sections.length;n+=2){let r=this.sections[n],i=this.sections[n+1];i<0?t.push(r):i==0?t.push([r]):t.push([r].concat(this.inserted[n>>1].toJSON()))}return t}static of(t,n,r){let i=[],a=[],l=0,s=null;function c(d=!1){if(!d&&!i.length)return;l<n&&Tn(i,n-l,-1);let p=new Yt(i,a);s=s?s.compose(p.map(s)):p,i=[],a=[],l=0}function f(d){if(Array.isArray(d))for(let p of d)f(p);else if(d instanceof Yt){if(d.length!=n)throw new RangeError(`Mismatched change set length (got ${d.length}, expected ${n})`);c(),s=s?s.compose(d.map(s)):d}else{let{from:p,to:g=p,insert:v}=d;if(p>g||p<0||g>n)throw new RangeError(`Invalid change range ${p} to ${g} (in doc of length ${n})`);let y=v?typeof v=="string"?Je.of(v.split(r||J1)):v:Je.empty,x=y.length;if(p==g&&x==0)return;p<l&&c(),p>l&&Tn(i,p-l,-1),Tn(i,g-p,x),$l(a,i,y),l=g}}return f(t),c(!s),s}static empty(t){return new Yt(t?[t,-1]:[],[])}static fromJSON(t){if(!Array.isArray(t))throw new RangeError("Invalid JSON representation of ChangeSet");let n=[],r=[];for(let i=0;i<t.length;i++){let a=t[i];if(typeof a=="number")n.push(a,-1);else{if(!Array.isArray(a)||typeof a[0]!="number"||a.some((l,s)=>s&&typeof l!="string"))throw new RangeError("Invalid JSON representation of ChangeSet");if(a.length==1)n.push(a[0],0);else{for(;r.length<i;)r.push(Je.empty);r[i]=Je.of(a.slice(1)),n.push(a[0],r[i].length)}}}return new Yt(n,r)}static createSet(t,n){return new Yt(t,n)}}function Tn(e,t,n,r=!1){if(t==0&&n<=0)return;let i=e.length-2;i>=0&&n<=0&&n==e[i+1]?e[i]+=t:i>=0&&t==0&&e[i]==0?e[i+1]+=n:r?(e[i]+=t,e[i+1]+=n):e.push(t,n)}function $l(e,t,n){if(n.length==0)return;let r=t.length-2>>1;if(r<e.length)e[e.length-1]=e[e.length-1].append(n);else{for(;e.length<r;)e.push(Je.empty);e.push(n)}}function eS(e,t,n){let r=e.inserted;for(let i=0,a=0,l=0;l<e.sections.length;){let s=e.sections[l++],c=e.sections[l++];if(c<0)i+=s,a+=s;else{let f=i,d=a,p=Je.empty;for(;f+=s,d+=c,c&&r&&(p=p.append(r[l-2>>1])),!(n||l==e.sections.length||e.sections[l+1]<0);)s=e.sections[l++],c=e.sections[l++];t(i,f,a,d,p),i=f,a=d}}}function tS(e,t,n,r=!1){let i=[],a=r?[]:null,l=new hh(e),s=new hh(t);for(let c=-1;;){if(l.done&&s.len||s.done&&l.len)throw new Error("Mismatched change set lengths");if(l.ins==-1&&s.ins==-1){let f=Math.min(l.len,s.len);Tn(i,f,-1),l.forward(f),s.forward(f)}else if(s.ins>=0&&(l.ins<0||c==l.i||l.off==0&&(s.len<l.len||s.len==l.len&&!n))){let f=s.len;for(Tn(i,s.ins,-1);f;){let d=Math.min(l.len,f);l.ins>=0&&c<l.i&&l.len<=d&&(Tn(i,0,l.ins),a&&$l(a,i,l.text),c=l.i),l.forward(d),f-=d}s.next()}else if(l.ins>=0){let f=0,d=l.len;for(;d;)if(s.ins==-1){let p=Math.min(d,s.len);f+=p,d-=p,s.forward(p)}else if(s.ins==0&&s.len<d)d-=s.len,s.next();else break;Tn(i,f,c<l.i?l.ins:0),a&&c<l.i&&$l(a,i,l.text),c=l.i,l.forward(l.len-d)}else{if(l.done&&s.done)return a?Yt.createSet(i,a):Qi.create(i);throw new Error("Mismatched change set lengths")}}}function mI(e,t,n=!1){let r=[],i=n?[]:null,a=new hh(e),l=new hh(t);for(let s=!1;;){if(a.done&&l.done)return i?Yt.createSet(r,i):Qi.create(r);if(a.ins==0)Tn(r,a.len,0,s),a.next();else if(l.len==0&&!l.done)Tn(r,0,l.ins,s),i&&$l(i,r,l.text),l.next();else{if(a.done||l.done)throw new Error("Mismatched change set lengths");{let c=Math.min(a.len2,l.len),f=r.length;if(a.ins==-1){let d=l.ins==-1?-1:l.off?0:l.ins;Tn(r,c,d,s),i&&d&&$l(i,r,l.text)}else l.ins==-1?(Tn(r,a.off?0:a.len,c,s),i&&$l(i,r,a.textBit(c))):(Tn(r,a.off?0:a.len,l.off?0:l.ins,s),i&&!l.off&&$l(i,r,l.text));s=(a.ins>c||l.ins>=0&&l.len>c)&&(s||r.length>f),a.forward2(c),l.forward(c)}}}}class hh{constructor(t){this.set=t,this.i=0,this.next()}next(){let{sections:t}=this.set;this.i<t.length?(this.len=t[this.i++],this.ins=t[this.i++]):(this.len=0,this.ins=-2),this.off=0}get done(){return this.ins==-2}get len2(){return this.ins<0?this.len:this.ins}get text(){let{inserted:t}=this.set,n=this.i-2>>1;return n>=t.length?Je.empty:t[n]}textBit(t){let{inserted:n}=this.set,r=this.i-2>>1;return r>=n.length&&!t?Je.empty:n[r].slice(this.off,t==null?void 0:this.off+t)}forward(t){t==this.len?this.next():(this.len-=t,this.off+=t)}forward2(t){this.ins==-1?this.forward(t):t==this.ins?this.next():(this.ins-=t,this.off+=t)}}class jl{constructor(t,n,r,i){this.from=t,this.to=n,this.flags=r,this.goalColumn=i}get anchor(){return this.flags&32?this.to:this.from}get head(){return this.flags&32?this.from:this.to}get empty(){return this.from==this.to}get assoc(){return this.flags&8?-1:this.flags&16?1:0}get undirectional(){return(this.flags&64)>0}get bidiLevel(){let t=this.flags&7;return t==7?null:t}map(t,n=-1){let r,i;return this.empty?r=i=t.mapPos(this.from,n):(r=t.mapPos(this.from,1),i=t.mapPos(this.to,-1)),r==this.from&&i==this.to?this:new jl(r,i,this.flags,this.goalColumn)}extend(t,n=t,r=0){if(t<=this.anchor&&n>=this.anchor)return te.range(t,n,void 0,void 0,r);let i=Math.abs(t-this.anchor)>Math.abs(n-this.anchor)?t:n;return te.range(this.anchor,i,void 0,void 0,r)}eq(t,n=!1){return this.anchor==t.anchor&&this.head==t.head&&this.goalColumn==t.goalColumn&&(!n||!this.empty||this.assoc==t.assoc)}toJSON(){return{anchor:this.anchor,head:this.head}}static fromJSON(t){if(!t||typeof t.anchor!="number"||typeof t.head!="number")throw new RangeError("Invalid JSON representation for SelectionRange");return te.range(t.anchor,t.head)}static create(t,n,r,i){return new jl(t,n,r,i)}}class te{constructor(t,n){this.ranges=t,this.mainIndex=n}map(t,n=-1){return t.empty?this:te.create(this.ranges.map(r=>r.map(t,n)),this.mainIndex)}eq(t,n=!1){if(this.ranges.length!=t.ranges.length||this.mainIndex!=t.mainIndex)return!1;for(let r=0;r<this.ranges.length;r++)if(!this.ranges[r].eq(t.ranges[r],n))return!1;return!0}get main(){return this.ranges[this.mainIndex]}asSingle(){return this.ranges.length==1?this:new te([this.main],0)}addRange(t,n=!0){return te.create([t].concat(this.ranges),n?0:this.mainIndex+1)}replaceRange(t,n=this.mainIndex){let r=this.ranges.slice();return r[n]=t,te.create(r,this.mainIndex)}toJSON(){return{ranges:this.ranges.map(t=>t.toJSON()),main:this.mainIndex}}static fromJSON(t){if(!t||!Array.isArray(t.ranges)||typeof t.main!="number"||t.main>=t.ranges.length)throw new RangeError("Invalid JSON representation for EditorSelection");return new te(t.ranges.map(n=>jl.fromJSON(n)),t.main)}static single(t,n=t){return new te([te.range(t,n)],0)}static create(t,n=0){if(t.length==0)throw new RangeError("A selection needs at least one range");for(let r=0,i=0;i<t.length;i++){let a=t[i];if(a.empty?a.from<=r:a.from<r)return te.normalized(t.slice(),n);r=a.to}return new te(t,n)}static cursor(t,n=0,r,i){return jl.create(t,t,(n==0?0:n<0?8:16)|(r==null?7:Math.min(6,r)),i)}static range(t,n,r,i,a){let l=i==null?7:Math.min(6,i);return!a&&t!=n&&(a=n<t?1:-1),a&&(l|=a<0?8:16),n<t?jl.create(n,t,l|32,r):jl.create(t,n,l,r)}static undirectionalRange(t,n){return jl.create(t,n,64,void 0)}static normalized(t,n=0){let r=t[n];t.sort((i,a)=>i.from-a.from),n=t.indexOf(r);for(let i=1;i<t.length;i++){let a=t[i],l=t[i-1];if(a.empty?a.from<=l.to:a.from<l.to){let s=l.from,c=Math.max(a.to,l.to);i<=n&&n--,t.splice(--i,2,a.anchor>a.head?te.range(c,s):te.range(s,c))}}return new te(t,n)}}function gI(e,t){for(let n of e.ranges)if(n.to>t)throw new RangeError("Selection points outside of document")}let SO=0;class me{constructor(t,n,r,i,a){this.combine=t,this.compareInput=n,this.compare=r,this.isStatic=i,this.id=SO++,this.default=t([]),this.extensions=typeof a=="function"?a(this):a}get reader(){return this}static define(t={}){return new me(t.combine||(n=>n),t.compareInput||((n,r)=>n===r),t.compare||(t.combine?(n,r)=>n===r:wO),!!t.static,t.enables)}of(t){return new jm([],this,0,t)}compute(t,n){if(this.isStatic)throw new Error("Can't compute a static facet");return new jm(t,this,1,n)}computeN(t,n){if(this.isStatic)throw new Error("Can't compute a static facet");return new jm(t,this,2,n)}from(t,n){return n||(n=r=>r),this.compute([t],r=>n(r.field(t)))}}function wO(e,t){return e==t||e.length==t.length&&e.every((n,r)=>n===t[r])}class jm{constructor(t,n,r,i){this.dependencies=t,this.facet=n,this.type=r,this.value=i,this.id=SO++}dynamicSlot(t){var n;let r=this.value,i=this.facet.compareInput,a=this.id,l=t[a]>>1,s=this.type==2,c=!1,f=!1,d=[];for(let p of this.dependencies)p=="doc"?c=!0:p=="selection"?f=!0:(((n=t[p.id])!==null&&n!==void 0?n:1)&1)==0&&d.push(t[p.id]);return{create(p){return p.values[l]=r(p),1},update(p,g){if(c&&g.docChanged||f&&(g.docChanged||g.selection)||nS(p,d)){let v=r(p);if(s?!$M(v,p.values[l],i):!i(v,p.values[l]))return p.values[l]=v,1}return 0},reconfigure:(p,g)=>{let v,y=g.config.address[a];if(y!=null){let x=rg(g,y);if(this.dependencies.every(w=>w instanceof me?g.facet(w)===p.facet(w):w instanceof Nn?g.field(w,!1)==p.field(w,!1):!0)||(s?$M(v=r(p),x,i):i(v=r(p),x)))return p.values[l]=x,0}else v=r(p);return p.values[l]=v,1}}}get extension(){return this}}function $M(e,t,n){if(e.length!=t.length)return!1;for(let r=0;r<e.length;r++)if(!n(e[r],t[r]))return!1;return!0}function nS(e,t){let n=!1;for(let r of t)Xf(e,r)&1&&(n=!0);return n}function _7(e,t,n){let r=n.map(c=>e[c.id]),i=n.map(c=>c.type),a=r.filter(c=>!(c&1)),l=e[t.id]>>1;function s(c){let f=[];for(let d=0;d<r.length;d++){let p=rg(c,r[d]);if(i[d]==2)for(let g of p)f.push(g);else f.push(p)}return t.combine(f)}return{create(c){for(let f of r)Xf(c,f);return c.values[l]=s(c),1},update(c,f){if(!nS(c,a))return 0;let d=s(c);return t.compare(d,c.values[l])?0:(c.values[l]=d,1)},reconfigure(c,f){let d=nS(c,r),p=f.config.facets[t.id],g=f.facet(t);if(p&&!d&&wO(n,p))return c.values[l]=g,0;let v=s(c);return t.compare(v,g)?(c.values[l]=g,0):(c.values[l]=v,1)}}}const Hp=me.define({static:!0});class Nn{constructor(t,n,r,i,a){this.id=t,this.createF=n,this.updateF=r,this.compareF=i,this.spec=a,this.provides=void 0}static define(t){let n=new Nn(SO++,t.create,t.update,t.compare||((r,i)=>r===i),t);return t.provide&&(n.provides=t.provide(n)),n}create(t){let n=t.facet(Hp).find(r=>r.field==this);return(n?.create||this.createF)(t)}slot(t){let n=t[this.id]>>1;return{create:r=>(r.values[n]=this.create(r),1),update:(r,i)=>{let a=r.values[n],l=this.updateF(a,i);return this.compareF(a,l)?0:(r.values[n]=l,1)},reconfigure:(r,i)=>{let a=r.facet(Hp),l=i.facet(Hp),s;return(s=a.find(c=>c.field==this))&&s!=l.find(c=>c.field==this)?(r.values[n]=s.create(r),1):i.config.address[this.id]!=null?(r.values[n]=i.field(this),0):(r.values[n]=this.create(r),1)}}}init(t){return[this,Hp.of({field:this,create:t})]}get extension(){return this}}const Io={lowest:4,low:3,default:2,high:1,highest:0};function xf(e){return t=>new vI(t,e)}const vs={highest:xf(Io.highest),high:xf(Io.high),default:xf(Io.default),low:xf(Io.low),lowest:xf(Io.lowest)};class vI{constructor(t,n){this.inner=t,this.prec=n}get extension(){return this}}class Rv{of(t){return new rS(this,t)}reconfigure(t){return Rv.reconfigure.of({compartment:this,extension:t})}get(t){return t.config.compartments.get(this)}}class rS{constructor(t,n){this.compartment=t,this.inner=n}get extension(){return this}}class ng{constructor(t,n,r,i,a,l){for(this.base=t,this.compartments=n,this.dynamicSlots=r,this.address=i,this.staticValues=a,this.facets=l,this.statusTemplate=[];this.statusTemplate.length<r.length;)this.statusTemplate.push(0)}staticFacet(t){let n=this.address[t.id];return n==null?t.default:this.staticValues[n>>1]}static resolve(t,n,r){let i=[],a=Object.create(null),l=new Map;for(let g of N7(t,n,l))g instanceof Nn?i.push(g):(a[g.facet.id]||(a[g.facet.id]=[])).push(g);let s=Object.create(null),c=[],f=[];for(let g of i)s[g.id]=f.length<<1,f.push(v=>g.slot(v));let d=r?.config.facets;for(let g in a){let v=a[g],y=v[0].facet,x=d&&d[g]||[];if(v.every(w=>w.type==0))if(s[y.id]=c.length<<1|1,wO(x,v))c.push(r.facet(y));else{let w=y.combine(v.map(A=>A.value));c.push(r&&y.compare(w,r.facet(y))?r.facet(y):w)}else{for(let w of v)w.type==0?(s[w.id]=c.length<<1|1,c.push(w.value)):(s[w.id]=f.length<<1,f.push(A=>w.dynamicSlot(A)));s[y.id]=f.length<<1,f.push(w=>_7(w,y,v))}}let p=f.map(g=>g(s));return new ng(t,l,p,s,c,a)}}function N7(e,t,n){let r=[[],[],[],[],[]],i=new Map;function a(l,s){let c=i.get(l);if(c!=null){if(c<=s)return;let f=r[c].indexOf(l);f>-1&&r[c].splice(f,1),l instanceof rS&&n.delete(l.compartment)}if(i.set(l,s),Array.isArray(l))for(let f of l)a(f,s);else if(l instanceof rS){if(n.has(l.compartment))throw new RangeError("Duplicate use of compartment in extensions");let f=t.get(l.compartment)||l.inner;n.set(l.compartment,f),a(f,s)}else if(l instanceof vI)a(l.inner,l.prec);else if(l instanceof Nn)r[s].push(l),l.provides&&a(l.provides,s);else if(l instanceof jm)r[s].push(l),l.facet.extensions&&a(l.facet.extensions,Io.default);else{let f=l.extension;if(!f)throw new Error(`Unrecognized extension value in extension set (${l}).`);if(f==l)throw new Error(`Unrecognized extension value in extension set (${l}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`);a(f,s)}}return a(e,Io.default),r.reduce((l,s)=>l.concat(s))}function Xf(e,t){if(t&1)return 2;let n=t>>1,r=e.status[n];if(r==4)throw new Error("Cyclic dependency between fields and/or facets");if(r&2)return r;e.status[n]=4;let i=e.computeSlot(e,e.config.dynamicSlots[n]);return e.status[n]=2|i}function rg(e,t){return t&1?e.config.staticValues[t>>1]:e.values[t>>1]}const yI=me.define(),iS=me.define({combine:e=>e.some(t=>t),static:!0}),bI=me.define({combine:e=>e.length?e[0]:void 0,static:!0}),xI=me.define(),SI=me.define(),wI=me.define(),OI=me.define({combine:e=>e.length?e[0]:!1});class ia{constructor(t,n){this.type=t,this.value=n}static define(){return new R7}}class R7{of(t){return new ia(this,t)}}class j7{constructor(t){this.map=t}of(t){return new _e(this,t)}}class _e{constructor(t,n){this.type=t,this.value=n}map(t){let n=this.type.map(this.value,t);return n===void 0?void 0:n==this.value?this:new _e(this.type,n)}is(t){return this.type==t}static define(t={}){return new j7(t.map||(n=>n))}static mapEffects(t,n){if(!t.length)return t;let r=[];for(let i of t){let a=i.map(n);a&&r.push(a)}return r}}_e.reconfigure=_e.define();_e.appendConfig=_e.define();class Zt{constructor(t,n,r,i,a,l){this.startState=t,this.changes=n,this.selection=r,this.effects=i,this.annotations=a,this.scrollIntoView=l,this._doc=null,this._state=null,r&&gI(r,n.newLength),a.some(s=>s.type==Zt.time)||(this.annotations=a.concat(Zt.time.of(Date.now())))}static create(t,n,r,i,a,l){return new Zt(t,n,r,i,a,l)}get newDoc(){return this._doc||(this._doc=this.changes.apply(this.startState.doc))}get newSelection(){return this.selection||this.startState.selection.map(this.changes)}get state(){return this._state||this.startState.applyTransaction(this),this._state}annotation(t){for(let n of this.annotations)if(n.type==t)return n.value}get docChanged(){return!this.changes.empty}get reconfigured(){return this.startState.config!=this.state.config}isUserEvent(t){let n=this.annotation(Zt.userEvent);return!!(n&&(n==t||n.length>t.length&&n.slice(0,t.length)==t&&n[t.length]=="."))}}Zt.time=ia.define();Zt.userEvent=ia.define();Zt.addToHistory=ia.define();Zt.remote=ia.define();function L7(e,t){let n=[];for(let r=0,i=0;;){let a,l;if(r<e.length&&(i==t.length||t[i]>=e[r]))a=e[r++],l=e[r++];else if(i<t.length)a=t[i++],l=t[i++];else return n;!n.length||n[n.length-1]<a?n.push(a,l):n[n.length-1]<l&&(n[n.length-1]=l)}}function AI(e,t,n){var r;let i,a,l;return n?(i=t.changes,a=Yt.empty(t.changes.length),l=e.changes.compose(t.changes)):(i=t.changes.map(e.changes),a=e.changes.mapDesc(t.changes,!0),l=e.changes.compose(i)),{changes:l,selection:t.selection?t.selection.map(a):(r=e.selection)===null||r===void 0?void 0:r.map(i),effects:_e.mapEffects(e.effects,i).concat(_e.mapEffects(t.effects,a)),annotations:e.annotations.length?e.annotations.concat(t.annotations):t.annotations,scrollIntoView:e.scrollIntoView||t.scrollIntoView}}function aS(e,t,n){let r=t.selection,i=Pu(t.annotations);return t.userEvent&&(i=i.concat(Zt.userEvent.of(t.userEvent))),{changes:t.changes instanceof Yt?t.changes:Yt.of(t.changes||[],n,e.facet(bI)),selection:r&&(r instanceof te?r:te.single(r.anchor,r.head)),effects:Pu(t.effects),annotations:i,scrollIntoView:!!t.scrollIntoView}}function kI(e,t,n){let r=aS(e,t.length?t[0]:{},e.doc.length);t.length&&t[0].filter===!1&&(n=!1);for(let a=1;a<t.length;a++){t[a].filter===!1&&(n=!1);let l=!!t[a].sequential;r=AI(r,aS(e,t[a],l?r.changes.newLength:e.doc.length),l)}let i=Zt.create(e,r.changes,r.selection,r.effects,r.annotations,r.scrollIntoView);return B7(n?I7(i):i)}function I7(e){let t=e.startState,n=!0;for(let i of t.facet(xI)){let a=i(e);if(a===!1){n=!1;break}Array.isArray(a)&&(n=n===!0?a:L7(n,a))}if(n!==!0){let i,a;if(n===!1)a=e.changes.invertedDesc,i=Yt.empty(t.doc.length);else{let l=e.changes.filter(n);i=l.changes,a=l.filtered.mapDesc(l.changes).invertedDesc}e=Zt.create(t,i,e.selection&&e.selection.map(a),_e.mapEffects(e.effects,a),e.annotations,e.scrollIntoView)}let r=t.facet(SI);for(let i=r.length-1;i>=0;i--){let a=r[i](e);a instanceof Zt?e=a:Array.isArray(a)&&a.length==1&&a[0]instanceof Zt?e=a[0]:e=kI(t,Pu(a),!1)}return e}function B7(e){let t=e.startState,n=t.facet(wI),r=e;for(let i=n.length-1;i>=0;i--){let a=n[i](e);a&&Object.keys(a).length&&(r=AI(r,aS(t,a,e.changes.newLength),!0))}return r==e?e:Zt.create(t,e.changes,e.selection,r.effects,r.annotations,r.scrollIntoView)}const z7=[];function Pu(e){return e==null?z7:Array.isArray(e)?e:[e]}var Ot=(function(e){return e[e.Word=0]="Word",e[e.Space=1]="Space",e[e.Other=2]="Other",e})(Ot||(Ot={}));const $7=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;let lS;try{lS=new RegExp("[\\p{Alphabetic}\\p{Number}_]","u")}catch{}function U7(e){if(lS)return lS.test(e);for(let t=0;t<e.length;t++){let n=e[t];if(/\w/.test(n)||n>""&&(n.toUpperCase()!=n.toLowerCase()||$7.test(n)))return!0}return!1}function H7(e){return t=>{if(!/\S/.test(t))return Ot.Space;if(U7(t))return Ot.Word;for(let n=0;n<e.length;n++)if(t.indexOf(e[n])>-1)return Ot.Word;return Ot.Other}}class qe{constructor(t,n,r,i,a,l){this.config=t,this.doc=n,this.selection=r,this.values=i,this.status=t.statusTemplate.slice(),this.computeSlot=a,l&&(l._state=this);for(let s=0;s<this.config.dynamicSlots.length;s++)Xf(this,s<<1);this.computeSlot=null}field(t,n=!0){let r=this.config.address[t.id];if(r==null){if(n)throw new RangeError("Field is not present in this state");return}return Xf(this,r),rg(this,r)}update(...t){return kI(this,t,!0)}applyTransaction(t){let n=this.config,{base:r,compartments:i}=n;for(let s of t.effects)s.is(Rv.reconfigure)?(n&&(i=new Map,n.compartments.forEach((c,f)=>i.set(f,c)),n=null),i.set(s.value.compartment,s.value.extension)):s.is(_e.reconfigure)?(n=null,r=s.value):s.is(_e.appendConfig)&&(n=null,r=Pu(r).concat(s.value));let a;n?a=t.startState.values.slice():(n=ng.resolve(r,i,this),a=new qe(n,this.doc,this.selection,n.dynamicSlots.map(()=>null),(c,f)=>f.reconfigure(c,this),null).values);let l=t.startState.facet(iS)?t.newSelection:t.newSelection.asSingle();new qe(n,t.newDoc,l,a,(s,c)=>c.update(s,t),t)}replaceSelection(t){return typeof t=="string"&&(t=this.toText(t)),this.changeByRange(n=>({changes:{from:n.from,to:n.to,insert:t},range:te.cursor(n.from+t.length)}))}changeByRange(t){let n=this.selection,r=t(n.ranges[0]),i=this.changes(r.changes),a=[r.range],l=Pu(r.effects);for(let s=1;s<n.ranges.length;s++){let c=t(n.ranges[s]),f=this.changes(c.changes),d=f.map(i);for(let g=0;g<s;g++)a[g]=a[g].map(d);let p=i.mapDesc(f,!0);a.push(c.range.map(p)),i=i.compose(d),l=_e.mapEffects(l,d).concat(_e.mapEffects(Pu(c.effects),p))}return{changes:i,selection:te.create(a,n.mainIndex),effects:l}}changes(t=[]){return t instanceof Yt?t:Yt.of(t,this.doc.length,this.facet(qe.lineSeparator))}toText(t){return Je.of(t.split(this.facet(qe.lineSeparator)||J1))}sliceDoc(t=0,n=this.doc.length){return this.doc.sliceString(t,n,this.lineBreak)}facet(t){let n=this.config.address[t.id];return n==null?t.default:(Xf(this,n),rg(this,n))}toJSON(t){let n={doc:this.sliceDoc(),selection:this.selection.toJSON()};if(t)for(let r in t){let i=t[r];i instanceof Nn&&this.config.address[i.id]!=null&&(n[r]=i.spec.toJSON(this.field(t[r]),this))}return n}static fromJSON(t,n={},r){if(!t||typeof t.doc!="string")throw new RangeError("Invalid JSON representation for EditorState");let i=[];if(r){for(let a in r)if(Object.prototype.hasOwnProperty.call(t,a)){let l=r[a],s=t[a];i.push(l.init(c=>l.spec.fromJSON(s,c)))}}return qe.create({doc:t.doc,selection:te.fromJSON(t.selection),extensions:n.extensions?i.concat([n.extensions]):i})}static create(t={}){let n=ng.resolve(t.extensions||[],new Map),r=t.doc instanceof Je?t.doc:Je.of((t.doc||"").split(n.staticFacet(qe.lineSeparator)||J1)),i=t.selection?t.selection instanceof te?t.selection:te.single(t.selection.anchor,t.selection.head):te.single(0);return gI(i,r.length),n.staticFacet(iS)||(i=i.asSingle()),new qe(n,r,i,n.dynamicSlots.map(()=>null),(a,l)=>l.create(a),null)}get tabSize(){return this.facet(qe.tabSize)}get lineBreak(){return this.facet(qe.lineSeparator)||`
|
package/dist/ui/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>doc2vec</title>
|
|
7
7
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='0.9em' font-size='90'%3E%F0%9F%93%9A%3C/text%3E%3C/svg%3E" />
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DCnbYtxb.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-Cf1xdzH_.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/utils.js
CHANGED
|
@@ -177,5 +177,93 @@ class Utils {
|
|
|
177
177
|
to--;
|
|
178
178
|
return text.slice(from, to);
|
|
179
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Normalize a glob pattern or a relative path to the form the matcher uses:
|
|
182
|
+
* forward slashes, no leading `./`, no leading or trailing `/`.
|
|
183
|
+
*/
|
|
184
|
+
static normalizeGlobPath(value) {
|
|
185
|
+
return value
|
|
186
|
+
.replace(/\\/g, '/')
|
|
187
|
+
.replace(/^\.\//, '')
|
|
188
|
+
.replace(/^\/+/, '')
|
|
189
|
+
.replace(/\/+$/, '');
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Build a regular expression from a glob pattern.
|
|
193
|
+
*
|
|
194
|
+
* `**` crosses directory separators, `*` and `?` do not. A globstar
|
|
195
|
+
* followed by a slash also matches zero directories, so a pattern like
|
|
196
|
+
* `**` + `/*_test.go` matches `main_test.go`
|
|
197
|
+
* at the root as well as `pkg/a/main_test.go`.
|
|
198
|
+
*/
|
|
199
|
+
static globToRegExp(pattern) {
|
|
200
|
+
let source = '';
|
|
201
|
+
let i = 0;
|
|
202
|
+
while (i < pattern.length) {
|
|
203
|
+
const char = pattern[i];
|
|
204
|
+
if (char === '*') {
|
|
205
|
+
let end = i;
|
|
206
|
+
while (pattern[end] === '*')
|
|
207
|
+
end++;
|
|
208
|
+
const isGlobstar = end - i > 1;
|
|
209
|
+
if (!isGlobstar) {
|
|
210
|
+
source += '[^/]*';
|
|
211
|
+
i = end;
|
|
212
|
+
}
|
|
213
|
+
else if (pattern[end] === '/') {
|
|
214
|
+
source += '(?:.*/)?';
|
|
215
|
+
i = end + 1;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
source += '.*';
|
|
219
|
+
i = end;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else if (char === '?') {
|
|
223
|
+
source += '[^/]';
|
|
224
|
+
i++;
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
source += char.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
228
|
+
i++;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return new RegExp(`^${source}$`);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Report whether a relative path matches one of the glob patterns.
|
|
235
|
+
*/
|
|
236
|
+
static matchesAnyGlob(relativePath, patterns) {
|
|
237
|
+
if (!patterns || patterns.length === 0)
|
|
238
|
+
return false;
|
|
239
|
+
const normalizedPath = Utils.normalizeGlobPath(relativePath);
|
|
240
|
+
if (normalizedPath === '')
|
|
241
|
+
return false;
|
|
242
|
+
return patterns.some((pattern) => {
|
|
243
|
+
const normalizedPattern = Utils.normalizeGlobPath(pattern);
|
|
244
|
+
if (normalizedPattern === '')
|
|
245
|
+
return false;
|
|
246
|
+
return Utils.globToRegExp(normalizedPattern).test(normalizedPath);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Report whether a directory is excluded, so the caller can skip the whole
|
|
251
|
+
* subtree instead of walking it.
|
|
252
|
+
*
|
|
253
|
+
* A directory is excluded when a pattern matches the directory itself
|
|
254
|
+
* (`vendor`) or when a pattern excludes everything below it (`vendor/**`).
|
|
255
|
+
* Patterns that only select some descendants (a test-file pattern, for
|
|
256
|
+
* example) do not exclude the directory — the walk must continue and
|
|
257
|
+
* filter each file.
|
|
258
|
+
*/
|
|
259
|
+
static isDirectoryExcluded(relativePath, patterns) {
|
|
260
|
+
if (!patterns || patterns.length === 0)
|
|
261
|
+
return false;
|
|
262
|
+
const prefixes = patterns
|
|
263
|
+
.map((pattern) => Utils.normalizeGlobPath(pattern))
|
|
264
|
+
.filter((pattern) => pattern.endsWith('/**'))
|
|
265
|
+
.map((pattern) => pattern.slice(0, -3));
|
|
266
|
+
return Utils.matchesAnyGlob(relativePath, patterns) || Utils.matchesAnyGlob(relativePath, prefixes);
|
|
267
|
+
}
|
|
180
268
|
}
|
|
181
269
|
exports.Utils = Utils;
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "doc2vec",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
4
|
"type": "commonjs",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=22"
|
|
7
|
+
},
|
|
5
8
|
"description": "",
|
|
6
9
|
"main": "dist/doc2vec.js",
|
|
7
10
|
"private": false,
|
|
@@ -33,23 +36,23 @@
|
|
|
33
36
|
"@aws-sdk/client-s3": "^3.1004.0",
|
|
34
37
|
"@chonkiejs/core": "^0.0.7",
|
|
35
38
|
"@mozilla/readability": "^0.4.4",
|
|
36
|
-
"@qdrant/js-client-rest": "^1.
|
|
37
|
-
"@qdrant/qdrant-js": "^1.
|
|
38
|
-
"axios": "^1.
|
|
39
|
-
"better-sqlite3": "^
|
|
39
|
+
"@qdrant/js-client-rest": "^1.19.0",
|
|
40
|
+
"@qdrant/qdrant-js": "^1.19.0",
|
|
41
|
+
"axios": "^1.19.0",
|
|
42
|
+
"better-sqlite3": "^13.0.3",
|
|
40
43
|
"chalk": "^5.4.1",
|
|
41
44
|
"cheerio": "^1.0.0-rc.12",
|
|
42
45
|
"commander": "^15.0.0",
|
|
43
46
|
"croner": "^10.0.1",
|
|
44
47
|
"dotenv": "^16.3.1",
|
|
45
48
|
"express": "^5.2.1",
|
|
46
|
-
"js-yaml": "^4.1
|
|
49
|
+
"js-yaml": "^4.3.1",
|
|
47
50
|
"jsdom": "^26.0.0",
|
|
48
51
|
"mammoth": "^1.11.0",
|
|
49
52
|
"openai": "^4.20.1",
|
|
50
53
|
"pdfjs-dist": "^5.3.31",
|
|
51
54
|
"pg": "^8.18.0",
|
|
52
|
-
"puppeteer": "^
|
|
55
|
+
"puppeteer": "^25.8.0",
|
|
53
56
|
"sanitize-html": "^2.11.0",
|
|
54
57
|
"sqlite-vec": "0.1.7-alpha.2",
|
|
55
58
|
"tree-sitter-wasms": "^0.1.0",
|