首页龙虾技能列表 › Stack Scaffold — 堆栈脚手架

Stack Scaffold — 堆栈脚手架

v0.1.2

堆栈脚手架工具。

1· 662·0 当前·0 累计
by @guifav (Guilherme Favaron)·MIT-0
下载技能包
License
MIT-0
最后更新
2026/4/13
安全扫描
VirusTotal
无害
查看报告
OpenClaw
可疑
high confidence
The skill's instructions are plausible for scaffolding a Next.js + Supabase/Firebase project, but its declared metadata (claw.json) requests multiple sensitive environment variables — including Firebase private key — that are unnecessary for file scaffolding and contradict the SKILL.md's claim not to read .env files.
评估建议
This skill mostly looks like a legitimate project scaffolder, but the package metadata (claw.json) asks for many sensitive environment variables — including the Firebase private key — which are not needed just to create files. Before installing or running it: (1) prefer not to supply secrets to the skill/agent; scaffolding should be done in an empty/new directory without exposing credentials, (2) verify the source (claw.json claims a GitHub homepage but the skill metadata says 'unknown'); prefer...
详细分析 ▾
用途与能力
The SKILL.md describes a scaffolding tool and its runtime instructions align with that purpose (creating files, running npx create-next-app, initializing git). However claw.json requires numerous environment variables (including FIREBASE_PRIVATE_KEY, FIREBASE_CLIENT_EMAIL) that a scaffolder does not need to run; these are disproportionate and do not match the stated purpose. Required binaries (node, npx, git) are reasonable.
指令范围
The SKILL.md mandates a Planning Protocol and explicitly forbids reading existing .env or credential files; it instructs only to run `ls` and `node -v` to verify the target directory and to create files and run npx commands. The file templates reference process.env.* placeholders (expected for scaffolding). There are no instructions to transmit secrets or inspect unrelated system files. Overall the runtime instructions are scoped to scaffolding, but they rely on templates that assume sensitive env vars exist at runtime.
安装机制
This is an instruction-only skill with no install spec and no code files executed by the platform; that minimizes install-time risk. The skill will instruct the agent to run system tooling (npx, npm) which is expected for a scaffolder.
凭证需求
claw.json declares many required env variables (NEXT_PUBLIC_SUPABASE_*, NEXT_PUBLIC_FIREBASE_*, FIREBASE_PRIVATE_KEY, FIREBASE_CLIENT_EMAIL, etc.). For scaffolding files, requesting runtime secrets (especially FIREBASE_PRIVATE_KEY) is unnecessary and excessive. The SKILL.md explicitly says it will not read .env files, creating a direct contradiction with the metadata that marks those env vars as required. This mismatch is the primary security concern.
持久化与权限
The skill is user-invocable, not always-enabled, and does not request unusual persistence. Recommended skillDependencies and permissions in claw.json (filesystem, network) are expected for scaffolding and template fetching.
安全有层次,运行前请审查代码。

License

MIT-0

可自由使用、修改和再分发,无需署名。

运行时依赖

无特殊依赖

版本

latestv0.1.22026/2/19

stack-scaffold 0.1.2 - Added a CHANGELOG.md file to the project. - Updated SKILL.md with no functional or protocol changes. - Updated claw.json (details not shown).

● 无害

安装命令 点击复制

官方npx clawhub@latest install stack-scaffold
镜像加速npx clawhub@latest install stack-scaffold --registry https://cn.clawhub-mirror.com

技能文档

You are an expert full-stack developer. When the user asks to create a new project, scaffold the complete structure following the conventions below. Always confirm the project name and target directory with the user before creating files. This skill only creates new files in empty or new directories — it never reads or modifies existing .env, .env.local, or credential files.

Planning Protocol (MANDATORY — execute 之前 任何 action)

