Token导航 LogoToken导航

Agent Skill · 研究检索

remix-patterns(混音模式)

remix-patterns 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

remix-patterns 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 64,068。

总安装 306周安装 13GitHub Stars 公开资料未说明下载 107核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:remix-patterns(混音模式)
来源仓库:https://github.com/tejovanthn/rasikalife
仓库路径:skills/remix-patterns
安装命令:
npx skills add https://github.com/tejovanthn/rasikalife --skill remix-patterns
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/tejovanthn/rasikalife --skill remix-patterns

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

remix-patterns 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。适用于混音模式相关的信息查询与筛选任务,支持多宿主环境集成。

通过 npx skills add 命令从指定 GitHub 仓库安装并使用该技能。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写操作。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/remix-patterns

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/tejovanthn/rasikalife --skill remix-patterns;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

remix-patterns 怎么安装?

在终端执行 npx skills add https://github.com/tejovanthn/rasikalife --skill remix-patterns。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

remix-patterns 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

remix-patterns 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

remix-patterns 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

remix-patterns 用的人多吗?

公开数据是累计安装 306 次,近一周安装 13 次,下载 107 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

remix-patterns 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
remix-patterns

混音模式 · 本页

306—需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Remix Development Patterns

This skill provides comprehensive guidance for building Remix applications following best practices and framework conventions.

Core Philosophy

Remix embraces:

  • Web Fundamentals: Work with HTTP, not against it
  • Progressive Enhancement: Apps should work without JavaScript
  • Server-First: Do the work on the server, send HTML
  • Nested Routes: Compose UIs with route hierarchy
  • No Client State: Use the URL and server as the source of truth

Route Structure

Basic Route Module

Every route module can export these functions:

// app/routes/posts.$id.tsx
import type { LoaderFunctionArgs, ActionFunctionArgs } from "@remix-run/node";
import { json } from "@remix-run/node";
import { useLoaderData, Form } from "@remix-run/react";

// Loader: Fetch data on GET requests
export async function loader({ params, request }: LoaderFunctionArgs) {
  const post = await getPost(params.id);
  if (!post) {
    throw new Response("Not Found", { status: 404 });
  }
  return json({ post });
}

// Action: Handle mutations (POST, PUT, DELETE)
export async function action({ request, params }: ActionFunctionArgs) {
  const formData = await request.formData();
  const title = formData.get("title");

  await updatePost(params.id, { title });
  return json({ success: true });
}

// Component: Render the UI
export default function Post() {
  const { post } = useLoaderData<typeof loader>();

  return (
    <div>
      <h1>{post.title}</h1>
      <Form method="post">
        <input name="title" defaultValue={post.title} />
        <button type="submit">Update</button>
      </Form>
    </div>
  );
}

Data Loading Patterns

Pattern 1: Simple Data Fetching

export async function loader({ params }: LoaderFunctionArgs) {
  const [user, posts] = await Promise.all([
    db.user.findUnique({ where: { id: params.userId } }),
    db.post.findMany({ where: { userId: params.userId } })
  ]);

  return json({ user, posts });
}

Pattern 2: Authentication Checks

export async function loader({ request }: LoaderFunctionArgs) {
  const userId = await requireAuth(request);
  const user = await db.user.findUnique({ where: { id: userId } });

  return json({ user });
}

// Helper function
async function requireAuth(request: Request) {
  const userId = await getUserId(request);
  if (!userId) {
    throw redirect("/login");
  }
  return userId;
}

Pattern 3: Search with URL Params

export async function loader({ request }: LoaderFunctionArgs) {
  const url = new URL(request.url);
  const query = url.searchParams.get("q") || "";
  const page = Number(url.searchParams.get("page")) || 1;

  const results = await searchPosts({ query, page });

  return json({ results, query, page });
}

export default function Search() {
  const { results, query } = useLoaderData<typeof loader>();

  return (
    <div>
      <Form method="get">
        <input name="q" defaultValue={query} />
        <button type="submit">Search</button>
      </Form>
      {/* Results */}
    </div>
  );
}

Pattern 4: Dependent Loaders (Parent/Child)

// app/routes/users.$userId.tsx (parent)
export async function loader({ params }: LoaderFunctionArgs) {
  const user = await db.user.findUnique({ where: { id: params.userId } });
  return json({ user });
}

// app/routes/users.$userId.posts.tsx (child)
export async function loader({ params }: LoaderFunctionArgs) {
  // Can access parent data via useRouteLoaderData
  const posts = await db.post.findMany({ where: { userId: params.userId } });
  return json({ posts });
}

