Quickstart
This chapter is the fastest reproducible path to a real JSKIT app.
The base flow below gives you:
- personal workspaces
- users
- console
- MySQL
- Supabase auth
- one
adminassistant configured fromconsole
It also shows the first page-extension moves most apps need:
- add two workspace settings pages
- make one of them the default landing page
- add a page to the admin cog
- add a normal left-menu page
- inspect placement destinations and understand why some links are inferred automatically
Step 1: Create the app
Set these values first:
OPENAI_API_KEY=...
SUPABASE_URL=...
SUPABASE_KEY=...
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=testapp
DB_USER=...
DB_PASSWORD=...Before continuing, make sure the MySQL database already exists and that the chosen DB_USER / DB_PASSWORD can connect to it. If the database does not exist yet, create it first or use a local MySQL account with enough privileges to create it before the runtime install step.
Then run the exact sequence below:
npx @jskit-ai/create-app testapp --tenancy-mode personal
cd testapp
npm install
npx jskit add package auth-provider-supabase-core \
--auth-supabase-url "$SUPABASE_URL" \
--auth-supabase-publishable-key "$SUPABASE_KEY" \
--app-public-url "http://localhost:5173"
npx jskit add bundle auth-base
npx jskit add package database-runtime-mysql \
--db-host "$DB_HOST" \
--db-port "$DB_PORT" \
--db-name "$DB_NAME" \
--db-user "$DB_USER" \
--db-password "$DB_PASSWORD"
npx jskit add package users-web
npx jskit add package console-web
npx jskit add package workspaces-core
npx jskit add package workspaces-web
npx jskit generate assistant setup \
--surface admin \
--settings-surface console \
--config-scope global \
--ai-provider openai \
--ai-api-key "$OPENAI_API_KEY"
npx jskit generate assistant page \
w/[workspaceSlug]/admin/assistant/index.vue \
--name "Assistant"
npx jskit generate assistant settings-page \
console/settings/admin-assistant/index.vue \
--surface admin \
--name "Admin Assistant"
npm install
npm run db:migrateAt this point you have:
- a workspace-enabled app with
tenancyMode = "personal" - an
adminassistant at/w/[workspaceSlug]/admin/assistant - an assistant settings page at
/console/settings/admin-assistant
Step 2: Add two workspace settings pages
Generate two child pages under the workspace settings host:
npx jskit generate ui-generator page \
w/[workspaceSlug]/admin/workspace/settings/billing/index.vue \
--name "Billing"
npx jskit generate ui-generator page \
w/[workspaceSlug]/admin/workspace/settings/branding/index.vue \
--name "Branding"These commands create:
src/pages/w/[workspaceSlug]/admin/workspace/settings/billing/index.vuesrc/pages/w/[workspaceSlug]/admin/workspace/settings/branding/index.vue
They also append matching menu entries into src/placement.js.
Step 3: Make one settings page the default
Best practice is to make the default child explicit.
Edit:
src/pages/w/[workspaceSlug]/admin/workspace/settings/index.vueand replace its contents with:
<script setup>
import { redirectToChild } from "@jskit-ai/kernel/client/pageRedirects";
definePage({
redirect: redirectToChild("billing")
});
</script>That makes /w/[workspaceSlug]/admin/workspace/settings land on /w/[workspaceSlug]/admin/workspace/settings/billing.
Use this explicit redirect pattern instead of trying to infer the default child from placement order or “the first generated page”.
Step 4: Add a page to the admin cog
First list the available placement destinations:
npx jskit list-placementsIn a workspace-enabled app, that output includes the semantic admin.tools-menu placement.
Then generate the page:
npx jskit generate ui-generator page \
w/[workspaceSlug]/admin/catalogue/index.vue \
--name "Catalogue" \
--link-placement admin.tools-menu--link-placement is necessary here because this is just a normal admin page. It is not a child page under a local route host that already owns a nested outlet.
Step 5: Add a normal left-menu page
Generate a normal admin page without an explicit placement:
npx jskit generate ui-generator page \
w/[workspaceSlug]/admin/reports/index.vue \
--name "Reports"Because this page is not under a more specific local host, JSKIT falls back to the app's default shell menu outlet. In practice, that means a normal left-menu entry.
Step 6: Understand the placement "magic"
The workspace settings pages in Step 2 auto-linked into the settings menu for two reasons:
- The parent host already exposes a concrete outlet:
<ShellOutlet target="admin-settings:primary-menu" />- Your generated pages live under that host route:
w/[workspaceSlug]/admin/workspace/settings/...So JSKIT can infer both:
- the semantic placement target:
page.section-nav - the placement owner:
admin-settings
The renderer comes from src/placementTopology.js, where page.section-nav maps to the concrete admin-settings:primary-menu outlet for each layout class.
That is why the simple settings-page commands do not need --link-placement.
The admin cog example is different. w/[workspaceSlug]/admin/catalogue/index.vue is just a normal admin page, so there is no local nested host to infer. That is why you must pass --link-placement admin.tools-menu there.
If you want a little more context than the raw destination list, this is also useful:
npx jskit show @jskit-ai/workspaces-web --detailsThat output shows both the workspace-owned placement outlets and the default entries already targeting them.