@forinda/kickjs-cli 8.8.0 → 8.9.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/dist/{agent-docs-BsXKM5QH.mjs → agent-docs-DUB-1Z6Q.mjs} +34 -13
- package/dist/{agent-docs-BsXKM5QH.mjs.map → agent-docs-DUB-1Z6Q.mjs.map} +1 -1
- package/dist/{agent-docs-DQksWOe5.mjs → agent-docs-bVMPt2m5.mjs} +33 -12
- package/dist/{build-Bnd_mk4h.mjs → build-C30mBgw6.mjs} +3 -3
- package/dist/{build-Bnd_mk4h.mjs.map → build-C30mBgw6.mjs.map} +1 -1
- package/dist/{build-DPUojF2G.mjs → build-xQXbdDpw.mjs} +2 -2
- package/dist/{builtins-BEBO5upe.mjs → builtins-CtpLZ4FY.mjs} +2 -2
- package/dist/{builtins-CJTP3xQj.mjs → builtins-DiWfXc-D.mjs} +115 -101
- package/dist/cli.mjs +2 -2
- package/dist/{config-ty1Nc3PN.mjs → config-YvIngROH.mjs} +2 -2
- package/dist/{config-F9g6CNDA.mjs → config-ZHuFjsKI.mjs} +3 -3
- package/dist/config-ZHuFjsKI.mjs.map +1 -0
- package/dist/{doctor-C8TAKn1d.mjs → doctor-CnsnRW7T.mjs} +4 -4
- package/dist/{doctor-C8TAKn1d.mjs.map → doctor-CnsnRW7T.mjs.map} +1 -1
- package/dist/{fs-BGHl3dHm.mjs → fs-Bm2St4gk.mjs} +1 -1
- package/dist/{fs-BB3QxPj8.mjs → fs-BvGbbHY0.mjs} +2 -2
- package/dist/{fs-BB3QxPj8.mjs.map → fs-BvGbbHY0.mjs.map} +1 -1
- package/dist/fullstack-B0g06sSQ.mjs +96 -0
- package/dist/fullstack-B0g06sSQ.mjs.map +1 -0
- package/dist/fullstack-CZ9XQYk-.mjs +95 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{plugin-C4Dl_s4-.mjs → plugin-BfdvW6_r.mjs} +2 -2
- package/dist/{plugin-Y7BoYk1K.mjs → plugin-Bs0soxrU.mjs} +2 -2
- package/dist/{project-3LsfnPLE.mjs → project-B_qDdkYQ.mjs} +89 -23
- package/dist/project-B_qDdkYQ.mjs.map +1 -0
- package/dist/{project-BIq7_Fzk.mjs → project-Bp-KfBNb.mjs} +88 -22
- package/dist/{project-root-CFrn6ftT.mjs → project-root-B9BrO1na.mjs} +3 -3
- package/dist/{project-root-CFrn6ftT.mjs.map → project-root-B9BrO1na.mjs.map} +1 -1
- package/dist/{project-root-BDRPMlb9.mjs → project-root-LYOxQHXp.mjs} +2 -2
- package/dist/{prompts-BJTp1w0l.mjs → prompts-BEAqcbPT.mjs} +2 -2
- package/dist/{prompts-BJTp1w0l.mjs.map → prompts-BEAqcbPT.mjs.map} +1 -1
- package/dist/{rolldown-runtime-OACgOwtl.mjs → rolldown-runtime-Da-NDvKz.mjs} +1 -1
- package/dist/{run-plugins-2DJy76gx.mjs → run-plugins-0AfIgIsZ.mjs} +89 -75
- package/dist/run-plugins-0AfIgIsZ.mjs.map +1 -0
- package/dist/{typegen-BBzX2LDz.mjs → typegen-BzgWveE_.mjs} +5 -5
- package/dist/{typegen-BBzX2LDz.mjs.map → typegen-BzgWveE_.mjs.map} +1 -1
- package/dist/{typegen-COAIhZZ4.mjs → typegen-up-UkaNc.mjs} +4 -4
- package/dist/{types-gy6PkRFW.mjs → types-ChFFRT8E.mjs} +1 -1
- package/package.json +3 -3
- package/templates/base/files/src/serverless.ts +6 -0
- package/templates/host-config/files/netlify.toml +1 -1
- package/templates/template-inertia/files/src/index.ts +4 -2
- package/templates/template-inertia/files/vite.client.config.ts +14 -3
- package/templates/template-inertia/files/vite.config.ts +9 -5
- package/dist/config-F9g6CNDA.mjs.map +0 -1
- package/dist/fullstack-D25STbVk.mjs +0 -95
- package/dist/fullstack-DWcfo-zl.mjs +0 -96
- package/dist/fullstack-DWcfo-zl.mjs.map +0 -1
- package/dist/project-3LsfnPLE.mjs.map +0 -1
- package/dist/run-plugins-2DJy76gx.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @forinda/kickjs-cli v8.
|
|
2
|
+
* @forinda/kickjs-cli v8.9.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Felix Orinda
|
|
5
5
|
*
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
-
import{t as e}from"./rolldown-runtime-
|
|
11
|
+
import{t as e}from"./rolldown-runtime-Da-NDvKz.mjs";import{r as t}from"./fs-BvGbbHY0.mjs";import{t as n}from"./prompts-BEAqcbPT.mjs";import{o as r}from"./config-ZHuFjsKI.mjs";import{join as i}from"node:path";import{existsSync as a,readFileSync as o}from"node:fs";function s(e,t,n){return`# CLAUDE.md — ${e}
|
|
12
12
|
|
|
13
13
|
**Read \`./.agents/AGENTS.md\` first.** It is the canonical, multi-agent
|
|
14
14
|
reference for this project (Claude, Copilot, Codex, Gemini, etc.) —
|
|
@@ -675,27 +675,45 @@ kick g config --force --repo postgres # Drop a kick.config.ts i
|
|
|
675
675
|
- Writing \`"name:type?"\` for optional scaffold fields — \`?\` is a shell glob in bash/zsh; use \`name:type:optional\`.
|
|
676
676
|
- Running \`kick new <name> --yes\` in a non-empty directory expecting it to wipe — \`--yes\` aborts without \`--force\`; pair them when destruction is intended.
|
|
677
677
|
- Skipping \`kick g config\` on a legacy project then wondering why generators ignore \`modules.dir\` / \`modules.repo\`.
|
|
678
|
-
- Editing \`kick.config.ts\` with deprecated top-level \`modulesDir\` / \`defaultRepo\` / \`schemaDir\` / \`pluralize\` instead of the nested \`modules\` block.`},{slug:`route-flags`,frontmatterName:`kickjs-route-flags`,description:`Use when a fact about a route (public, CSRF-exempt, unmetered, expose as a tool) has to be read by auth, CSRF, rate limiting, OpenAPI or MCP — instead of repeating it as paths in each consumer.`,body:"A route flag is a named, inheritable fact about a route. It carries no\nbehaviour: it records something every consumer can read, so \"this endpoint is\nopen\" is declared once instead of restated as an auth contributor, a\n`csrf ignorePaths` entry and a `rateLimit skipPaths` entry — two of which are\npathname strings that cannot express `/users/:id`.\n\n**Steps**:\n1. Declare it once, in its own module:\n ```ts\n import { defineRouteFlag } from '@forinda/kickjs'\n\n export const Public = defineRouteFlag('auth.public')\n export const Limit = defineRouteFlag<{ rpm: number }>('rate.limit')\n ```\n2. Apply it. A class flag is inherited by every route under it; `.off` on a\n method removes it:\n ```ts\n @Public // every route below inherits it\n @Controller()\n export class WebhooksController {\n @Get('/health')\n health(ctx: RequestContext) {} // public\n\n @Public.off // the method wins\n @Post('/admin')\n admin(ctx: RequestContext) {} // not public\n\n @Limit({ rpm: 10 }) // flags can carry a value\n @Post('/login')\n login(ctx: RequestContext) {}\n }\n ```\n3. Read it from the consumer that already exists, rather than a new one.\n **Where a consumer is mounted decides how it reads flags** — everything\n after route matching gets `ctx.route`; anything before it does not:\n\n | Consumer | Mounted at | Reads flags by |\n | --- | --- | --- |\n | Handler | the route itself | `ctx.route?.flags.has('auth.public')` |\n | Guard / `@Middleware()` | `@Middleware(fn)` on a method or controller class | `ctx.route`, or the built-ins' `exemptWhen` |\n | `csrfGuard()` / `rateLimitGuard()` | same — `@Middleware()`, class or method | `exemptWhen: 'csrf.exempt'` |\n | Contributor | method > class > module `contributors()` > adapter `contributors()` > `bootstrap({ contributors })` | `skipWhen` / `onlyWhen` on the registration |\n | Global middleware (`rateLimit()`) | `bootstrap({ middlewares: [...] })` — runs **before** matching | the route policy table (`bindRoutePolicy`); `ctx.route` is `undefined` here |\n | Adapter middleware | `AppAdapter.middleware()`, phase `beforeGlobal` … `afterRoutes` | the policy table — the handler is Express-style `(req, res, next)`, so there is no `ctx` in any phase |\n | OpenAPI | `SwaggerAdapter({ publicFlag: 'auth.public' })` | read once at startup, not per request |\n | MCP / AI tools | `McpAdapter({ exposeWhen: 'mcp.tool', hideWhen: 'mcp.hidden' })` | read once at startup |\n\n The contributor row is the one that buys the most: those five levels mean a\n plugin's contributor can be skipped on one route (`skipWhen`) without\n forking it, and a method-level registration beats the adapter's.\n\n4. Run `kick typegen`. It writes the `KickRouteFlags` augmentation, so flag\n names autocomplete and a typo fails `tsc` instead of silently never matching.\n\n**Red flags**:\n- Writing `@Public(false)` to remove a flag — removal is `@Public.off`. A\n resolved flag is present or absent; `false` is a legitimate *value* for a\n flag declared `boolean`, and a presence check would still answer `true`.\n- A new consumer growing its own `skipPaths` / `ignorePaths` list — that is\n the duplication flags exist to remove, and path strings break on params and\n on any `apiPrefix` change.\n- `@Public.off` on a route that never inherited the flag — a no-op, and\n usually a sign the expected class-level flag is not there.\n- Reading `ctx.route` in global middleware — it is `undefined` before a route\n is matched (steps 1-6 of the pipeline). Move the check into a guard mounted\n with `@Middleware()`, or read the policy table.\n- Inventing a flag name per consumer (`auth.open`, `public`, `isPublic`). The\n framework names none of them; pick one name per fact and reuse it."},{slug:`cli-plugin`,frontmatterName:`kickjs-cli-plugin`,description:`Use when adding a kick <name> command, a kick g <name> generator, or a typegen emitter to this project or a package it ships.`,body:"A CLI plugin contributes commands, generators and typegen emitters to the\n`kick` CLI. Every built-in command ships as one, so the contract is the same\none the framework uses.\n\n**Steps**:\n1. Write the plugin. All four contribution kinds are optional:\n ```ts\n // kick-tool.ts\n import { defineCliPlugin } from '@forinda/kickjs-cli'\n\n export const toolPlugin = (options: { watch?: boolean } = {}) =>\n defineCliPlugin({\n // Stable id, unique across plugins — it names the plugin in conflict errors.\n name: 'my-tool',\n // Declarative: same shape as kick.config.ts `commands`.\n commands: [{ name: 'db:migrate', description: 'Apply migrations', steps: 'node ./scripts/migrate.js' }],\n // Programmatic: full commander API, when you need options or subcommands.\n register(program, ctx) {\n program\n .command('my-tool')\n .description('Do the thing')\n .option('--watch', 'Watch mode')\n .action(async () => {\n ctx.log(`running in ${ctx.projectRoot}`)\n // ctx.config is the loaded kick.config.ts\n })\n },\n })\n ```\n2. Register it in `kick.config.ts`:\n ```ts\n import { toolPlugin } from './kick-tool'\n\n export default defineConfig({ plugins: [toolPlugin()] })\n ```\n3. Check it is loaded, per contribution kind: `kick --help` lists a command,\n `kick g --list` lists a generator, `kick typegen` runs an emitter. A\n plugin that fails to load takes the whole CLI down with a conflict error,\n so silence here means the config never referenced it.\n\n**Which kind to use**: `commands` for a shell one-liner, `register` for\noptions / subcommands / async work, `generators` (`defineGenerator`) for\n`kick g <name>` scaffolders, `typegens` for a file under `.kickjs/types/`.\n\n**Red flags**:\n- Confusing this with a runtime plugin: `defineCliPlugin` (from\n `@forinda/kickjs-cli`) extends the CLI; `definePlugin` (from\n `@forinda/kickjs`) hooks the running app. They share nothing.\n- Claiming a command name a built-in owns (`build:netlify`, `typegen`,\n `generate`) — duplicate declarative names are a startup conflict, and\n `register` has no conflict detection at all, so it silently loses. Namespace\n your own (`my-tool:build`).\n- Doing real work inside `register` — it runs at CLI startup for every\n command, so it must only register. Put the work in the action.\n- Importing heavy dependencies at module scope. `await import()` them inside\n the action, so an unrelated `kick dev` does not pay for them."},{slug:`deploy`,frontmatterName:`kickjs-deploy`,description:`Use when deploying this app — Netlify, Vercel or Cloudflare Workers — or when an API route returns the SPA shell, the platform build fails, or the function is missing from a deploy.`,body:`**
|
|
678
|
+
- Editing \`kick.config.ts\` with deprecated top-level \`modulesDir\` / \`defaultRepo\` / \`schemaDir\` / \`pluralize\` instead of the nested \`modules\` block.`},{slug:`route-flags`,frontmatterName:`kickjs-route-flags`,description:`Use when a fact about a route (public, CSRF-exempt, unmetered, expose as a tool) has to be read by auth, CSRF, rate limiting, OpenAPI or MCP — instead of repeating it as paths in each consumer.`,body:"A route flag is a named, inheritable fact about a route. It carries no\nbehaviour: it records something every consumer can read, so \"this endpoint is\nopen\" is declared once instead of restated as an auth contributor, a\n`csrf ignorePaths` entry and a `rateLimit skipPaths` entry — two of which are\npathname strings that cannot express `/users/:id`.\n\n**Steps**:\n1. Declare it once, in its own module:\n ```ts\n import { defineRouteFlag } from '@forinda/kickjs'\n\n export const Public = defineRouteFlag('auth.public')\n export const Limit = defineRouteFlag<{ rpm: number }>('rate.limit')\n ```\n2. Apply it. A class flag is inherited by every route under it; `.off` on a\n method removes it:\n ```ts\n @Public // every route below inherits it\n @Controller()\n export class WebhooksController {\n @Get('/health')\n health(ctx: RequestContext) {} // public\n\n @Public.off // the method wins\n @Post('/admin')\n admin(ctx: RequestContext) {} // not public\n\n @Limit({ rpm: 10 }) // flags can carry a value\n @Post('/login')\n login(ctx: RequestContext) {}\n }\n ```\n3. Read it from the consumer that already exists, rather than a new one.\n **Where a consumer is mounted decides how it reads flags** — everything\n after route matching gets `ctx.route`; anything before it does not:\n\n | Consumer | Mounted at | Reads flags by |\n | --- | --- | --- |\n | Handler | the route itself | `ctx.route?.flags.has('auth.public')` |\n | Guard / `@Middleware()` | `@Middleware(fn)` on a method or controller class | `ctx.route`, or the built-ins' `exemptWhen` |\n | `csrfGuard()` / `rateLimitGuard()` | same — `@Middleware()`, class or method | `exemptWhen: 'csrf.exempt'` |\n | Contributor | method > class > module `contributors()` > adapter `contributors()` > `bootstrap({ contributors })` | `skipWhen` / `onlyWhen` on the registration |\n | Global middleware (`rateLimit()`) | `bootstrap({ middlewares: [...] })` — runs **before** matching | the route policy table (`bindRoutePolicy`); `ctx.route` is `undefined` here |\n | Adapter middleware | `AppAdapter.middleware()`, phase `beforeGlobal` … `afterRoutes` | the policy table — the handler is Express-style `(req, res, next)`, so there is no `ctx` in any phase |\n | OpenAPI | `SwaggerAdapter({ publicFlag: 'auth.public' })` | read once at startup, not per request |\n | MCP / AI tools | `McpAdapter({ exposeWhen: 'mcp.tool', hideWhen: 'mcp.hidden' })` | read once at startup |\n\n The contributor row is the one that buys the most: those five levels mean a\n plugin's contributor can be skipped on one route (`skipWhen`) without\n forking it, and a method-level registration beats the adapter's.\n\n4. Run `kick typegen`. It writes the `KickRouteFlags` augmentation, so flag\n names autocomplete and a typo fails `tsc` instead of silently never matching.\n\n**Red flags**:\n- Writing `@Public(false)` to remove a flag — removal is `@Public.off`. A\n resolved flag is present or absent; `false` is a legitimate *value* for a\n flag declared `boolean`, and a presence check would still answer `true`.\n- A new consumer growing its own `skipPaths` / `ignorePaths` list — that is\n the duplication flags exist to remove, and path strings break on params and\n on any `apiPrefix` change.\n- `@Public.off` on a route that never inherited the flag — a no-op, and\n usually a sign the expected class-level flag is not there.\n- Reading `ctx.route` in global middleware — it is `undefined` before a route\n is matched (steps 1-6 of the pipeline). Move the check into a guard mounted\n with `@Middleware()`, or read the policy table.\n- Inventing a flag name per consumer (`auth.open`, `public`, `isPublic`). The\n framework names none of them; pick one name per fact and reuse it."},{slug:`cli-plugin`,frontmatterName:`kickjs-cli-plugin`,description:`Use when adding a kick <name> command, a kick g <name> generator, or a typegen emitter to this project or a package it ships.`,body:"A CLI plugin contributes commands, generators and typegen emitters to the\n`kick` CLI. Every built-in command ships as one, so the contract is the same\none the framework uses.\n\n**Steps**:\n1. Write the plugin. All four contribution kinds are optional:\n ```ts\n // kick-tool.ts\n import { defineCliPlugin } from '@forinda/kickjs-cli'\n\n export const toolPlugin = (options: { watch?: boolean } = {}) =>\n defineCliPlugin({\n // Stable id, unique across plugins — it names the plugin in conflict errors.\n name: 'my-tool',\n // Declarative: same shape as kick.config.ts `commands`.\n commands: [{ name: 'db:migrate', description: 'Apply migrations', steps: 'node ./scripts/migrate.js' }],\n // Programmatic: full commander API, when you need options or subcommands.\n register(program, ctx) {\n program\n .command('my-tool')\n .description('Do the thing')\n .option('--watch', 'Watch mode')\n .action(async () => {\n ctx.log(`running in ${ctx.projectRoot}`)\n // ctx.config is the loaded kick.config.ts\n })\n },\n })\n ```\n2. Register it in `kick.config.ts`:\n ```ts\n import { toolPlugin } from './kick-tool'\n\n export default defineConfig({ plugins: [toolPlugin()] })\n ```\n3. Check it is loaded, per contribution kind: `kick --help` lists a command,\n `kick g --list` lists a generator, `kick typegen` runs an emitter. A\n plugin that fails to load takes the whole CLI down with a conflict error,\n so silence here means the config never referenced it.\n\n**Which kind to use**: `commands` for a shell one-liner, `register` for\noptions / subcommands / async work, `generators` (`defineGenerator`) for\n`kick g <name>` scaffolders, `typegens` for a file under `.kickjs/types/`.\n\n**Red flags**:\n- Confusing this with a runtime plugin: `defineCliPlugin` (from\n `@forinda/kickjs-cli`) extends the CLI; `definePlugin` (from\n `@forinda/kickjs`) hooks the running app. They share nothing.\n- Claiming a command name a built-in owns (`build:netlify`, `typegen`,\n `generate`) — duplicate declarative names are a startup conflict, and\n `register` has no conflict detection at all, so it silently loses. Namespace\n your own (`my-tool:build`).\n- Doing real work inside `register` — it runs at CLI startup for every\n command, so it must only register. Put the work in the action.\n- Importing heavy dependencies at module scope. `await import()` them inside\n the action, so an unrelated `kick dev` does not pay for them."},{slug:`deploy`,frontmatterName:`kickjs-deploy`,description:`Use when deploying this app — a Node host or Docker, Netlify, Vercel or Cloudflare Workers — or when an API route returns the SPA shell, the platform build fails, or the function is missing from a deploy.`,body:`**A Node host or a container** runs the long-running server. The project
|
|
679
|
+
ships a \`Dockerfile\`; without Docker:
|
|
680
|
+
|
|
681
|
+
\`\`\`bash
|
|
682
|
+
${e} run build && NODE_ENV=production node dist/index.js
|
|
683
|
+
\`\`\`
|
|
684
|
+
|
|
685
|
+
Start it with \`node\`, not \`kick start\`: the CLI is a dev dependency, gone
|
|
686
|
+
after a production install. The image installs from the lockfile, so commit it.
|
|
687
|
+
|
|
688
|
+
**Netlify and Vercel** run the app as a Node function; the CLI builds both:
|
|
679
689
|
|
|
680
690
|
\`\`\`bash
|
|
681
691
|
${e} run build:netlify # → .netlify/v1/functions/api.mjs
|
|
682
692
|
${e} run build:vercel # → .vercel/output (Build Output API v3)
|
|
683
693
|
\`\`\`
|
|
684
694
|
|
|
685
|
-
Both bundle \`src/serverless.ts
|
|
686
|
-
|
|
687
|
-
|
|
695
|
+
Both bundle \`src/serverless.ts\`:
|
|
696
|
+
\`createHandler(() => import('./index'))\` serves the app \`src/index.ts\`
|
|
697
|
+
describes — its \`bootstrap()\` call builds the app without listening — so
|
|
698
|
+
there is one set of options. Add middleware and adapters to \`src/index.ts\`
|
|
699
|
+
as usual.
|
|
688
700
|
|
|
689
701
|
Settings are detected from the layout: a workspace member beside a \`web\`
|
|
690
|
-
package publishes \`web/dist\` and routes \`/api/*\`;
|
|
691
|
-
|
|
702
|
+
package publishes \`web/dist\` and routes \`/api/*\`; an Inertia app publishes
|
|
703
|
+
\`dist/client\`, packages the asset manifest and SSR bundle with the function,
|
|
704
|
+
and lets it take every other path; a standalone API takes every path.
|
|
705
|
+
Override in \`kick.config.ts\`:
|
|
692
706
|
|
|
693
707
|
\`\`\`ts
|
|
694
708
|
export default defineConfig({
|
|
695
|
-
deploy: { apiPath: '/api', staticDir: '../web/dist' },
|
|
709
|
+
deploy: { apiPath: '/api', staticDir: '../web/dist', include: ['data/geo.json'] },
|
|
696
710
|
})
|
|
697
711
|
\`\`\`
|
|
698
712
|
|
|
713
|
+
\`include\` lists files the app reads at runtime; they are packaged with the
|
|
714
|
+
function. Memory does not survive between function instances: keep sessions in
|
|
715
|
+
\`session({ store: 'cookie' })\` or a shared store, and data in a database.
|
|
716
|
+
|
|
699
717
|
**Cloudflare Workers** is a different entry, not a third flag on this one.
|
|
700
718
|
Workers have no \`node:http\`, so \`createHandler\` cannot run there; use the
|
|
701
719
|
web entry over h3 v2:
|
|
@@ -734,14 +752,17 @@ plugins. Serve static files from Workers Assets or a separate deploy.
|
|
|
734
752
|
**Red flags**:
|
|
735
753
|
- An \`/api/*\` route returning \`index.html\` on Netlify — the function is not
|
|
736
754
|
routed. Check the deploy summary says a function was deployed, keep
|
|
737
|
-
\`preferStatic\` out of
|
|
738
|
-
unset so it reads the function at the repo root.
|
|
755
|
+
\`preferStatic\` out of a fullstack function's config, and leave Netlify's
|
|
756
|
+
**Package directory** unset so it reads the function at the repo root.
|
|
757
|
+
- Validation errors or flash messages that vanish on Netlify / Vercel — the
|
|
758
|
+
session lives in one instance's memory. Use \`session({ store: 'cookie' })\`.
|
|
739
759
|
- Committing \`.netlify/\` or \`.vercel/\` — both are build output.
|
|
740
760
|
- A frontend that builds somewhere other than \`web/dist\` and only one of
|
|
741
761
|
\`deploy.staticDir\`, \`SpaAdapter({ clientDir })\` and netlify.toml's
|
|
742
762
|
\`publish\` updated. All three name that directory.
|
|
743
763
|
- Pointing a platform at \`src/index.ts\` — it calls \`bootstrap()\`, which
|
|
744
|
-
listens on a port and registers signal handlers inside the function.
|
|
764
|
+
listens on a port and registers signal handlers inside the function. The
|
|
765
|
+
platform entry is \`src/serverless.ts\`.
|
|
745
766
|
- Expecting \`kick build\` alone to produce a deployable function; it builds
|
|
746
767
|
the server. Run the target command after it.`},{slug:`docs-lookup`,frontmatterName:`kickjs-docs-lookup`,description:`Use FIRST when unsure about any KickJS API, option, or behaviour — before guessing from memory or inferring from surrounding code.`,body:`These skills are deliberately short — they cover the traps, not the whole API
|
|
747
768
|
surface. When the answer is not in one of them, read the docs rather than
|
|
@@ -852,4 +873,4 @@ Codex / Cursor / Gemini / Claude Code without copy-pasting.
|
|
|
852
873
|
CLI template. Hand-edited content is overwritten — keep customisation
|
|
853
874
|
in \`.agents/COPILOT.local.md\`.
|
|
854
875
|
`}var p=/* @__PURE__ */ e({generateAgentDocs:()=>b});const m=`.agents`,h=/* @__PURE__ */ new Set([`rest`,`minimal`,`fullstack`,`inertia`]);function g(e,t){if(t)return t;try{let t=JSON.parse(o(i(e,`package.json`),`utf-8`));if(t.name)return t.name.replace(/^@[^/]+\//,``)}catch{}return e.split(`/`).findLast(Boolean)??`app`}function _(e,t){if(t)return t;try{let t=JSON.parse(o(i(e,`package.json`),`utf-8`));if(t.packageManager)return t.packageManager.split(`@`)[0]}catch{}return`pnpm`}async function v(e){try{return(await r(e))?.modules?.style===`class`?`class`:`define`}catch{return`define`}}async function y(e,t){if(t)return t;try{let t=(await r(e))?.pattern;if(t&&h.has(t))return t}catch{}return`rest`}async function b(e){let r=e.only??`all`,o=g(e.outDir,e.name),l=_(e.outDir,e.pm),p=await y(e.outDir,e.template),h=await v(e.outDir),b=r===`agents`||r===`both`||r===`all`,x=r===`claude`||r===`both`||r===`all`,S=r===`skills`||r===`all`,C=r===`gemini`||r===`all`,w=r===`copilot`||r===`all`,T=[];if(b&&T.push({file:i(e.outDir,m,`AGENTS.md`),render:()=>c(o,p,l)}),x&&T.push({file:i(e.outDir,`CLAUDE.md`),render:()=>s(o,p,l)}),S)for(let t of u(o,p,l,h))T.push({file:i(e.outDir,m,`skills`,t.slug,`SKILL.md`),render:()=>t.content});C&&T.push({file:i(e.outDir,m,`GEMINI.md`),render:()=>d(o,p,l)}),w&&T.push({file:i(e.outDir,m,`COPILOT.md`),render:()=>f(o,p,l)});let E=[];for(let{file:r,render:i}of T)a(r)&&!e.force&&!await n({message:`${r.replace(e.outDir+`/`,``)} already exists. Overwrite?`,initialValue:!1})?console.log(` Skipped — existing ${r.replace(e.outDir+`/`,``)} preserved.`):(await t(r,i()),E.push(r));return E}export{b as n,p as t};
|
|
855
|
-
//# sourceMappingURL=agent-docs-
|
|
876
|
+
//# sourceMappingURL=agent-docs-DUB-1Z6Q.mjs.map
|