Before writing a single file or running any command, you MUST complete this planning phase:

  • Understand 请求. Restate 什么 用户 wants 在...中 own words. Identify 任何 ambiguities. 如果 请求 vague (e.g., "创建 project"), ask one round 的 clarifying questions (project name, purpose, 任何 specific requirements).
  • Survey environment. Check current directory structure 和 installed tools. Run ls节点 -v 到 confirm target directory 空 或 做 不 exist 尚未. 做 不 读取, 打开, 或 inspect 任何 .env, .env.local, 或 credential files. skill 仅 creates 新的 projects — 如果 directory 已经 contains project, ask 用户 到 confirm 之前 proceeding.
  • Build execution plan. 写入 out numbered 列表 的 steps 您 将 take, 包括 file paths 您 将 创建 或 修改, commands 您 将 run, 和 expected outcome 的 每个 step. Present plan 到 yourself (在...中 reasoning) 之前 executing.
  • Identify risks. Note 任何 step could 失败 或 cause data loss (overwriting files, dropping tables, force-pushing). 对于 每个 risk, define mitigation (备份, dry-run, confirmation).
  • Execute sequentially. 关注 plan step 由 step. 之后 每个 step, 验证 succeeded 之前 moving 到 下一个. 如果 step fails, diagnose issue, 更新 plan, 和 continue.
  • Summarize. 之后 completing 所有 steps, provide concise summary 的 什么 是 created, 什么 是 modified, 和 任何 manual steps 用户 仍然 needs 到 take.

Do NOT skip this protocol. Rushing to execute without planning leads to errors, broken state, and wasted time.

Project Initialization

  • Run npx 创建-下一个-app@latest --typescript --tailwind --eslint --app --src-dir --导入-alias "@/" 到 创建 下一个.js project 带有 App Router.
  • cd 进入 project directory.
  • Ensure .gitignore exists 和 includes 在 minimum: .env, .env.local, .env.local, node_modules/, .下一个/. 创建-下一个-app 模板 已经 includes these, 但是 验证 之前 任何 commit.
  • Initialize git: git init && git 添加 - && git commit -m "chore: initial 下一个.js scaffold".

Dependencies

Install the following in a single command:

npm install @supabase/supabase-js @supabase/ssr firebase firebase-admin zod zustand next-themes
npm install -D @types/node vitest @vitejs/plugin-react playwright @playwright/test prettier eslint-config-prettier

Directory Structure

Create this structure inside src/:

src/
├── app/
│   ├── (auth)/
│   │   ├── login/page.tsx
│   │   └── signup/page.tsx
│   ├── (dashboard)/
│   │   └── page.tsx
│   ├── api/
│   │   └── health/route.ts
│   ├── layout.tsx
│   ├── page.tsx
│   └── globals.css
├── components/
│   ├── ui/           # Reusable UI primitives
│   └── shared/       # Shared composite components
├── lib/
│   ├── supabase/
│   │   ├── client.ts       # Browser Supabase client
│   │   ├── server.ts       # Server Supabase client (cookies-based)
│   │   ├── middleware.ts    # Auth refresh middleware helper
│   │   └── types.ts        # Generated DB types (placeholder)
│   ├── firebase/
│   │   ├── client.ts       # Firebase client SDK init
│   │   └── admin.ts        # Firebase Admin SDK init (server-only)
│   └── utils.ts
├── hooks/
│   └── use-auth.ts         # Auth state hook
├── stores/
│   └── user-store.ts       # Zustand user store
├── types/
│   └── index.ts
└── middleware.ts            # Next.js middleware for auth

File Contents

src/lib/supabase/client.ts

import { createBrowserClient } from "@supabase/ssr";

export function createClient() { return createBrowserClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! ); }

src/lib/supabase/server.ts

import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";

export async function createClient() { const cookieStore = await cookies(); return createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { getAll() { return cookieStore.getAll(); }, setAll(cookiesToSet) { try { cookiesToSet.forEach(({ name, value, options }) => cookieStore.set(name, value, options) ); } catch { // Called from Server Component — ignore } }, }, } ); }

src/lib/firebase/client.ts

import { initializeApp, getApps } from "firebase/app";
import { getAuth } from "firebase/auth";

const firebaseConfig = { apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, };

const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0]; export const auth = getAuth(app);

src/lib/firebase/管理员.ts

import { initializeApp, getApps, cert } from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";

if (getApps().length === 0) { initializeApp({ credential: cert({ projectId: process.env.FIREBASE_PROJECT_ID, clientEmail: process.env.FIREBASE_CLIENT_EMAIL, privateKey: process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/g, "\n"), }), }); }

export const adminAuth = getAuth();

src/中间件.ts

import { type NextRequest, NextResponse } from "next/server";
import { createServerClient } from "@supabase/ssr";

export async function middleware(request: NextRequest) { let response = NextResponse.next({ request });

const supabase = createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { getAll() { return request.cookies.getAll(); }, setAll(cookiesToSet) { cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value) ); response = NextResponse.next({ request }); cookiesToSet.forEach(({ name, value, options }) => response.cookies.set(name, value, options) ); }, }, } );

