尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Maintenance notice: any change that alters setup commands, workspace
layout, auth model, data layer, or the engine API must update this file and
docs/ARCHITECTURE.md in the same pull request. Doc
accuracy is part of review.查看完整 README ↗Maintenance notice: any change that alters setup commands, workspace layout, auth model, data layer, or the engine API must update this file and docs/ARCHITECTURE.md in the same pull request. Doc accuracy is part of review.
Unfiltered replaces rigid filter-based product search on fashion Shopify stores with free-text search that understands how shoppers actually describe what they want ("elegant summer wedding dress, not black, under ₪400"), in any language, and proves its value to the merchant in attributed orders. It ships as a self-serve Shopify app backed by a catalog-agnostic search engine.
npm-workspaces monorepo with three workspaces:
| Workspace | Purpose |
|---|---|
apps/shopify-app | Embedded Shopify app (official Shopify React Router + TypeScript template). Consumes the engine as a client. |
packages/engine | Catalog-agnostic search engine with a versioned, typed public API: the wish extraction, the judge, the enrichment vocabularies and the classic keyword-search port — all data and AI access through vendor-free ports (LLM, decision model, embedding, cost metering, classic-search store). |
packages/provider-gemini | Google AI Studio (Gemini) adapter implementing the engine's LLM and embedding ports, metered through the cost-recorder port. |
After a result set, "same but cheaper" or "בלי שרוולים" means modify that
search, not start a new one. Every submitted response carries a carry —
the chain's first sentence plus its two most recent refinements — and the
client sends it back as previousQuery on the next search. The find step,
the wish extraction and the judge read it; the extraction also answers
whether the new sentence refines the chain or replaces it ("nike air max 90"
starts a new one). The server stores nothing between searches: the client
holds the carry. See docs/ARCHITECTURE.md for the
full contract and apps/shopify-app/app/search/refinement.test.ts for the
tests that pin the behavior.
Requires Node.js >=20.19 <22 || >=22.12.
Install all workspaces from the repo root:
npm install
TypeScript strict is enabled in every workspace. From the root:
npm run typecheck
Vitest runs the test suites of both workspaces, including the boundary test
that fails if packages/engine ever references a @shopify/* package:
npm test
ESLint runs per workspace via:
npm run lint
UI tests (Playwright) drive the storefront widget against its local dev harness — no Shopify and no network:
npm run test:ui
All four commands run in CI (.github/workflows/ci.yml) on every pull
request and must pass before merge.
The storefront search widget lives in apps/shopify-app/widget/
(TypeScript + CSS, bundled by Vite) and ships to themes through the theme
app extension in apps/shopify-app/extensions/unfiltered-widget/: an app
embed block loads the built assets and calls
window.UnfilteredWidget.init({ locale, storeId }) with the storefront
locale and shop domain. Build the self-contained bundle into the extension's
assets/ (the output is committed):
npm run build:widget
For manual development, the same Vite config serves a fake storefront harness (theme-like search form + stubbed search endpoint, no Shopify):
npm run widget:harness --workspace app
# http://127.0.0.1:4173 and /no-search-form.html
The app runs through the Shopify CLI, which needs a Shopify Partner login and
a development store (see .env.example for the placeholder variables the app
reads):
npm run dev --workspace app
To smoke-test without Shopify credentials, build and start the server directly with placeholder env values, then hit the health route that exercises the engine wiring:
npm run build
npx prisma generate --schema apps/shopify-app/prisma/schema.prisma
SHOPIFY_API_KEY=placeholder SHOPIFY_API_SECRET=placeholder \
SHOPIFY_APP_URL=https://localhost:3000 SCOPES=write_products \
npm run start --workspace app
# in another shell:
curl http://localhost:3000/healthz
/healthz returns the engine version and a typed empty search result from
the engine stub.
Ingest a public store's catalog and share the playground over it:
npm run ingest:public --workspace app -- \
--url https://store.example.com --slug store-example --name "Store Example"
# then share https://<deployment>/s/store-example
/s/<slug> is the playground with that catalog preloaded; the store's name
is the only thing the page adds, and the page is noindex. An unknown slug
answers a designed 404, never the seed catalog. See
docs/ARCHITECTURE.md.
The playground runs as a Docker web service on Render, built from the
repo-root Dockerfile and described by render.yaml. The image builds every
workspace and the entrypoint applies migrations before serving; a container
without DATABASE_URL refuses to start. Full setup, environment values,
free-plan behavior, rollback, and custom-domain steps live in
docs/DEPLOY.md.
docker build -t unfiltered .
CI builds the same image on every pull request.