Token导航 LogoToken导航

Agent Skill · 研究检索

bknd-crud-delete(bknd 增删改查删除)

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

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

总安装 346周安装 14GitHub Stars 3下载 109核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

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

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-crud-delete

这个 Skill 是做什么的

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

bknd-crud-delete 用于从数据库移除指定记录,适合在 Codex、Claude、Cursor、Gemini CLI 中执行数据清理或用户请求的删除操作。适用场景包括手动清理测试数据、应用层级的软删除模拟及合规性数据擦除任务。核心能力是通过 record ID 精确定位目标,支持单条或多条件批量删除。

使用方式推荐在 Code 模式中编写过滤逻辑,确保删除范围可控且可追溯。执行前务必二次确认 ID 准确性,防止误删关联数据造成系统故障。

来源仓库内路径:skills/bknd-crud-delete

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

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

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

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

常见问题

6 条

bknd-crud-delete 怎么安装?

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

bknd-crud-delete 支持哪些 AI 工具?

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

bknd-crud-delete 需要什么权限?

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

bknd-crud-delete 是免费的吗?

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

bknd-crud-delete 用的人多吗?

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

bknd-crud-delete 安全吗?

第三方扫描有未通过项,风险较高。除非你确认过源码,否则不建议直接安装到常用环境。

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

值得选的地方

  • 同时适配 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调用外部服务未明确有提醒
bknd-crud-delete

bknd 增删改查删除 · 本页

3463需要联网未明确未通过

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

SKILL.md 原文

CRUD Delete

Delete records from your Bknd database using the SDK or REST API.

Prerequisites

  • Bknd project running (local or deployed)
  • Entity exists with records to delete
  • SDK configured or API endpoint known
  • Record ID or filter criteria known
  • Understanding of any relationships/dependencies

When to Use UI Mode

  • Quick one-off deletions
  • Manual data cleanup
  • Visual verification of what's being deleted

UI steps: Admin Panel > Data > Select Entity > Click record > Delete button > Confirm

When to Use Code Mode

  • Application logic for user-initiated deletes
  • Automated data cleanup/maintenance
  • Bulk deletions
  • Soft delete implementations

Code Approach

Step 1: Set Up SDK Client

import { Api } from "bknd";

const api = new Api({
  host: "http://localhost:7654",
});

// If auth required:
api.updateToken("your-jwt-token");

Step 2: Delete Single Record

Use deleteOne(entity, id):

const { ok, data, error } = await api.data.deleteOne("posts", 1);

if (ok) {
  console.log("Deleted post:", data.id);
} else {
  console.error("Failed:", error.message);
}

Step 3: Handle Response

The response object:

type DeleteResponse = {
  ok: boolean;       // Success/failure
  data?: {           // Deleted record (if ok)
    id: number;
    // ...all fields of deleted record
  };
  error?: {          // Error info (if !ok)
    message: string;
    code: string;
  };
};

Step 4: Delete Multiple Records (Bulk)

Use deleteMany(entity, where):

// Delete all archived posts
const { ok, data } = await api.data.deleteMany("posts", {
  status: { $eq: "archived" },
});

// data contains deleted records
console.log("Deleted", data.length, "posts");

Important: where clause is required to prevent accidental delete-all.

// Delete old sessions
await api.data.deleteMany("sessions", {
  last_active: { $lt: "2024-01-01" },
});

// Delete by multiple conditions
await api.data.deleteMany("logs", {
  level: { $eq: "debug" },
  created_at: { $lt: "2024-06-01" },
});

Step 5: Verify Before Delete

Always verify record exists or check count before deleting:

// Check record exists
const { data: existing } = await api.data.readOne("posts", id);
if (!existing) {
  throw new Error("Post not found");
}
await api.data.deleteOne("posts", id);

// Check count before bulk delete
const { data: countResult } = await api.data.count("logs", {
  level: { $eq: "debug" },
});
console.log(`About to delete ${countResult.count} records`);

REST API Approach

Delete One

curl -X DELETE http://localhost:7654/api/data/posts/1

Delete with Auth

curl -X DELETE http://localhost:7654/api/data/posts/1 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Delete Many

# Delete all archived posts
curl -X DELETE "http://localhost:7654/api/data/posts?where=%7B%22status%22%3A%22archived%22%7D"

# URL-decoded where: {"status":"archived"}

React Integration

Delete Button

import { useApp } from "bknd/react";
import { useState } from "react";

function DeleteButton({ postId, onDeleted }: { postId: number; onDeleted?: () => void }) {
  const { api } = useApp();
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function handleDelete() {
    if (!confirm("Are you sure you want to delete this post?")) {
      return;
    }

    setLoading(true);
    setError(null);

    const { ok, error: apiError } = await api.data.deleteOne("posts", postId);

    setLoading(false);

    if (ok) {
      onDeleted?.();
    } else {
      setError(apiError.message);
    }
  }

  return (
    <>
      <button onClick={handleDelete} disabled={loading}>
        {loading ? "Deleting..." : "Delete"}
      </button>
      {error && <p className="error">{error}</p>}
    </>
  );
}

With SWR Revalidation

import { mutate } from "swr";

function useDeletePost() {
  const { api } = useApp();

  async function deletePost(id: number) {
    const { ok, error } = await api.data.deleteOne("posts", id);

    if (ok) {
      // Revalidate list
      mutate("posts");
    }

    return { ok, error };
  }

  return { deletePost };
}

Optimistic Delete

function useOptimisticDelete() {
  const { api } = useApp();
  const [posts, setPosts] = useState<Post[]>([]);

  async function deletePost(id: number) {
    // Optimistic: remove immediately
    const originalPosts = [...posts];
    setPosts((prev) => prev.filter((p) => p.id !== id));

    // Actual delete
    const { ok } = await api.data.deleteOne("posts", id);

    if (!ok) {
      // Rollback on failure
      setPosts(originalPosts);
    }

    return { ok };
  }

  return { posts, deletePost };
}

Full Example

import { Api } from "bknd";

const api = new Api({ host: "http://localhost:7654" });

// Authenticate
await api.auth.login({ email: "admin@example.com", password: "password" });

// Simple delete
const { ok, data } = await api.data.deleteOne("posts", 1);
if (ok) {
  console.log("Deleted:", data.title);
}

// Delete with verification
const postId = 5;
const { data: post } = await api.data.readOne("posts", postId);
if (post) {
  await api.data.deleteOne("posts", postId);
}

// Bulk delete: remove old archived posts
const { data: deleted } = await api.data.deleteMany("posts", {
  status: { $eq: "archived" },
  created_at: { $lt: "2023-01-01" },
});
console.log("Deleted", deleted.length, "old archived posts");

// Cleanup expired sessions
await api.data.deleteMany("sessions", {
  expires_at: { $lt: new Date().toISOString() },
});

Common Patterns

Soft Delete (Recommended for User Data)

Instead of permanent deletion, mark as deleted:

// Soft delete: set timestamp
async function softDelete(api: Api, entity: string, id: number) {
  return api.data.updateOne(entity, id, {
    deleted_at: new Date().toISOString(),
  });
}

// Restore soft-deleted record
async function restore(api: Api, entity: string, id: number) {
  return api.data.updateOne(entity, id, {
    deleted_at: null,
  });
}

// Query non-deleted records
async function findActive(api: Api, entity: string, query = {}) {
  return api.data.readMany(entity, {
    ...query,
    where: {
      ...query.where,
      deleted_at: { $isnull: true },
    },
  });
}

// Permanently delete soft-deleted records older than 30 days
async function purgeDeleted(api: Api, entity: string) {
  const thirtyDaysAgo = new Date();
  thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

  return api.data.deleteMany(entity, {
    deleted_at: { $lt: thirtyDaysAgo.toISOString() },
  });
}

Delete with Confirmation

async function deleteWithConfirmation(
  api: Api,
  entity: string,
  id: number,
  confirm: () => Promise<boolean>
) {
  const { data } = await api.data.readOne(entity, id);
  if (!data) {
    return { ok: false, error: { message: "Record not found" } };
  }

  const confirmed = await confirm();
  if (!confirmed) {
    return { ok: false, error: { message: "Cancelled by user" } };
  }

  return api.data.deleteOne(entity, id);
}

Cascade Delete (Manual)

When Bknd doesn't auto-cascade, delete children first:

async function cascadeDelete(api: Api, userId: number) {
  // Delete children first
  await api.data.deleteMany("posts", { author_id: { $eq: userId } });
  await api.data.deleteMany("comments", { user_id: { $eq: userId } });
  await api.data.deleteMany("likes", { user_id: { $eq: userId } });

  // Then delete parent
  return api.data.deleteOne("users", userId);
}

Batch Delete with Progress

async function batchDelete(
  api: Api,
  entity: string,
  ids: number[],
  onProgress?: (done: number, total: number) => void
) {
  const results = [];

  for (let i = 0; i < ids.length; i++) {
    const result = await api.data.deleteOne(entity, ids[i]);
    results.push(result);
    onProgress?.(i + 1, ids.length);
  }

  return results;
}

// Usage
const idsToDelete = [1, 5, 12, 23];
await batchDelete(api, "posts", idsToDelete, (done, total) => {
  console.log(`Deleted ${done}/${total}`);
});

Archive Before Delete

async function archiveAndDelete(
  api: Api,
  sourceEntity: string,
  archiveEntity: string,
  id: number
) {
  // Read current record
  const { data: record } = await api.data.readOne(sourceEntity, id);
  if (!record) {
    return { ok: false, error: { message: "Record not found" } };
  }

  // Create archive copy
  await api.data.createOne(archiveEntity, {
    ...record,
    original_id: record.id,
    archived_at: new Date().toISOString(),
  });

  // Delete original
  return api.data.deleteOne(sourceEntity, id);
}

Conditional Delete

async function deleteIf(
  api: Api,
  entity: string,
  id: number,
  condition: (record: any) => boolean
) {
  const { data } = await api.data.readOne(entity, id);
  if (!data) {
    return { ok: false, error: { message: "Record not found" } };
  }

  if (!condition(data)) {
    return { ok: false, error: { message: "Condition not met" } };
  }

  return api.data.deleteOne(entity, id);
}

// Only delete if draft
await deleteIf(api, "posts", 1, (post) => post.status === "draft");

Common Pitfalls

Record Not Found

Problem: Delete returns no data or error.

Fix: Check if record exists first:

const { data: existing } = await api.data.readOne("posts", id);
if (!existing) {
  console.error("Post not found");
  return;
}
await api.data.deleteOne("posts", id);

Foreign Key Constraint

Problem: FOREIGN KEY constraint failed when deleting parent.

Fix: Delete or unlink children first:

// Option 1: Delete children
await api.data.deleteMany("comments", { post_id: { $eq: postId } });
await api.data.deleteOne("posts", postId);

// Option 2: Unlink children (if nullable FK)
await api.data.updateMany(
  "comments",
  { post_id: { $eq: postId } },
  { post_id: null }
);
await api.data.deleteOne("posts", postId);

Not Checking Response

Problem: Assuming success without verification.

Fix: Always check ok:

// Wrong
await api.data.deleteOne("posts", id);
console.log("Deleted!");  // Might have failed!

// Correct
const { ok, error } = await api.data.deleteOne("posts", id);
if (!ok) {
  console.error("Delete failed:", error.message);
  return;
}
console.log("Deleted!");

Accidental Mass Delete

Problem: Deleting more records than intended.

Fix: Always use specific where clause and verify count:

// Dangerous - might delete more than expected
await api.data.deleteMany("posts", { status: { $eq: "draft" } });

// Safer - check count first
const { data: count } = await api.data.count("posts", {
  status: { $eq: "draft" }
});
console.log(`About to delete ${count.count} posts`);
if (count.count > 100) {
  throw new Error("Too many records - aborting");
}

Missing Auth

Problem: Unauthorized error.

Fix: Authenticate before deleting:

await api.auth.login({ email, password });
// or
api.updateToken(savedToken);

await api.data.deleteOne("posts", id);

No Undo for Hard Delete

Problem: Accidentally deleted important data.

Fix: Use soft delete for recoverable data:

// Instead of hard delete
await api.data.deleteOne("posts", id);

// Use soft delete
await api.data.updateOne("posts", id, {
  deleted_at: new Date().toISOString(),
});

Deleting Without Confirmation

Problem: Users accidentally delete data.

Fix: Always confirm destructive actions:

// In frontend
function handleDelete(id: number) {
  if (!confirm("Delete this post? This cannot be undone.")) {
    return;
  }
  api.data.deleteOne("posts", id);
}

Verification

After deleting, verify the record is gone:

const { ok } = await api.data.deleteOne("posts", 1);

if (ok) {
  const { data } = await api.data.readOne("posts", 1);
  console.log("Record exists:", data !== null);  // Should be false
}

Or via admin panel: Admin Panel > Data > Select Entity > Search for deleted record.

DOs and DON'Ts

DO:

  • Check ok before assuming success
  • Verify record exists before deleting
  • Use soft delete for user data
  • Handle foreign key constraints
  • Confirm with user before destructive actions
  • Check count before bulk deletes
  • Consider archiving before permanent delete

DON'T:

  • Assume deleteOne always succeeds
  • Delete parent before children with FK constraints
  • Hard delete user data without confirmation
  • Forget to revalidate caches after delete
  • Use deleteMany without specific where clause
  • Delete without authentication on protected entities

Related Skills

  • bknd-crud-read - Verify records before deleting
  • bknd-crud-update - Update instead of delete (soft delete)
  • bknd-crud-create - Recreate accidentally deleted records
  • bknd-define-relationship - Understand FK constraints
  • bknd-bulk-operations - Large-scale delete patterns

平台分布

Codex

35.48%
按下载量换算39

Claude

29.33%
按下载量换算32

Cursor

16.94%
按下载量换算18

Gemini CLI

10.33%
按下载量换算11

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

未通过

权限和风险

需要联网

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

安装前确认

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

继续浏览同类 Skills