await supabase.auth.getUser();

return response; }

export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico|.\\.(?:svg|png|jpg|jpeg|gif|webp)$).)"], };

src/app/api/health/路由.ts

import { NextResponse } from "next/server";

export async function GET() { return NextResponse.json({ status: "ok", timestamp: new Date().toISOString() }); }

.env.示例

# Supabase
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=

# Firebase Client NEXT_PUBLIC_FIREBASE_API_KEY= NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN= NEXT_PUBLIC_FIREBASE_PROJECT_ID= NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET= NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID= NEXT_PUBLIC_FIREBASE_APP_ID=

# Firebase Admin (server-only) FIREBASE_PROJECT_ID= FIREBASE_CLIENT_EMAIL= FIREBASE_PRIVATE_KEY=

# App NEXT_PUBLIC_APP_URL=http://localhost:3000

vercel.json

{
  "framework": "nextjs",
  "regions": ["gru1"],
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Cache-Control", "value": "no-store" }
      ]
    }
  ]
}

vitest.配置.ts

import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";
import path from "path";

export default defineConfig({ plugins: [react()], test: { environment: "jsdom", globals: true, setupFiles: ["./src/tests/setup.ts"], }, resolve: { alias: { "@": path.resolve(__dirname, "./src"), }, }, });

Post-Scaffold Steps

  • 复制 .env.示例.env.local 和 remind 用户 到 fill 在...中 values.
  • 创建 initial Supabase migration file 在 supabase/migrations/00000000000000_init.sql 带有 profiles 表:
create table public.profiles (
  id uuid references auth.users on delete cascade primary key,
  email text not null,
  full_name text,
  avatar_url text,
  created_at timestamptz default now() not null,
  updated_at timestamptz default now() not null
);

alter table public.profiles enable row level security;

create policy "Users can view own profile" on public.profiles for select using (auth.uid() = id);

create policy "Users can update own profile" on public.profiles for update using (auth.uid() = id);

  • 添加 scripts 到 包.json:
{
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "format": "prettier --write .",
    "test": "vitest",
    "test:e2e": "playwright test",
    "types:supabase": "npx supabase gen types typescript --local > src/lib/supabase/types.ts"
  }
}
  • Commit: git 添加 - && git commit -m "chore: 添加 满 stack scaffold 带有 Supabase, Firebase Auth, Vercel 配置".
  • 打印 summary 的 什么 是 created 和 什么 用户 needs 到 configure manually (env vars, Supabase project, Firebase project, Vercel project 链接, Cloudflare DNS).

下一个 Steps — Recommended Skill Sequence

After scaffolding is complete, run the following skills in order:

  • firebase-auth-setup — Configures auth providers (Google, Apple, email/密码), creates auth 钩子, auth provider 组件, server-side 令牌 verification, 和 Firebase-Supabase 用户 同步 路由. builds 在...上 Firebase client/管理员 SDK files created 由 scaffold.
  • shadcn-主题-默认 — Applies 默认 shadcn/ui Neutral 主题 带有 OKLCH CSS variables 和 dark mode support.
  • cloudflare-guard — Sets up DNS, SSL, rate limiting, 和 caching 对于 domain 在...上 Cloudflare.
  • deploy-pilot — Runs pre-deploy checklist 和 pushes initial deployment 到 Vercel.

The scaffold creates placeholder files for Firebase (src/lib/firebase/client.ts, src/lib/firebase/admin.ts) and a basic auth middleware (src/middleware.ts). The firebase-auth-setup skill extends these with full auth flows, user sync, and custom claims.

数据来源:ClawHub ↗ · 中文优化:龙虾技能库
OpenClaw 技能定制 / 插件定制 / 私有工作流定制

免费技能或插件可能存在安全风险,如需更匹配、更安全的方案,建议联系付费定制

了解定制服务