export default function UserPosts() {
  const { posts } = useLoaderData<typeof loader>();
  const { user } = useRouteLoaderData<typeof parentLoader>("routes/users.$userId");

  return <div>{/* ... */}</div>;
}

Form Handling Patterns

Pattern 1: Basic Form Submission

export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const title = formData.get("title");
  const content = formData.get("content");

  const post = await db.post.create({
    data: { title, content }
  });

  return redirect(`/posts/${post.id}`);
}

export default function NewPost() {
  return (
    <Form method="post">
      <input name="title" required />
      <textarea name="content" required />
      <button type="submit">Create Post</button>
    </Form>
  );
}

Pattern 2: Form with Validation

import { z } from "zod";

const schema = z.object({
  email: z.string().email(),
  password: z.string().min(8)
});

export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const data = Object.fromEntries(formData);

  const result = schema.safeParse(data);
  if (!result.success) {
    return json(
      { errors: result.error.flatten() },
      { status: 400 }
    );
  }

  await createUser(result.data);
  return redirect("/dashboard");
}

export default function Signup() {
  const actionData = useActionData<typeof action>();

  return (
    <Form method="post">
      <input name="email" />
      {actionData?.errors.fieldErrors.email && (
        <span>{actionData.errors.fieldErrors.email}</span>
      )}

      <input name="password" type="password" />
      {actionData?.errors.fieldErrors.password && (
        <span>{actionData.errors.fieldErrors.password}</span>
      )}

      <button type="submit">Sign Up</button>
    </Form>
  );
}

Pattern 3: Optimistic UI

import { useFetcher } from "@remix-run/react";

export default function Todo({ todo }) {
  const fetcher = useFetcher();

  // Optimistic state
  const isComplete = fetcher.formData
    ? fetcher.formData.get("complete") === "true"
    : todo.complete;

  return (
    <fetcher.Form method="post" action={`/todos/${todo.id}`}>
      <input type="hidden" name="complete" value={String(!isComplete)} />
      <button type="submit">
        {isComplete ? "✓" : "○"} {todo.title}
      </button>
    </fetcher.Form>
  );
}

Pattern 4: Multiple Actions per Route

export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const intent = formData.get("intent");

  switch (intent) {
    case "delete":
      await deletePost(formData.get("id"));
      return json({ success: true });

    case "update":
      await updatePost(formData.get("id"), {
        title: formData.get("title")
      });
      return json({ success: true });

    default:
      throw new Response("Invalid intent", { status: 400 });
  }
}

export default function Post() {
  return (
    <>
      <Form method="post">
        <input type="hidden" name="intent" value="update" />
        <input name="title" />
        <button type="submit">Update</button>
      </Form>

      <Form method="post">
        <input type="hidden" name="intent" value="delete" />
        <button type="submit">Delete</button>
      </Form>
    </>
  );
}

Error Handling

Pattern 1: Error Boundaries

// app/routes/posts.$id.tsx
export async function loader({ params }: LoaderFunctionArgs) {
  const post = await db.post.findUnique({ where: { id: params.id } });

  if (!post) {
    throw new Response("Post not found", { status: 404 });
  }

  return json({ post });
}

export function ErrorBoundary() {
  const error = useRouteError();

  if (isRouteErrorResponse(error)) {
    return (
      <div>
        <h1>{error.status} {error.statusText}</h1>
        <p>{error.data}</p>
      </div>
    );
  }

  return <div>Something went wrong!</div>;
}

Pattern 2: Nested Error Boundaries

// Root error boundary (app/root.tsx)
export function ErrorBoundary() {
  return (
    <html>
      <body>
        <h1>Application Error</h1>
        <p>Sorry, something went wrong.</p>
      </body>
    </html>
  );
}

// Route-specific error boundary
export function ErrorBoundary() {
  return (
    <div>
      <h1>Post Error</h1>
      <p>Couldn't load this post.</p>
    </div>
  );
}

Nested Routes

Pattern 1: Layout Routes

// app/routes/dashboard.tsx (layout)
import { Outlet } from "@remix-run/react";

export default function Dashboard() {
  return (
    <div>
      <nav>{/* Dashboard navigation */}</nav>
      <main>
        <Outlet /> {/* Child routes render here */}
      </main>
    </div>
  );
}

// app/routes/dashboard.settings.tsx (child)
export default function Settings() {
  return <div>Settings content</div>;
}

// app/routes/dashboard.profile.tsx (child)
export default function Profile() {
  return <div>Profile content</div>;
}

Pattern 2: Pathless Layouts

// app/routes/_auth.tsx (pathless layout - note the underscore)
export default function AuthLayout() {
  return (
    <div className="auth-container">
      <Outlet />
    </div>
  );
}

// app/routes/_auth.login.tsx
// URL: /login (not /_auth/login)
export default function Login() {
  return <Form>{/* login form */}</Form>;
}

// app/routes/_auth.signup.tsx
// URL: /signup
export default function Signup() {
  return <Form>{/* signup form */}</Form>;
}

Resource Routes

Pattern 1: Image Generation

// app/routes/og.$id.tsx
import { LoaderFunctionArgs } from "@remix-run/node";

export async function loader({ params }: LoaderFunctionArgs) {
  const post = await getPost(params.id);
  const image = await generateOGImage(post);

  return new Response(image, {
    headers: {
      "Content-Type": "image/png",
      "Cache-Control": "public, max-age=31536000, immutable"
    }
  });
}

Pattern 2: File Downloads

// app/routes/downloads.$fileId.tsx
export async function loader({ params }: LoaderFunctionArgs) {
  const file = await getFile(params.fileId);
  const stream = await getFileStream(file.path);

  return new Response(stream, {
    headers: {
      "Content-Type": file.mimeType,
      "Content-Disposition": `attachment; filename="${file.name}"`
    }
  });
}

Best Practices

1. Prefer Server-Side Logic

❌ Don't fetch on the client:

export default function Posts() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    fetch("/api/posts").then(r => r.json()).then(setPosts);
  }, []);
}

✅ Do use loaders:

export async function loader() {
  const posts = await db.post.findMany();
  return json({ posts });
}

export default function Posts() {
  const { posts } = useLoaderData<typeof loader>();
  return <div>{/* render posts */}</div>;
}

2. Use Form Component

❌ Don't use fetch for mutations:

function handleSubmit(e) {
  e.preventDefault();
  fetch("/api/posts", { method: "POST", body: formData });
}

✅ Do use Form:

export default function NewPost() {
  return (
    <Form method="post">
      <input name="title" />
      <button type="submit">Create</button>
    </Form>
  );
}

3. Colocate Related Code

✅ Keep route concerns together:

// app/routes/posts.$id.tsx
// - loader (data fetching)
// - action (mutations)
// - component (UI)
// - ErrorBoundary (error handling)
// All in one file!

4. Use Type Safety

import type { LoaderFunctionArgs } from "@remix-run/node";

export async function loader({ params }: LoaderFunctionArgs) {
  // TypeScript knows about params, request, etc.
}

export default function Component() {
  // Automatic type inference from loader!
  const data = useLoaderData<typeof loader>();
  //    ^? data is typed based on loader return
}

5. Handle Loading States

import { useNavigation } from "@remix-run/react";

export default function Component() {
  const navigation = useNavigation();
  const isSubmitting = navigation.state === "submitting";

  return (
    <Form method="post">
      <button disabled={isSubmitting}>
        {isSubmitting ? "Saving..." : "Save"}
      </button>
    </Form>
  );
}

Common Gotchas

1. Loader Return Types

Always use json() or Response:

✅ return json({ data });
✅ return new Response(data);
❌ return { data };  // Won't work correctly

2. Form Data is Always Strings

const formData = await request.formData();
const age = formData.get("age");  // This is a string!

// Convert to number
const ageNumber = Number(age);

3. Redirects Stop Execution

export async function action({ request }: ActionFunctionArgs) {
  if (!isValid) {
    return json({ error: "Invalid" });  // Continues execution
  }

  throw redirect("/login");  // Stops execution immediately
}

Performance Tips

1. Parallel Data Loading

export async function loader() {
  // These load in parallel!
  const [user, posts, comments] = await Promise.all([
    getUser(),
    getPosts(),
    getComments()
  ]);

  return json({ user, posts, comments });
}

2. Cache Headers

export async function loader() {
  const data = await getStaticData();

  return json(data, {
    headers: {
      "Cache-Control": "public, max-age=3600"
    }
  });
}

3. Defer for Streaming

import { defer } from "@remix-run/node";
import { Await, useLoaderData } from "@remix-run/react";
import { Suspense } from "react";

export async function loader() {
  return defer({
    critical: await getCriticalData(),  // Wait for this
    deferred: getDeferredData()          // Don't wait
  });
}

export default function Component() {
  const { critical, deferred } = useLoaderData<typeof loader>();

  return (
    <div>
      <div>{critical}</div>

      <Suspense fallback={<div>Loading...</div>}>
        <Await resolve={deferred}>
          {(data) => <div>{data}</div>}
        </Await>
      </Suspense>
    </div>
  );
}

Further Reading

平台分布

Codex

35.62%
按下载量换算38

Claude

30.05%
按下载量换算32

Cursor

18.96%
按下载量换算20

Gemini CLI

10.95%
按下载量换算12

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills