@forgeailab/spark 0.2.0 → 0.4.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.
Files changed (138) hide show
  1. package/package.json +8 -6
  2. package/src/commands/add.ts +3 -1
  3. package/src/commands/preset.ts +1 -0
  4. package/src/internal/board.ts +266 -304
  5. package/src/io/board.ts +29 -65
  6. package/src/io/env.ts +8 -3
  7. package/src/io/files.ts +22 -7
  8. package/packs/README.md +0 -130
  9. package/packs/ai-anthropic/files/app/api/ai/route.ts +0 -57
  10. package/packs/ai-anthropic/files/lib/anthropic.ts +0 -58
  11. package/packs/ai-anthropic/pack.toml +0 -31
  12. package/packs/ai-anthropic/skills/ai-feature-patterns/SKILL.md +0 -87
  13. package/packs/ai-anthropic/tasks.yaml +0 -9
  14. package/packs/ai-openai/files/app/api/ai-openai/route.ts +0 -55
  15. package/packs/ai-openai/files/lib/openai.ts +0 -21
  16. package/packs/ai-openai/pack.toml +0 -30
  17. package/packs/ai-openai/tasks.yaml +0 -9
  18. package/packs/analytics-posthog/files/components/PostHogProvider.tsx +0 -19
  19. package/packs/analytics-posthog/files/lib/posthog/client.ts +0 -20
  20. package/packs/analytics-posthog/files/lib/posthog/server.ts +0 -24
  21. package/packs/analytics-posthog/pack.toml +0 -35
  22. package/packs/analytics-posthog/tasks.yaml +0 -15
  23. package/packs/auth-better-auth/files/app/(auth)/login/page.tsx +0 -58
  24. package/packs/auth-better-auth/files/app/api/auth/[...all]/route.ts +0 -4
  25. package/packs/auth-better-auth/files/lib/auth.ts +0 -60
  26. package/packs/auth-better-auth/pack.toml +0 -28
  27. package/packs/auth-better-auth/tasks.yaml +0 -10
  28. package/packs/auth-better-auth-pg/files/app/api/auth/[...all]/route.ts +0 -4
  29. package/packs/auth-better-auth-pg/files/lib/auth.ts +0 -125
  30. package/packs/auth-better-auth-pg/pack.toml +0 -28
  31. package/packs/auth-better-auth-pg/tasks.yaml +0 -17
  32. package/packs/auth-supabase/files/app/(auth)/login/page.tsx +0 -64
  33. package/packs/auth-supabase/files/app/auth/callback/route.ts +0 -15
  34. package/packs/auth-supabase/files/middleware.ts +0 -41
  35. package/packs/auth-supabase/pack.toml +0 -34
  36. package/packs/auth-supabase/tasks.yaml +0 -10
  37. package/packs/db-postgres/files/compose/postgres.yml +0 -28
  38. package/packs/db-postgres/files/docker-compose.include.yml +0 -1
  39. package/packs/db-postgres/files/docker-compose.yml +0 -6
  40. package/packs/db-postgres/files/drizzle.config.ts +0 -10
  41. package/packs/db-postgres/files/lib/db/index.ts +0 -10
  42. package/packs/db-postgres/files/lib/db/schema.ts +0 -11
  43. package/packs/db-postgres/pack.toml +0 -53
  44. package/packs/db-postgres/tasks.yaml +0 -11
  45. package/packs/db-sqlite/files/drizzle.config.ts +0 -10
  46. package/packs/db-sqlite/files/lib/db.ts +0 -8
  47. package/packs/db-sqlite/files/lib/schema.ts +0 -13
  48. package/packs/db-sqlite/pack.toml +0 -34
  49. package/packs/db-sqlite/tasks.yaml +0 -6
  50. package/packs/db-supabase/files/lib/supabase/client.ts +0 -8
  51. package/packs/db-supabase/files/lib/supabase/server.ts +0 -27
  52. package/packs/db-supabase/pack.toml +0 -32
  53. package/packs/db-supabase/skills/supabase-patterns/SKILL.md +0 -82
  54. package/packs/db-supabase/tasks.yaml +0 -6
  55. package/packs/deploy-vercel/files/docs/deploy.md +0 -21
  56. package/packs/deploy-vercel/files/vercel.json +0 -4
  57. package/packs/deploy-vercel/pack.toml +0 -30
  58. package/packs/deploy-vercel/tasks.yaml +0 -14
  59. package/packs/docker-compose-dev/files/.env.docker.example +0 -2
  60. package/packs/docker-compose-dev/files/compose/redis.yml +0 -17
  61. package/packs/docker-compose-dev/files/docker-compose.include.yml +0 -1
  62. package/packs/docker-compose-dev/files/docker-compose.yml +0 -6
  63. package/packs/docker-compose-dev/pack.toml +0 -38
  64. package/packs/docker-compose-dev/tasks.yaml +0 -9
  65. package/packs/email-resend/files/app/api/email/test/route.ts +0 -38
  66. package/packs/email-resend/files/emails/welcome.tsx +0 -66
  67. package/packs/email-resend/files/lib/email.ts +0 -40
  68. package/packs/email-resend/pack.toml +0 -34
  69. package/packs/email-resend/tasks.yaml +0 -9
  70. package/packs/example/pack.toml +0 -69
  71. package/packs/payments-stripe/files/app/api/billing-portal/route.ts +0 -24
  72. package/packs/payments-stripe/files/app/api/checkout/route.ts +0 -58
  73. package/packs/payments-stripe/files/app/api/webhooks/stripe/route.ts +0 -84
  74. package/packs/payments-stripe/files/lib/stripe.ts +0 -158
  75. package/packs/payments-stripe/pack.toml +0 -45
  76. package/packs/payments-stripe/skills/stripe-patterns/SKILL.md +0 -93
  77. package/packs/payments-stripe/tasks.yaml +0 -16
  78. package/packs/sync-zero/files/components/ZeroProvider.tsx +0 -13
  79. package/packs/sync-zero/files/compose/zero-cache.yml +0 -26
  80. package/packs/sync-zero/files/docker-compose.include.yml +0 -1
  81. package/packs/sync-zero/files/docker-compose.yml +0 -6
  82. package/packs/sync-zero/files/lib/zero/client.ts +0 -18
  83. package/packs/sync-zero/files/lib/zero/schema.ts +0 -30
  84. package/packs/sync-zero/files/zero.config.ts +0 -26
  85. package/packs/sync-zero/pack.toml +0 -57
  86. package/packs/sync-zero/skills/zero-patterns/SKILL.md +0 -69
  87. package/packs/sync-zero/tasks.yaml +0 -16
  88. package/packs/testing-playwright/files/e2e/example.spec.ts +0 -7
  89. package/packs/testing-playwright/files/playwright.config.ts +0 -33
  90. package/packs/testing-playwright/pack.toml +0 -25
  91. package/packs/testing-playwright/tasks.yaml +0 -9
  92. package/packs/ui-shadcn/files/app/globals.css +0 -56
  93. package/packs/ui-shadcn/files/components/ui/button.tsx +0 -47
  94. package/packs/ui-shadcn/files/components/ui/card.tsx +0 -33
  95. package/packs/ui-shadcn/files/lib/utils.ts +0 -6
  96. package/packs/ui-shadcn/files/postcss.config.mjs +0 -7
  97. package/packs/ui-shadcn/files/tailwind.config.ts +0 -57
  98. package/packs/ui-shadcn/pack.toml +0 -44
  99. package/packs/ui-shadcn/skills/shadcn-dashboard-patterns/SKILL.md +0 -85
  100. package/packs/ui-shadcn/tasks.yaml +0 -6
  101. package/presets/docs-site.toml +0 -4
  102. package/presets/internal-tool.toml +0 -4
  103. package/presets/lean-saas.toml +0 -4
  104. package/presets/local-ai-mvp.toml +0 -4
  105. package/presets/saas-classic.toml +0 -4
  106. package/templates/README.md +0 -43
  107. package/templates/astro/README.md +0 -3
  108. package/templates/astro/template.toml +0 -4
  109. package/templates/astro-starlight/README.md +0 -3
  110. package/templates/astro-starlight/template.toml +0 -4
  111. package/templates/nextjs/.ai/architecture.md +0 -13
  112. package/templates/nextjs/.ai/board.md +0 -7
  113. package/templates/nextjs/.ai/product-spec.md +0 -11
  114. package/templates/nextjs/.claude/skills/.gitkeep +0 -0
  115. package/templates/nextjs/.codex/skills/.gitkeep +0 -0
  116. package/templates/nextjs/AGENTS.md +0 -95
  117. package/templates/nextjs/CLAUDE.md +0 -3
  118. package/templates/nextjs/README.md +0 -20
  119. package/templates/nextjs/app/(app)/home/page.tsx +0 -43
  120. package/templates/nextjs/app/(app)/home/posts-panel.tsx +0 -83
  121. package/templates/nextjs/app/(app)/layout.tsx +0 -12
  122. package/templates/nextjs/app/(auth)/login/page.tsx +0 -97
  123. package/templates/nextjs/app/globals.css +0 -23
  124. package/templates/nextjs/app/layout.tsx +0 -20
  125. package/templates/nextjs/app/page.tsx +0 -39
  126. package/templates/nextjs/lib/auth-placeholder.ts +0 -21
  127. package/templates/nextjs/lib/posts-placeholder.ts +0 -30
  128. package/templates/nextjs/next.config.ts +0 -5
  129. package/templates/nextjs/package.json +0 -26
  130. package/templates/nextjs/postcss.config.mjs +0 -7
  131. package/templates/nextjs/spark.config.json +0 -4
  132. package/templates/nextjs/template.toml +0 -4
  133. package/templates/nextjs/tsconfig.json +0 -27
  134. package/templates/nextjs/types/post.ts +0 -13
  135. package/templates/one/README.md +0 -5
  136. package/templates/one/template.toml +0 -4
  137. package/templates/vite-react/README.md +0 -3
  138. package/templates/vite-react/template.toml +0 -4
@@ -1,16 +0,0 @@
1
- epic: Payments
2
-
3
- tasks:
4
- - id: PAY-001
5
- title: Configure products + prices in Stripe dashboard
6
- status: Clarifying
7
- acceptance:
8
- - Stripe dashboard has at least one active subscription product and recurring price.
9
- - The selected price ID is available to the checkout flow.
10
-
11
- - id: PAY-002
12
- title: Test webhook signing locally with stripe listen
13
- status: Clarifying
14
- acceptance:
15
- - Local webhook forwarding reaches app/api/webhooks/stripe.
16
- - A signed test event is accepted and unsigned payloads are rejected.
@@ -1,13 +0,0 @@
1
- 'use client';
2
-
3
- import type { ReactNode } from 'react';
4
- import type { ZeroOptions } from '@rocicorp/zero';
5
- import { ZeroProvider as RocicorpZeroProvider } from '@rocicorp/zero/react';
6
-
7
- type ZeroProviderProps = ZeroOptions & {
8
- children: ReactNode;
9
- };
10
-
11
- export function ZeroProvider({ children, ...options }: ZeroProviderProps) {
12
- return <RocicorpZeroProvider {...options}>{children}</RocicorpZeroProvider>;
13
- }
@@ -1,26 +0,0 @@
1
- services:
2
- zero-cache:
3
- image: rocicorp/zero:latest
4
- restart: unless-stopped
5
- environment:
6
- ZERO_UPSTREAM_DB: ${ZERO_UPSTREAM_DB}
7
- ZERO_CVR_DB: ${ZERO_CVR_DB:-${ZERO_UPSTREAM_DB}_cvr}
8
- ZERO_CHANGE_DB: ${ZERO_CHANGE_DB:-${ZERO_UPSTREAM_DB}_change}
9
- ZERO_REPLICA_FILE: /zero/replica.db
10
- ZERO_AUTH_SECRET: ${ZERO_AUTH_SECRET}
11
- ZERO_ADMIN_PASSWORD: ${ZERO_ADMIN_PASSWORD:-change-me}
12
- ZERO_PUSH_URL: ${ZERO_PUSH_URL:-http://host.docker.internal:3000/api/zero/mutate}
13
- ZERO_LOG_LEVEL: ${ZERO_LOG_LEVEL:-info}
14
- ZERO_NUM_SYNC_WORKERS: "1"
15
- ports:
16
- - "${ZERO_PORT:-4848}:4848"
17
- volumes:
18
- - zero_data:/zero
19
- extra_hosts:
20
- - "host.docker.internal:host-gateway"
21
- depends_on:
22
- postgres:
23
- condition: service_healthy
24
-
25
- volumes:
26
- zero_data:
@@ -1 +0,0 @@
1
- - compose/zero-cache.yml
@@ -1,6 +0,0 @@
1
- # Spark-managed Docker Compose root.
2
- #
3
- # Each infra-providing pack appends an entry below. Service definitions live
4
- # in compose/*.yml fragments. Run with `docker compose up -d` — Compose 2.20+
5
- # resolves `include:` for you.
6
- include:
@@ -1,18 +0,0 @@
1
- 'use client';
2
-
3
- import { Zero } from '@rocicorp/zero';
4
- import type { ZeroOptions } from '@rocicorp/zero';
5
- import { schema } from './schema';
6
-
7
- const DEFAULT_ZERO_URL = 'http://localhost:4848';
8
-
9
- export function createZeroOptions(): ZeroOptions {
10
- return {
11
- cacheURL: process.env.NEXT_PUBLIC_ZERO_URL ?? DEFAULT_ZERO_URL,
12
- schema,
13
- };
14
- }
15
-
16
- export function createZeroClient(options: ZeroOptions = createZeroOptions()) {
17
- return new Zero(options);
18
- }
@@ -1,30 +0,0 @@
1
- import {
2
- ANYONE_CAN,
3
- createBuilder,
4
- createSchema,
5
- definePermissions,
6
- number,
7
- string,
8
- table,
9
- } from '@rocicorp/zero';
10
-
11
- // Example schema. Replace with your app's tables.
12
- const users = table('user')
13
- .columns({
14
- id: string(),
15
- name: string(),
16
- email: string(),
17
- createdAt: number(),
18
- })
19
- .primaryKey('id');
20
-
21
- export const schema = createSchema({
22
- tables: [users],
23
- });
24
- export const zql = createBuilder(schema);
25
-
26
- export type Schema = typeof schema;
27
-
28
- export const permissions = definePermissions<unknown, Schema>(schema, () => ({
29
- user: { row: { select: ANYONE_CAN } },
30
- }));
@@ -1,26 +0,0 @@
1
- type ZeroCacheConfig = {
2
- upstreamDB: string;
3
- authSecret: string;
4
- queryURL: string;
5
- mutateURL: string;
6
- };
7
-
8
- export function getZeroCacheConfig(): ZeroCacheConfig {
9
- const upstreamDB = process.env.ZERO_UPSTREAM_DB;
10
- const authSecret = process.env.ZERO_AUTH_SECRET;
11
-
12
- if (!upstreamDB) {
13
- throw new Error("ZERO_UPSTREAM_DB is required to run zero-cache.");
14
- }
15
-
16
- if (!authSecret) {
17
- throw new Error("ZERO_AUTH_SECRET is required to authenticate Zero clients.");
18
- }
19
-
20
- return {
21
- upstreamDB,
22
- authSecret,
23
- queryURL: "http://localhost:3000/api/query",
24
- mutateURL: "http://localhost:3000/api/mutate",
25
- };
26
- }
@@ -1,57 +0,0 @@
1
- name = "sync-zero"
2
- version = "1.0.0"
3
- category = "infra"
4
- description = "Rocicorp Zero client-first sync setup for a Postgres-backed app."
5
- provides = ["sync"]
6
- requires = ["db-pg"]
7
- conflicts = ["sync"]
8
- requires_runtime = ["server"]
9
- compatible_scaffolds = ["nextjs"]
10
-
11
- [dependencies]
12
- runtime = ["@rocicorp/zero"]
13
-
14
- [env]
15
- required = ["ZERO_AUTH_SECRET", "ZERO_UPSTREAM_DB"]
16
- optional = []
17
-
18
- [[files]]
19
- mode = "create"
20
- from = "zero.config.ts"
21
- to = "zero.config.ts"
22
-
23
- [[files]]
24
- mode = "create"
25
- from = "lib/zero/schema.ts"
26
- to = "lib/zero/schema.ts"
27
-
28
- [[files]]
29
- mode = "create"
30
- from = "lib/zero/client.ts"
31
- to = "lib/zero/client.ts"
32
-
33
- [[files]]
34
- mode = "create"
35
- from = "components/ZeroProvider.tsx"
36
- to = "components/ZeroProvider.tsx"
37
-
38
- [[files]]
39
- mode = "create-or-skip"
40
- from = "docker-compose.yml"
41
- to = "docker-compose.yml"
42
-
43
- [[files]]
44
- mode = "create"
45
- from = "compose/zero-cache.yml"
46
- to = "compose/zero-cache.yml"
47
-
48
- [[files]]
49
- mode = "append"
50
- from = "docker-compose.include.yml"
51
- to = "docker-compose.yml"
52
-
53
- [skills]
54
- copy = ["skills/zero-patterns"]
55
-
56
- [tasks]
57
- file = "tasks.yaml"
@@ -1,69 +0,0 @@
1
- ---
2
- name: zero-patterns
3
- description: Use when implementing Rocicorp Zero client-first sync, schema changes, queries, mutators, or zero-cache setup in an spark project.
4
- ---
5
-
6
- # Zero Patterns
7
-
8
- ## Core Model
9
-
10
- Zero is client-first. Reads should feel local because the client queries its
11
- local store first, then syncs with `zero-cache` and the upstream Postgres
12
- database in the background.
13
-
14
- Do not treat Zero as a REST wrapper. Keep query definitions and mutators as
15
- the product contract. Components consume those contracts through Zero React
16
- helpers instead of hand-building fetch calls for synced data.
17
-
18
- ## Before Coding
19
-
20
- 1. Check which `db` pack is installed.
21
- 2. Find the authoritative database schema and migrations.
22
- 3. Read `lib/zero/schema.ts`.
23
- 4. Identify the smallest set of rows the UI needs.
24
- 5. Confirm auth context before exposing user-scoped data.
25
-
26
- ## Schema Authoring
27
-
28
- Zero schema mirrors the subset of Postgres that clients can query. Keep it
29
- small, explicit, and aligned with the database.
30
-
31
- Use table builders from `@rocicorp/zero`, for example `table`, `string`,
32
- `boolean`, `number`, `json`, and `enumeration`.
33
-
34
- Every table must have an explicit primary key. Prefer stable string IDs for
35
- client-created records. Avoid auto-increment IDs for records created from the
36
- client because mutators may run more than once.
37
-
38
- When adding fields, use an expand deploy order: database first, then server
39
- query or mutate code, then client usage. When removing fields, reverse that:
40
- client stops using it, then server stops exposing it, then database removes it.
41
-
42
- ## Queries
43
-
44
- Clients should call named query helpers, not arbitrary server endpoints. Keep
45
- queries narrow enough that Zero can cache and update them efficiently.
46
-
47
- ## Mutators
48
-
49
- Mutators are optimistic. They can run on the client and again on the server, so
50
- they must be deterministic and safe to replay.
51
-
52
- Generate IDs before calling the mutator and pass them as arguments. Do not
53
- generate random IDs, timestamps, or external side effects inside a mutator.
54
-
55
- Validate mutator arguments at the boundary. Keep authorization checks on the
56
- server path, even if the client path also hides unauthorized actions.
57
-
58
- ## Local Development
59
-
60
- `zero-cache` needs a Postgres upstream with logical replication enabled. Keep
61
- `ZERO_UPSTREAM_DB` pointed at the same database your app server uses.
62
-
63
- ## Review Checklist
64
-
65
- - Schema matches current migrations.
66
- - Client-visible rows are scoped by query and auth context.
67
- - Mutators are deterministic and replay-safe.
68
- - Query shape is indexed or intentionally small.
69
- - Local setup documents `ZERO_UPSTREAM_DB` and cache reset steps.
@@ -1,16 +0,0 @@
1
- epic: Sync
2
- tasks:
3
- - id: ZERO-001
4
- title: Define initial schema in lib/zero/schema.ts
5
- status: Clarifying
6
- acceptance:
7
- - The Zero schema matches the first database tables that need client-first reads.
8
- - Every synced table has an explicit primary key and only includes fields needed by the client.
9
- - Schema changes are deployed in Zero-safe expand or contract order.
10
- - id: ZERO-002
11
- title: Run zero-cache locally
12
- status: Clarifying
13
- acceptance:
14
- - zero-cache starts with ZERO_UPSTREAM_DB pointed at a logical-replication-enabled Postgres database.
15
- - Local app query and mutate endpoints are reachable from zero-cache.
16
- - The development workflow documents how to reset the local SQLite replica.
@@ -1,7 +0,0 @@
1
- import { expect, test } from "@playwright/test";
2
-
3
- test("landing page renders a heading", async ({ page }) => {
4
- await page.goto("/");
5
-
6
- await expect(page.locator("h1")).toBeVisible();
7
- });
@@ -1,33 +0,0 @@
1
- import { defineConfig, devices } from "@playwright/test";
2
-
3
- const port = Number(process.env.PORT ?? 3000);
4
- const baseURL = `http://127.0.0.1:${port}`;
5
-
6
- export default defineConfig({
7
- testDir: "./e2e",
8
- fullyParallel: true,
9
- timeout: 30_000,
10
- expect: {
11
- timeout: 5_000,
12
- },
13
- reporter: process.env.CI ? [["github"], ["html", { open: "never" }]] : "list",
14
- use: {
15
- baseURL,
16
- trace: "on-first-retry",
17
- },
18
- webServer: {
19
- command: "bun dev",
20
- url: baseURL,
21
- reuseExistingServer: !process.env.CI,
22
- timeout: 120_000,
23
- env: {
24
- PORT: String(port),
25
- },
26
- },
27
- projects: [
28
- {
29
- name: "chromium",
30
- use: { ...devices["Desktop Chrome"] },
31
- },
32
- ],
33
- });
@@ -1,25 +0,0 @@
1
- name = "testing-playwright"
2
- version = "1.0.0"
3
- category = "testing"
4
- description = "Playwright end-to-end test setup for the Next.js scaffold."
5
- provides = ["e2e"]
6
- requires = []
7
- conflicts = []
8
- requires_runtime = ["server"]
9
- compatible_scaffolds = ["nextjs"]
10
-
11
- [dependencies]
12
- dev = ["@playwright/test"]
13
-
14
- [[files]]
15
- mode = "create"
16
- from = "playwright.config.ts"
17
- to = "playwright.config.ts"
18
-
19
- [[files]]
20
- mode = "create"
21
- from = "e2e/example.spec.ts"
22
- to = "e2e/example.spec.ts"
23
-
24
- [tasks]
25
- file = "tasks.yaml"
@@ -1,9 +0,0 @@
1
- epic: Testing
2
-
3
- tasks:
4
- - id: E2E-001
5
- title: Add a smoke test for the first user-facing flow
6
- status: Clarifying
7
- acceptance:
8
- - The first user-facing flow has a Playwright smoke test.
9
- - The test runs against the local dev server through Playwright config.
@@ -1,56 +0,0 @@
1
- /* # >>> spark:ui-shadcn >>> */
2
- @layer base {
3
- :root {
4
- --background: 0 0% 100%;
5
- --foreground: 222.2 84% 4.9%;
6
- --card: 0 0% 100%;
7
- --card-foreground: 222.2 84% 4.9%;
8
- --popover: 0 0% 100%;
9
- --popover-foreground: 222.2 84% 4.9%;
10
- --primary: 221.2 83.2% 53.3%;
11
- --primary-foreground: 210 40% 98%;
12
- --secondary: 210 40% 96.1%;
13
- --secondary-foreground: 222.2 47.4% 11.2%;
14
- --muted: 210 40% 96.1%;
15
- --muted-foreground: 215.4 16.3% 46.9%;
16
- --accent: 210 40% 96.1%;
17
- --accent-foreground: 222.2 47.4% 11.2%;
18
- --destructive: 0 84.2% 60.2%;
19
- --destructive-foreground: 210 40% 98%;
20
- --border: 214.3 31.8% 91.4%;
21
- --input: 214.3 31.8% 91.4%;
22
- --ring: 221.2 83.2% 53.3%;
23
- --radius: 0.5rem;
24
- }
25
-
26
- .dark {
27
- --background: 222.2 84% 4.9%;
28
- --foreground: 210 40% 98%;
29
- --card: 222.2 84% 4.9%;
30
- --card-foreground: 210 40% 98%;
31
- --popover: 222.2 84% 4.9%;
32
- --popover-foreground: 210 40% 98%;
33
- --primary: 217.2 91.2% 59.8%;
34
- --primary-foreground: 222.2 47.4% 11.2%;
35
- --secondary: 217.2 32.6% 17.5%;
36
- --secondary-foreground: 210 40% 98%;
37
- --muted: 217.2 32.6% 17.5%;
38
- --muted-foreground: 215 20.2% 65.1%;
39
- --accent: 217.2 32.6% 17.5%;
40
- --accent-foreground: 210 40% 98%;
41
- --destructive: 0 62.8% 30.6%;
42
- --destructive-foreground: 210 40% 98%;
43
- --border: 217.2 32.6% 17.5%;
44
- --input: 217.2 32.6% 17.5%;
45
- --ring: 224.3 76.3% 48%;
46
- }
47
-
48
- * {
49
- @apply border-border;
50
- }
51
-
52
- body {
53
- @apply bg-background text-foreground;
54
- }
55
- }
56
- /* # <<< spark:ui-shadcn <<< */
@@ -1,47 +0,0 @@
1
- import * as React from 'react';
2
- import { Slot } from '@radix-ui/react-slot';
3
- import { cva, type VariantProps } from 'class-variance-authority';
4
- import { cn } from '@/lib/utils';
5
-
6
- const buttonVariants = cva(
7
- 'inline-flex h-10 items-center justify-center gap-2 whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
8
- {
9
- variants: {
10
- variant: {
11
- default: 'bg-primary text-primary-foreground hover:bg-primary/90',
12
- destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
13
- outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
14
- secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
15
- ghost: 'hover:bg-accent hover:text-accent-foreground',
16
- link: 'text-primary underline-offset-4 hover:underline',
17
- },
18
- size: {
19
- default: 'h-10 px-4 py-2',
20
- sm: 'h-9 rounded-md px-3',
21
- lg: 'h-11 rounded-md px-8',
22
- icon: 'h-10 w-10',
23
- },
24
- },
25
- defaultVariants: {
26
- variant: 'default',
27
- size: 'default',
28
- },
29
- },
30
- );
31
-
32
- export function Button({
33
- className,
34
- variant,
35
- size,
36
- asChild = false,
37
- ...props
38
- }: React.ComponentProps<'button'> &
39
- VariantProps<typeof buttonVariants> & {
40
- asChild?: boolean;
41
- }) {
42
- const Comp = asChild ? Slot : 'button';
43
-
44
- return <Comp className={cn(buttonVariants({ variant, size, className }))} {...props} />;
45
- }
46
-
47
- export { buttonVariants };
@@ -1,33 +0,0 @@
1
- import * as React from 'react';
2
- import { cn } from '@/lib/utils';
3
-
4
- export function Card({ className, ...props }: React.ComponentProps<'div'>) {
5
- return (
6
- <div
7
- className={cn('rounded-lg border bg-card text-card-foreground shadow-sm', className)}
8
- {...props}
9
- />
10
- );
11
- }
12
-
13
- export function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
14
- return <div className={cn('flex flex-col space-y-1.5 p-6', className)} {...props} />;
15
- }
16
-
17
- export function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
18
- return (
19
- <div className={cn('text-2xl font-semibold leading-none tracking-tight', className)} {...props} />
20
- );
21
- }
22
-
23
- export function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
24
- return <div className={cn('text-sm text-muted-foreground', className)} {...props} />;
25
- }
26
-
27
- export function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
28
- return <div className={cn('p-6 pt-0', className)} {...props} />;
29
- }
30
-
31
- export function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
32
- return <div className={cn('flex items-center p-6 pt-0', className)} {...props} />;
33
- }
@@ -1,6 +0,0 @@
1
- import { clsx, type ClassValue } from 'clsx';
2
- import { twMerge } from 'tailwind-merge';
3
-
4
- export function cn(...inputs: ClassValue[]) {
5
- return twMerge(clsx(inputs));
6
- }
@@ -1,7 +0,0 @@
1
- const config = {
2
- plugins: {
3
- '@tailwindcss/postcss': {},
4
- },
5
- };
6
-
7
- export default config;
@@ -1,57 +0,0 @@
1
- import type { Config } from 'tailwindcss';
2
-
3
- const config: Config = {
4
- darkMode: ['class'],
5
- content: [
6
- './app/**/*.{ts,tsx,mdx}',
7
- './components/**/*.{ts,tsx,mdx}',
8
- './lib/**/*.{ts,tsx,mdx}',
9
- ],
10
- theme: {
11
- extend: {
12
- borderRadius: {
13
- lg: 'var(--radius)',
14
- md: 'calc(var(--radius) - 2px)',
15
- sm: 'calc(var(--radius) - 4px)',
16
- },
17
- colors: {
18
- background: 'hsl(var(--background))',
19
- foreground: 'hsl(var(--foreground))',
20
- card: {
21
- DEFAULT: 'hsl(var(--card))',
22
- foreground: 'hsl(var(--card-foreground))',
23
- },
24
- popover: {
25
- DEFAULT: 'hsl(var(--popover))',
26
- foreground: 'hsl(var(--popover-foreground))',
27
- },
28
- primary: {
29
- DEFAULT: 'hsl(var(--primary))',
30
- foreground: 'hsl(var(--primary-foreground))',
31
- },
32
- secondary: {
33
- DEFAULT: 'hsl(var(--secondary))',
34
- foreground: 'hsl(var(--secondary-foreground))',
35
- },
36
- muted: {
37
- DEFAULT: 'hsl(var(--muted))',
38
- foreground: 'hsl(var(--muted-foreground))',
39
- },
40
- accent: {
41
- DEFAULT: 'hsl(var(--accent))',
42
- foreground: 'hsl(var(--accent-foreground))',
43
- },
44
- destructive: {
45
- DEFAULT: 'hsl(var(--destructive))',
46
- foreground: 'hsl(var(--destructive-foreground))',
47
- },
48
- border: 'hsl(var(--border))',
49
- input: 'hsl(var(--input))',
50
- ring: 'hsl(var(--ring))',
51
- },
52
- },
53
- },
54
- plugins: [],
55
- };
56
-
57
- export default config;
@@ -1,44 +0,0 @@
1
- name = "ui-shadcn"
2
- version = "1.0.0"
3
- category = "ui"
4
- description = "Shadcn-style UI primitives for Next.js dashboards."
5
- provides = ["ui-kit"]
6
- requires = []
7
- conflicts = ["ui-kit"]
8
- requires_runtime = ["react"]
9
- compatible_scaffolds = ["nextjs"]
10
-
11
- [dependencies]
12
- runtime = [
13
- "@radix-ui/react-slot",
14
- "class-variance-authority",
15
- "clsx",
16
- "tailwind-merge",
17
- "lucide-react",
18
- ]
19
-
20
- [[files]]
21
- mode = "create"
22
- from = "lib/utils.ts"
23
- to = "lib/utils.ts"
24
-
25
- [[files]]
26
- mode = "create"
27
- from = "components/ui/button.tsx"
28
- to = "components/ui/button.tsx"
29
-
30
- [[files]]
31
- mode = "create"
32
- from = "components/ui/card.tsx"
33
- to = "components/ui/card.tsx"
34
-
35
- [[files]]
36
- mode = "append"
37
- from = "app/globals.css"
38
- to = "app/globals.css"
39
-
40
- [skills]
41
- copy = ["skills/shadcn-dashboard-patterns"]
42
-
43
- [tasks]
44
- file = "tasks.yaml"