mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-16 08:25:14 +02:00
chore(workspace): gate dead-code with knip production mode
Turn on production-mode knip plus an autofix run in pre-commit and the `pnpm dead-code` script, document the `/** @internal */` convention for test-only exports in AGENTS.md, annotate test-only exports across the CLI with that JSDoc, and drop dead exports/wrappers the new gate surfaced (e.g. `cli-project.ts`, `lookerRuntimeSourceToFileAdapterSource`, `createLocalScanEnrichmentProvidersFromConfig`, `PGLITE_OWNER_PROCESS_BACKEND_CAPABILITIES`, stale type re-exports). Replace the loose `ignoreIssues` allowlist in `knip.json` with explicit production entries so cross-package barrel leaks are caught.
This commit is contained in:
parent
ac3885b652
commit
b690e6988b
71 changed files with 211 additions and 279 deletions
|
|
@ -3,6 +3,7 @@ import { join, relative } from 'node:path';
|
|||
|
||||
const YAML_EXT_RE = /\.(ya?ml)$/i;
|
||||
|
||||
/** @internal */
|
||||
export function normalizeDbtPath(path: string): string {
|
||||
return path.replaceAll('\\', '/');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
import { Buffer } from 'node:buffer';
|
||||
import type { StagedPatternsInput } from './types.js';
|
||||
|
||||
export const HISTORIC_SQL_PATTERN_WORKUNIT_DIR = 'patterns-input';
|
||||
const HISTORIC_SQL_PATTERN_WORKUNIT_DIR = 'patterns-input';
|
||||
/** @internal */
|
||||
export const HISTORIC_SQL_PATTERN_WORKUNIT_MAX_BYTES = 110_000;
|
||||
export const HISTORIC_SQL_PATTERN_WORKUNIT_PATH_RE = /^patterns-input\/part-\d{4}\.json$/;
|
||||
const HISTORIC_SQL_PATTERN_WORKUNIT_PATH_RE = /^patterns-input\/part-\d{4}\.json$/;
|
||||
|
||||
type PatternTemplate = StagedPatternsInput['templates'][number];
|
||||
|
||||
export interface HistoricSqlPatternInputShard {
|
||||
interface HistoricSqlPatternInputShard {
|
||||
path: string;
|
||||
input: StagedPatternsInput;
|
||||
byteLength: number;
|
||||
|
|
@ -27,10 +28,11 @@ export function isHistoricSqlPatternInputShardPath(path: string): boolean {
|
|||
return HISTORIC_SQL_PATTERN_WORKUNIT_PATH_RE.test(path);
|
||||
}
|
||||
|
||||
export function serializeStagedPatternsInput(input: StagedPatternsInput): string {
|
||||
function serializeStagedPatternsInput(input: StagedPatternsInput): string {
|
||||
return `${JSON.stringify(input, null, 2)}\n`;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function serializedStagedPatternsInputByteLength(input: StagedPatternsInput): number {
|
||||
return Buffer.byteLength(serializeStagedPatternsInput(input), 'utf-8');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ function tableSortKey(table: KtxTableRef): string {
|
|||
return `${table.catalog ?? ''}\u0000${table.db ?? ''}\u0000${table.name}`;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function liveDatabaseTablePath(table: KtxTableRef): string {
|
||||
return `${LIVE_DATABASE_TABLES_DIR}/${encodePathPart(table.catalog)}.${encodePathPart(table.db)}.${encodePathPart(
|
||||
table.name,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { mkdir, writeFile } from 'node:fs/promises';
|
||||
import { dirname, join } from 'node:path';
|
||||
import type { ParsedTargetTable } from '../../parsed-target-table.js';
|
||||
import type { FetchContext } from '../../types.js';
|
||||
import { writeLookerEvidenceDocuments } from './evidence-documents.js';
|
||||
import { writeLookerFetchReport } from './fetch-report.js';
|
||||
import {
|
||||
type LookerPullConfig,
|
||||
type ParsedTargetTable,
|
||||
parseLookerPullConfig,
|
||||
STAGED_FILES,
|
||||
type StagedDashboardFile,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
import type { ParsedTargetTable } from '../../parsed-target-table.js';
|
||||
import type { LookerWarehouseConnectionInfo } from './client.js';
|
||||
import type {
|
||||
LookerPullConfig,
|
||||
LookerRuntimeCursors,
|
||||
ParsedTargetTable,
|
||||
StagedExploreFile,
|
||||
StagedLookmlModelsFile,
|
||||
} from './types.js';
|
||||
import type { LookerPullConfig, LookerRuntimeCursors, StagedExploreFile, StagedLookmlModelsFile } from './types.js';
|
||||
|
||||
export const LOOKER_DIALECT_TO_CONNECTION_TYPE = {
|
||||
bigquery: 'BIGQUERY',
|
||||
|
|
|
|||
|
|
@ -1,17 +1,5 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { buildLookerReconcileNotes, lookerRuntimeSourceToFileAdapterSource } from './reconcile.js';
|
||||
|
||||
describe('lookerRuntimeSourceToFileAdapterSource', () => {
|
||||
it('maps API-derived Looker source names to file-adapter source names', () => {
|
||||
expect(lookerRuntimeSourceToFileAdapterSource('looker__b2b__sales_pipeline')).toBe('b2b__sales_pipeline');
|
||||
expect(lookerRuntimeSourceToFileAdapterSource('looker__finance__orders')).toBe('finance__orders');
|
||||
});
|
||||
|
||||
it('ignores non-Looker and malformed source names', () => {
|
||||
expect(lookerRuntimeSourceToFileAdapterSource('b2b__sales_pipeline')).toBeNull();
|
||||
expect(lookerRuntimeSourceToFileAdapterSource('looker__missing_explore')).toBeNull();
|
||||
});
|
||||
});
|
||||
import { buildLookerReconcileNotes } from './reconcile.js';
|
||||
|
||||
describe('buildLookerReconcileNotes', () => {
|
||||
it('instructs reconciliation to record subsumed provenance', () => {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,3 @@
|
|||
export function lookerRuntimeSourceToFileAdapterSource(sourceName: string): string | null {
|
||||
if (!sourceName.startsWith('looker__')) {
|
||||
return null;
|
||||
}
|
||||
const stripped = sourceName.slice('looker__'.length);
|
||||
const parts = stripped.split('__');
|
||||
if (parts.length < 2 || parts.some((part) => part.length === 0)) {
|
||||
return null;
|
||||
}
|
||||
const [model, ...exploreParts] = parts;
|
||||
return `${model}__${exploreParts.join('__')}`;
|
||||
}
|
||||
|
||||
export function buildLookerReconcileNotes(): string[] {
|
||||
return [
|
||||
[
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { tool } from 'ai';
|
||||
import { z } from 'zod';
|
||||
import type { ToolOutput } from '../../../../tools/index.js';
|
||||
import { type ParsedTargetTable, stagedLookerQuerySchema } from '../types.js';
|
||||
import type { ParsedTargetTable } from '../../../parsed-target-table.js';
|
||||
import { stagedLookerQuerySchema } from '../types.js';
|
||||
|
||||
const lookerUsageInputSchema = z.object({
|
||||
queryCount30d: z.number().int().nonnegative().default(0),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { parsedTargetTableSchema } from '../../parsed-target-table.js';
|
||||
import {
|
||||
lookerPullConfigSchema,
|
||||
parseLookerPullConfig,
|
||||
parsedTargetTableSchema,
|
||||
stagedDashboardFileSchema,
|
||||
stagedExploreFileSchema,
|
||||
stagedLookerFetchIssueSchema,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ const nullableLookerIdSchema = z.union([lookerIdSchema, z.null()]).default(null)
|
|||
|
||||
export const lookerConnectionIdSchema = z.string().min(1).regex(/^[A-Za-z0-9_-]+$/);
|
||||
|
||||
export { parsedTargetTableSchema, type ParsedTargetTable } from '../../parsed-target-table.js';
|
||||
|
||||
export const lookerRuntimeCursorsSchema = z.object({
|
||||
dashboardsLastSyncedAt: z.iso.datetime().nullable().default(null),
|
||||
looksLastSyncedAt: z.iso.datetime().nullable().default(null),
|
||||
|
|
@ -16,6 +14,7 @@ export const lookerRuntimeCursorsSchema = z.object({
|
|||
|
||||
export type LookerRuntimeCursors = z.infer<typeof lookerRuntimeCursorsSchema>;
|
||||
|
||||
/** @internal */
|
||||
export const lookerPullConfigSchema = z.object({
|
||||
lookerConnectionId: lookerConnectionIdSchema.optional(),
|
||||
instanceBaseUrl: z.url().optional(),
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import * as z from 'zod';
|
|||
import type { SourceFetchReport } from '../../types.js';
|
||||
import type { ParsedLookmlProject } from './parse.js';
|
||||
|
||||
/** @internal */
|
||||
export const LOOKML_FETCH_REPORT_FILE = 'lookml-fetch-report.json';
|
||||
/** @internal */
|
||||
export const LOOKML_MISMATCHED_MODELS_FILE = 'lookml-mismatched-models.json';
|
||||
|
||||
const fetchIssueKindSchema = z.enum([
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import * as z from 'zod';
|
||||
import { parsedTargetTableSchema } from '../../parsed-target-table.js';
|
||||
|
||||
export const lookmlPullConfigSchema = z.object({
|
||||
const lookmlPullConfigSchema = z.object({
|
||||
repoUrl: z.string().url(),
|
||||
branch: z.string().default('main'),
|
||||
path: z.string().nullable().default(null),
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ const CARD_REF_RE = /\{\{#(\d+)\}\}/g;
|
|||
* Input TemplateTag shape mirrors `MetabaseClient.getTemplateTags` output. We keep the
|
||||
* shape loose — only `name`, `type`, and optional `cardReference`/`default` are needed here.
|
||||
*/
|
||||
/** @internal */
|
||||
export interface InputTemplateTag {
|
||||
name: string;
|
||||
type: string;
|
||||
|
|
@ -13,6 +14,7 @@ export interface InputTemplateTag {
|
|||
defaultValue?: string | null;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function extractReferencedCardIds(templateTags: InputTemplateTag[], sql: string): number[] {
|
||||
const ids = new Set<number>();
|
||||
for (const tag of templateTags) {
|
||||
|
|
@ -34,7 +36,7 @@ export function extractReferencedCardIds(templateTags: InputTemplateTag[], sql:
|
|||
* care about. The adapter reads whatever the client returns; this helper stays
|
||||
* duck-typed so the client's type can evolve without churn here.
|
||||
*/
|
||||
export interface InputCard {
|
||||
interface InputCard {
|
||||
id: number;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
export const metabaseSyncModeSchema = z.enum(['ALL', 'ONLY', 'EXCEPT']);
|
||||
const metabaseSyncModeSchema = z.enum(['ALL', 'ONLY', 'EXCEPT']);
|
||||
export type MetabaseSyncMode = z.infer<typeof metabaseSyncModeSchema>;
|
||||
|
||||
export const metabaseLocalConnectionIdSchema = z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/);
|
||||
|
|
@ -25,7 +25,7 @@ export function parseMetabasePullConfig(raw: unknown): MetabasePullConfig {
|
|||
}
|
||||
|
||||
/** A Metabase column from `card.result_metadata`. Mirrors what the LLM consumes today. */
|
||||
export const stagedResultColumnSchema = z.object({
|
||||
const stagedResultColumnSchema = z.object({
|
||||
name: z.string(),
|
||||
display_name: z.string().optional().nullable(),
|
||||
base_type: z.string(),
|
||||
|
|
@ -37,7 +37,7 @@ export const stagedResultColumnSchema = z.object({
|
|||
|
||||
export type StagedResultColumn = z.infer<typeof stagedResultColumnSchema>;
|
||||
|
||||
export const stagedParameterSchema = z.object({
|
||||
const stagedParameterSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
type: z.string(),
|
||||
|
|
@ -49,7 +49,7 @@ export const stagedParameterSchema = z.object({
|
|||
export type StagedParameter = z.infer<typeof stagedParameterSchema>;
|
||||
|
||||
/** A template tag pulled from an MBQL card's `dataset_query.stages[0].template-tags`. */
|
||||
export const stagedTemplateTagSchema = z.object({
|
||||
const stagedTemplateTagSchema = z.object({
|
||||
name: z.string(),
|
||||
type: z.string(),
|
||||
defaultValue: z.string().optional().nullable(),
|
||||
|
|
@ -87,7 +87,7 @@ export const stagedCardFileSchema = z.object({
|
|||
export type StagedCardFile = z.infer<typeof stagedCardFileSchema>;
|
||||
|
||||
/** A serialized collection file, `collections/<id>.json`. Minimal — path lives on the card. */
|
||||
export const stagedCollectionFileSchema = z.object({
|
||||
const stagedCollectionFileSchema = z.object({
|
||||
metabaseId: z.union([z.number().int(), z.literal('root')]),
|
||||
name: z.string(),
|
||||
parentId: z.union([z.number().int(), z.literal('root')]).nullable(),
|
||||
|
|
@ -96,7 +96,7 @@ export const stagedCollectionFileSchema = z.object({
|
|||
export type StagedCollectionFile = z.infer<typeof stagedCollectionFileSchema>;
|
||||
|
||||
/** A serialized database-mapping snapshot, `databases/<id>.json`. */
|
||||
export const stagedDatabaseFileSchema = z.object({
|
||||
const stagedDatabaseFileSchema = z.object({
|
||||
metabaseDatabaseId: z.number().int().positive(),
|
||||
metabaseDatabaseName: z.string(),
|
||||
metabaseEngine: z.string().nullable(),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { readdir, readFile } from 'node:fs/promises';
|
|||
import { join, relative } from 'node:path';
|
||||
import { parse as parseYaml } from 'yaml';
|
||||
|
||||
export interface ParsedMetricFlowSemanticModel {
|
||||
interface ParsedMetricFlowSemanticModel {
|
||||
/** Path relative to stagedDir, e.g. "models/orders.yml". */
|
||||
path: string;
|
||||
/** `name:` on the semantic_model. */
|
||||
|
|
@ -24,9 +24,9 @@ export interface ParsedMetricFlowSemanticModel {
|
|||
defaultTimeDimension: string | null;
|
||||
}
|
||||
|
||||
export type MetricFlowMetricType = 'simple' | 'derived' | 'cumulative' | 'ratio' | 'conversion';
|
||||
type MetricFlowMetricType = 'simple' | 'derived' | 'cumulative' | 'ratio' | 'conversion';
|
||||
|
||||
export interface ParsedMetricFlowMetric {
|
||||
interface ParsedMetricFlowMetric {
|
||||
path: string;
|
||||
name: string;
|
||||
type: MetricFlowMetricType;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { kmeans, pickK } from '../../clustering/kmeans.js';
|
|||
import type { WorkUnit } from '../../types.js';
|
||||
import { notionMetadataSchema } from './types.js';
|
||||
|
||||
/** @internal */
|
||||
export const MIN_PAGES_TO_CLUSTER = 5;
|
||||
const CLUSTER_TEXT_BODY_CHARS = 1024;
|
||||
const CLUSTER_SEED = 42;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ function richTextToMarkdown(value: unknown): string {
|
|||
.trim();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function propertyValueToText(value: unknown): string {
|
||||
if (!value || typeof value !== 'object' || !('type' in value)) {
|
||||
return '';
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ function shouldRetryNotionError(error: unknown): boolean {
|
|||
return code === 'rate_limited' || transientErrorCodes.has(code ?? '') || transientStatusCodes.has(status ?? 0);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export async function retryNotionRequest<T>(operation: () => Promise<T>, options: RetryOptions = {}): Promise<T> {
|
||||
const maxAttempts = options.maxAttempts ?? 4;
|
||||
const sleep = options.sleep ?? defaultSleep;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import type { KtxModelRole } from '../../llm/index.js';
|
|||
import type { KtxEmbeddingPort } from '../core/embedding.js';
|
||||
import type { GitService, KtxFileStorePort, KtxLogger, SessionOutcome } from '../core/index.js';
|
||||
import type { AgentRunnerPort, KtxLlmRuntimePort, KtxRuntimeToolSet } from '../llm/index.js';
|
||||
import type { CaptureSession, MemoryAction, MemoryKnowledgeSlRefsPort } from '../memory/index.js';
|
||||
import type { MemoryAction, MemoryKnowledgeSlRefsPort } from '../memory/index.js';
|
||||
import type { PromptService } from '../prompts/index.js';
|
||||
import type { SkillsRegistryService } from '../skills/index.js';
|
||||
import type {
|
||||
|
|
@ -34,7 +34,7 @@ import type {
|
|||
SourceAdapter,
|
||||
} from './types.js';
|
||||
|
||||
export type JsonPrimitive = string | number | boolean | null;
|
||||
type JsonPrimitive = string | number | boolean | null;
|
||||
export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue | undefined };
|
||||
|
||||
export interface IngestRunRecord {
|
||||
|
|
@ -359,9 +359,4 @@ export interface IngestBundleRunnerDeps {
|
|||
logger?: KtxLogger;
|
||||
}
|
||||
|
||||
export interface IngestCaptureState {
|
||||
session: CaptureSession;
|
||||
actions: MemoryAction[];
|
||||
}
|
||||
|
||||
export type IngestRunnerJob = IngestBundleJob;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ export interface SemanticLayerTargetPolicyInput {
|
|||
allowedConnectionIds: ReadonlySet<string>;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface SemanticLayerTargetPolicyViolation {
|
||||
path: string;
|
||||
connectionId: string;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type { WorkUnit } from '../types.js';
|
|||
|
||||
const MAX_WORK_UNIT_PROMPT_CHARS = 240_000;
|
||||
|
||||
export interface TouchedValidationResult {
|
||||
interface TouchedValidationResult {
|
||||
invalidSources: string[];
|
||||
validSources: string[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { MemoryAction } from '../../memory/index.js';
|
||||
import type { TouchedSlSource } from '../../tools/index.js';
|
||||
|
||||
export interface StageIndexWorkUnit {
|
||||
interface StageIndexWorkUnit {
|
||||
unitKey: string;
|
||||
rawFiles: string[];
|
||||
status: 'success' | 'failed';
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ export interface KtxSqlExecutionResponse {
|
|||
rowCount: number;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface KtxSqlExecutionMcpPort {
|
||||
execute(
|
||||
input: { connectionId: string; sql: string; maxRows: number },
|
||||
|
|
|
|||
|
|
@ -256,14 +256,10 @@ const ktxProjectConfigSchema = z
|
|||
|
||||
export type KtxProjectConfig = z.infer<typeof ktxProjectConfigSchema>;
|
||||
export type KtxProjectLlmConfig = z.infer<typeof llmSchema>;
|
||||
export type KtxProjectLlmProviderConfig = z.infer<typeof llmProviderSchema>;
|
||||
export type KtxProjectEmbeddingConfig = z.infer<typeof embeddingSchema>;
|
||||
export type KtxScanEnrichmentConfig = z.infer<typeof scanEnrichmentSchema>;
|
||||
export type KtxIngestWorkUnitsConfig = z.infer<typeof workUnitsSchema>;
|
||||
export type KtxScanRelationshipConfig = z.infer<typeof scanRelationshipsSchema>;
|
||||
export type KtxProjectScanConfig = z.infer<typeof scanSchema>;
|
||||
export type KtxProjectConnectionConfig = z.infer<typeof connectionSchema>;
|
||||
export type KtxProjectSetupConfig = z.infer<typeof setupSchema>;
|
||||
export type KtxStorageState = z.infer<typeof storageSchema>['state'];
|
||||
export type KtxSearchBackend = z.infer<typeof storageSchema>['search'];
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import {
|
|||
runLocalScanEnrichment,
|
||||
snapshotToKtxEnrichedSchema,
|
||||
} from './local-enrichment.js';
|
||||
import { createLocalScanEnrichmentProvidersFromConfig } from './local-scan.js';
|
||||
import {
|
||||
createKtxConnectorCapabilities,
|
||||
type KtxQueryResult,
|
||||
|
|
@ -813,46 +812,4 @@ describe('local scan enrichment', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('resolves gateway LLM providers and passes injected embedding provider through to scan enrichment', () => {
|
||||
const createKtxLlmProvider = vi.fn(() => ({
|
||||
getModel: vi.fn().mockReturnValue({ modelId: 'provider/language-model', provider: 'gateway' }),
|
||||
}));
|
||||
const embeddingProvider = {
|
||||
dimensions: 1536,
|
||||
maxBatchSize: 8,
|
||||
embed: vi.fn(),
|
||||
[['embed', 'Many'].join('')]: vi.fn(),
|
||||
};
|
||||
|
||||
const providers = createLocalScanEnrichmentProvidersFromConfig(
|
||||
{
|
||||
mode: 'llm',
|
||||
embeddings: {
|
||||
backend: 'openai',
|
||||
model: 'provider/embedding-model',
|
||||
dimensions: 1536,
|
||||
batchSize: 8,
|
||||
openai: { api_key: 'env:OPENAI_API_KEY' }, // pragma: allowlist secret
|
||||
},
|
||||
},
|
||||
{
|
||||
provider: {
|
||||
backend: 'gateway',
|
||||
gateway: {},
|
||||
},
|
||||
models: { default: 'provider/language-model' },
|
||||
},
|
||||
{
|
||||
createKtxLlmProvider: createKtxLlmProvider as any,
|
||||
env: { OPENAI_API_KEY: 'openai-key' }, // pragma: allowlist secret
|
||||
embeddingProvider: embeddingProvider as any,
|
||||
},
|
||||
);
|
||||
|
||||
expect(providers?.embedding?.dimensions).toBe(1536);
|
||||
expect(providers?.embedding?.maxBatchSize).toBe(8);
|
||||
expect(createKtxLlmProvider).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ backend: 'gateway', modelSlots: { default: 'provider/language-model' } }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -226,15 +226,6 @@ function resolveLocalScanEnrichmentProviders(
|
|||
};
|
||||
}
|
||||
|
||||
export function createLocalScanEnrichmentProvidersFromConfig(
|
||||
config: KtxScanEnrichmentConfig,
|
||||
llmConfig: KtxProjectLlmConfig,
|
||||
deps: LocalScanEnrichmentProviderDeps = {},
|
||||
): KtxLocalScanEnrichmentProviders | null {
|
||||
const resolved = resolveLocalScanEnrichmentProviders(config, llmConfig, deps);
|
||||
return resolved.status === 'ready' ? resolved.providers : null;
|
||||
}
|
||||
|
||||
function createLocalScanEnrichmentStateStore(options: RunLocalScanOptions): SqliteLocalScanEnrichmentStateStore | null {
|
||||
if (options.dryRun) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
pluralizeKtxRelationshipToken,
|
||||
singularizeKtxRelationshipToken,
|
||||
} from './relationship-name-similarity.js';
|
||||
export type { KtxRelationshipNormalizedName } from './relationship-name-similarity.js';
|
||||
;
|
||||
export { normalizeKtxRelationshipName } from './relationship-name-similarity.js';
|
||||
import type { KtxRelationshipProfileArtifact } from './relationship-profiling.js';
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export interface KtxRelationshipDiagnosticsThresholds {
|
|||
reviewThreshold: number;
|
||||
}
|
||||
|
||||
export interface KtxRelationshipDiagnosticsPolicy {
|
||||
interface KtxRelationshipDiagnosticsPolicy {
|
||||
validationRequiredForManifest: boolean;
|
||||
maxCandidatesPerColumn: number;
|
||||
profileSampleRows: number;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import { tmpdir } from 'node:os';
|
|||
import { join } from 'node:path';
|
||||
import { Client } from 'pg';
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
||||
import { assertSearchBackendCapabilities, assertSearchBackendConformanceCase } from './index.js';
|
||||
import { KtxPGliteOwnerProcess, PGLITE_OWNER_PROCESS_BACKEND_CAPABILITIES } from './pglite-owner-process.js';
|
||||
import { assertSearchBackendConformanceCase } from './index.js';
|
||||
import { KtxPGliteOwnerProcess } from './pglite-owner-process.js';
|
||||
|
||||
async function allocatePort(): Promise<number> {
|
||||
const server = createServer();
|
||||
|
|
@ -107,20 +107,6 @@ describe('KtxPGliteOwnerProcess', () => {
|
|||
await rm(tempDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it('declares the advanced PGlite search capabilities observed by the spike', () => {
|
||||
assertSearchBackendCapabilities({
|
||||
backendName: 'pglite-owner-process',
|
||||
capabilities: PGLITE_OWNER_PROCESS_BACKEND_CAPABILITIES,
|
||||
expected: {
|
||||
fts: true,
|
||||
vector: true,
|
||||
fuzzy: true,
|
||||
jsonSearch: true,
|
||||
arraySearch: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('starts a socket owner process and serves PostgreSQL clients', async () => {
|
||||
const owner = await KtxPGliteOwnerProcess.start({
|
||||
dataDir,
|
||||
|
|
|
|||
|
|
@ -3,15 +3,6 @@ import { pg_trgm } from '@electric-sql/pglite/contrib/pg_trgm';
|
|||
import { vector } from '@electric-sql/pglite/vector';
|
||||
import { PGLiteSocketServer } from '@electric-sql/pglite-socket';
|
||||
import { Client, type ClientConfig, type QueryResult, type QueryResultRow } from 'pg';
|
||||
import type { SearchBackendCapabilities } from './types.js';
|
||||
|
||||
export const PGLITE_OWNER_PROCESS_BACKEND_CAPABILITIES = {
|
||||
fts: true,
|
||||
vector: true,
|
||||
fuzzy: true,
|
||||
jsonSearch: true,
|
||||
arraySearch: false,
|
||||
} satisfies SearchBackendCapabilities;
|
||||
|
||||
export interface KtxPGliteOwnerProcessOptions {
|
||||
dataDir: string;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,11 @@ export interface LoadAllSourcesResult {
|
|||
loadErrors: string[];
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export class UnknownColumnOverrideError extends Error {}
|
||||
/** @internal */
|
||||
export class ColumnNameCollisionError extends Error {}
|
||||
/** @internal */
|
||||
export class ConflictingExcludeAndOverrideError extends Error {}
|
||||
class ComposeContractError extends Error {}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export interface ContextEvidenceSearchArgs {
|
|||
|
||||
export type ContextEvidenceSearchMatchReason = 'lexical' | 'semantic' | 'token' | (string & {});
|
||||
|
||||
export interface ContextEvidenceSearchLaneSummary {
|
||||
interface ContextEvidenceSearchLaneSummary {
|
||||
lane: string;
|
||||
status: 'available' | 'skipped' | 'failed';
|
||||
requestedCandidatePoolLimit: number;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ interface WikiSearchStructured {
|
|||
totalFound: number;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface WikiSearchAdapterPort {
|
||||
search(input: { userId: string; query: string; limit: number }): Promise<{
|
||||
results: Array<{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue