Skip to content

feat(shared): lint rule flags aiSearch indexes missing columns - #513

Open
MarioCadenas wants to merge 1 commit into
mainfrom
feat/ai-search-columns-lint
Open

feat(shared): lint rule flags aiSearch indexes missing columns#513
MarioCadenas wants to merge 1 commit into
mainfrom
feat/ai-search-columns-lint

Conversation

@MarioCadenas

Copy link
Copy Markdown
Collaborator

Stacked on # — base branch is feat/export-vector-search-plugin, not main. GitHub will auto-retarget to main once the parent merges. Review only the diff shown here (the lint rule); the parent PR carries the plugin itself.

What

Adds an appkit lint rule, ai-search-index-requires-columns, that flags an aiSearch plugin config whose indexes have no usable columns.

Why

In production the plugin does not auto-discover an index's columns — that's dev-only (ai-search.ts _autoDiscoverColumns, gated on NODE_ENV === "development"). So a config that omits columns works in dev but fails at query time in prod (Field 'columns' must be specified). appkit lint is the pre-deploy static catch, complementing the existing dev nudges (auto-discovery banner + manifest scaffolding.rules).

How

aiSearch({ indexes: { a: {...}, b: {...} } }) — "every index has non-empty columns" can't be expressed as a single ast-grep pattern, so this adds an optional find?: (root) => SgNode[] escape hatch to the Rule interface. Flat pattern rules and this structural rule share the same reporting path. lintFile now delegates to an exported lintSource() so rules can be tested against in-memory source.

Flagged (fail in prod):

  • bare aiSearch(), aiSearch({}), aiSearch({ indexes: {} }) — all fall back to the env-seeded default index, which has no columns
  • any index object missing columns, or with columns: []

Passed (can't statically prove bad — no false positives):

  • columns: SOME_CONST, indexes: buildIndexes(), aiSearch(dynamicConfig), spread index objects ({ ...base })

The violation points at the offending index alias, not the whole call.

Test plan

  • packages/shared/src/cli/commands/lint.test.ts — 14 vitest cases covering every pass/flag branch above
  • pnpm exec vitest run lint — 14/14 pass
  • pnpm -r typecheck — clean
  • pnpm exec biome check on changed files — clean
  • Manual: appkit lint over a temp server.ts with a bad aiSearch() flags it and exits 1

@MarioCadenas
MarioCadenas requested a review from a team as a code owner August 5, 2026 12:55
@MarioCadenas
MarioCadenas requested review from atilafassina and removed request for a team August 5, 2026 12:55
@MarioCadenas
MarioCadenas force-pushed the feat/ai-search-columns-lint branch from 39079f0 to 2c78d70 Compare August 5, 2026 13:38
Base automatically changed from feat/export-vector-search-plugin to main August 5, 2026 14:50
Add ai-search-index-requires-columns to `appkit lint`. In production the
plugin does not auto-discover an index's columns (dev-only), so a missing
or empty `columns` fails at query time. This is the pre-deploy static
catch.

Uses a structural traversal via a new optional `find` escape hatch on
Rule, since "every index in indexes:{...} has non-empty columns" isn't a
single ast-grep pattern. Flags bare aiSearch(), aiSearch({}), empty
indexes, and any index missing columns or with columns:[]; passes
dynamic/const/spread configs to avoid false positives. Extracts
lintSource() so rules can be tested against in-memory source.

Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
@MarioCadenas
MarioCadenas force-pushed the feat/ai-search-columns-lint branch from 2c78d70 to 1848b63 Compare August 5, 2026 15:02
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle size report

Compared against bundle-size-baseline.json (main).

@databricks/appkit

npm tarball (packed): 828 KB (+15 KB) — gzipped download (dist + bin; excludes release-only docs/NOTICE).

dist raw gzip
JS (runtime) 855 KB (+20 KB) 298 KB (+6.9 KB)
Type declarations 314 KB (+6.4 KB) 108 KB (+2.8 KB)
Source maps 1.7 MB (+31 KB) 557 KB (+11 KB)
Other 11 KB 3.7 KB
Total 2.8 MB (+57 KB) 967 KB (+20 KB)
Per-entry composition (own code — deps external (as shipped))
Entry Initial (gz) Lazy (gz) Total (gz) node_modules (min) Own code (min)
. 87 KB (+45 B) 2.5 KB 90 KB (+45 B) external 285 KB (+122 B)
./beta 48 KB (+3.0 KB) 459 B (+1 B) 48 KB (+3.0 KB) external 140 KB (+11 KB)
./type-generator 20 KB 0 B 20 KB external 57 KB

Chunks:

Entry Chunk Load Size (gz)
. index.js initial 83 KB
. utils.js initial 4.0 KB
. remote-tunnel-manager.js lazy 2.5 KB
./beta beta.js initial 32 KB
./beta stream-manager.js initial 5.8 KB
./beta wide-event-emitter.js initial 3.2 KB
./beta databricks.js initial 3.0 KB
./beta configuration.js initial 2.1 KB
./beta service-context.js initial 1.3 KB
./beta client.js initial 431 B
./beta client-options.js initial 220 B
./beta supervisor-api.js lazy 194 B
./beta databricks.js lazy 142 B
./beta index.js lazy 123 B
./type-generator index.js initial 20 KB

@databricks/appkit-ui

npm tarball (packed): 309 KB (+3.5 KB) — gzipped download (dist + bin; excludes release-only docs/NOTICE).

dist raw gzip
JS (runtime) 362 KB (+2.6 KB) 121 KB (+1.1 KB)
Type declarations 209 KB (+3.1 KB) 76 KB (+1.2 KB)
Source maps 693 KB (+7.1 KB) 227 KB (+2.8 KB)
CSS 16 KB 3.3 KB
Total 1.3 MB (+13 KB) 427 KB (+5.0 KB)
Per-entry composition (consumer bundle — deps bundled, peerDeps external)
Entry Initial (gz) Lazy (gz) Total (gz) node_modules (min) Own code (min)
./js 4.3 KB 49 KB 54 KB 208 KB 12 KB
./js/beta 20 B 0 B 20 B 0 B 0 B
./react 429 KB 49 KB 478 KB 1.3 MB 168 KB
./react/beta 1.0 KB (+1015 B) 0 B 1.0 KB (+1015 B) 0 B 1.9 KB (+1.9 KB)

Chunks:

Entry Chunk Load Size (gz)
./js index.js initial 4.2 KB
./js chunk initial 120 B
./js apache-arrow lazy 49 KB
./js/beta beta.js initial 20 B
./react index.js initial 427 KB
./react tslib initial 2.1 KB
./react apache-arrow lazy 49 KB
./react/beta beta.js initial 1.0 KB

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🤖 AppKit PR bot

🔬 Run evals

Start an eval for this PR from the evals-monitor app: Go to Evals Monitor →

📦 Try this PR's app template

Scaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh auth login — and the Databricks CLI):

gh run download 31018254689 -R databricks/appkit -n appkit-template-0.54.0-pr.0c0f748-feat-ai-search-columns-lint-513 -D appkit-pr-513 \
  && unzip -o "appkit-pr-513/appkit-template-0.54.0-pr.0c0f748-feat-ai-search-columns-lint-513.zip" -d "appkit-pr-513" \
  && databricks apps init --template "appkit-pr-513"

The template pins @databricks/appkit and @databricks/appkit-ui to tarballs built from this branch, so the scaffolded app runs against this PR's code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant