cabinet-ai-knowledge-base
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCabinet AI Knowledge Base
Cabinet AI 知识库
Skill by ara.so — Daily 2026 Skills collection.
Cabinet is an AI-first startup OS and knowledge base where everything lives as markdown files on disk. No database, no vendor lock-in — self-hosted with AI agents that have memory, scheduled jobs, embedded HTML apps, git-backed history, and a full web terminal.
由 ara.so 提供的Skill — 2026年度每日Skill合集。
Cabinet是一款以AI为核心的创业公司操作系统和知识库,所有内容都以markdown文件形式存储在磁盘上。无需数据库,无供应商锁定——支持自托管,具备带记忆功能的AI Agent、定时任务、嵌入式HTML应用、Git支撑的版本历史,以及完整的网页终端。
Installation
安装
Quick Start (recommended)
快速开始(推荐)
bash
npx create-cabinet@latest
cd cabinet
npm run dev:allOpen http://localhost:3000 — the onboarding wizard builds your AI team in 5 questions.
bash
npx create-cabinet@latest
cd cabinet
npm run dev:all打开 http://localhost:3000 —— 引导向导仅需5个问题即可完成你的AI团队配置。
Manual Clone
手动克隆
bash
git clone https://github.com/hilash/cabinet.git
cd cabinet
npm install
cp .env.example .env.local
npm run dev:allbash
git clone https://github.com/hilash/cabinet.git
cd cabinet
npm install
cp .env.example .env.local
npm run dev:allPrerequisites
前置要求
- Node.js 20+
- Claude Code CLI:
npm install -g @anthropic-ai/claude-code - macOS or Linux (Windows via WSL)
- Node.js 20+
- Claude Code CLI:
npm install -g @anthropic-ai/claude-code - macOS 或 Linux(Windows 需通过WSL运行)
Environment Configuration
环境配置
bash
undefinedbash
undefined.env.local
.env.local
KB_PASSWORD=your_optional_password # Leave empty for no auth
DOMAIN=localhost # Or your custom domain
---KB_PASSWORD=your_optional_password # 不需要鉴权可留空
DOMAIN=localhost # 或你的自定义域名
---Key Commands
常用命令
bash
npm run dev # Next.js dev server on port 3000
npm run dev:daemon # WebSocket + job scheduler on port 3001
npm run dev:all # Both servers together (use this for development)
npm run build # Production build
npm run start # Production mode (both servers)bash
npm run dev # Next.js 开发服务器,运行在3000端口
npm run dev:daemon # WebSocket + 任务调度器,运行在3001端口
npm run dev:all # 同时启动两个服务(开发环境推荐使用)
npm run build # 生产环境构建
npm run start # 生产模式运行(同时启动两个服务)Architecture
架构
cabinet/
src/
app/api/ → Next.js API routes
components/ → React components (sidebar, editor, agents, jobs, terminal)
stores/ → Zustand state management
lib/ → Storage, markdown, git, agents, jobs
server/
cabinet-daemon.ts → WebSocket + job scheduler + agent executor
data/
.agents/.library/ → 20 pre-built agent templates
getting-started/ → Default KB pagesTech stack: Next.js 16, TypeScript, Tailwind CSS, shadcn/ui, Tiptap, Zustand, xterm.js, node-cron
cabinet/
src/
app/api/ → Next.js API 路由
components/ → React 组件(侧边栏、编辑器、Agent、任务、终端)
stores/ → Zustand 状态管理
lib/ → 存储、markdown、git、Agent、任务相关逻辑
server/
cabinet-daemon.ts → WebSocket + 任务调度器 + Agent 执行器
data/
.agents/.library/ → 20个预置Agent模板
getting-started/ → 默认知识库页面技术栈: Next.js 16, TypeScript, Tailwind CSS, shadcn/ui, Tiptap, Zustand, xterm.js, node-cron
Project Structure (data directory)
项目结构(data目录)
Cabinet stores everything as markdown files under :
data/data/
getting-started/
index.md
my-project/
index.md
research.md
index.html ← Embedded HTML app (auto-rendered as iframe)
.agents/
.library/
ceo.md
product-manager.md
researcher.md
active/
my-ceo/
index.md ← Agent definition
memory.md ← Agent memory (auto-updated)Cabinet将所有内容以markdown文件形式存储在目录下:
data/data/
getting-started/
index.md
my-project/
index.md
research.md
index.html ← 嵌入式HTML应用(自动渲染为iframe)
.agents/
.library/
ceo.md
product-manager.md
researcher.md
active/
my-ceo/
index.md ← Agent 定义
memory.md ← Agent 记忆(自动更新)Agent Definition Format
Agent 定义格式
Agents are defined as markdown files with YAML frontmatter:
markdown
---
name: Research Scout
role: researcher
schedule: "0 */6 * * *" # Cron: every 6 hours
skills:
- web-search
- summarization
- reddit-scout
goals:
- Monitor competitor activity
- Surface trending topics in AI tooling
- File weekly summary reports
---Agent以附带YAML前置元数据的markdown文件定义:
markdown
---
name: Research Scout
role: researcher
schedule: "0 */6 * * *" # Cron表达式:每6小时执行一次
skills:
- web-search
- summarization
- reddit-scout
goals:
- Monitor competitor activity
- Surface trending topics in AI tooling
- File weekly summary reports
---Research Scout
Research Scout
You are a research agent for [Company Name]. Your job is to...
You are a research agent for [Company Name]. Your job is to...
Memory
Memory
<!-- Agent memory is auto-appended here by the daemon -->
---<!-- Agent 记忆会由守护进程自动追加到此处 -->
---Creating a Custom Agent
创建自定义Agent
Via the UI
通过UI界面
- Navigate to the Agents panel in the sidebar
- Click "New Agent" and select a template or start blank
- Fill in role, goals, and schedule
- Cabinet creates
data/.agents/active/<agent-name>/index.md
- 导航到侧边栏的Agent面板
- 点击「新建Agent」,选择模板或从空白开始创建
- 填写角色、目标和执行 schedule
- Cabinet会自动创建文件
data/.agents/active/<agent-name>/index.md
Programmatically
通过代码创建
typescript
// src/lib/agents.ts pattern — create an agent file directly
import fs from 'fs/promises'
import path from 'path'
const agentDir = path.join(process.cwd(), 'data', '.agents', 'active', 'my-agent')
await fs.mkdir(agentDir, { recursive: true })
await fs.writeFile(
path.join(agentDir, 'index.md'),
`---
name: My Custom Agent
role: analyst
schedule: "0 9 * * 1"
goals:
- Analyze weekly metrics
- Post summary to #reports channel
---typescript
// src/lib/agents.ts 模式 —— 直接创建Agent文件
import fs from 'fs/promises'
import path from 'path'
const agentDir = path.join(process.cwd(), 'data', '.agents', 'active', 'my-agent')
await fs.mkdir(agentDir, { recursive: true })
await fs.writeFile(
path.join(agentDir, 'index.md'),
`---
name: My Custom Agent
role: analyst
schedule: "0 9 * * 1"
goals:
- Analyze weekly metrics
- Post summary to #reports channel
---My Custom Agent
My Custom Agent
You are a data analyst agent. Every Monday at 9am you will...
`
)
---You are a data analyst agent. Every Monday at 9am you will...
`
)
---Scheduled Jobs (Cron)
定时任务(Cron)
Agents use standard cron syntax in their frontmatter field:
scheduleyaml
undefinedAgent在前置元数据的字段中使用标准Cron语法定义执行时间:
scheduleyaml
undefinedCommon schedule patterns
常用schedule配置示例
schedule: "0 */6 * * *" # Every 6 hours
schedule: "0 9 * * 1" # Every Monday at 9am
schedule: "0 8 * * " # Every day at 8am
schedule: "/30 * * * *" # Every 30 minutes
schedule: "0 0 * * 0" # Weekly on Sunday midnight
The Cabinet daemon (`server/cabinet-daemon.ts`) reads agent files and registers jobs via `node-cron`. Jobs run agent prompts through Claude Code and write results back to the agent's memory file.
---schedule: "0 */6 * * *" # 每6小时
schedule: "0 9 * * 1" # 每周一上午9点
schedule: "0 8 * * " # 每天上午8点
schedule: "/30 * * * *" # 每30分钟
schedule: "0 0 * * 0" # 每周日午夜
Cabinet守护进程(`server/cabinet-daemon.ts`)会读取Agent文件,并通过`node-cron`注册任务。任务会将Agent提示词传给Claude Code执行,并将结果写回Agent的记忆文件。
---Embedded HTML Apps
嵌入式HTML应用
Drop an in any folder under — Cabinet automatically renders it as an embedded iframe with a full-screen toggle:
index.htmldata/data/
my-dashboard/
index.html ← Cabinet renders this as an embedded app
data.json
style.cssExample :
data/my-dashboard/index.htmlhtml
<!DOCTYPE html>
<html>
<head>
<title>Metrics Dashboard</title>
<style>
body { font-family: sans-serif; padding: 20px; background: #1a1a1a; color: #eee; }
.metric { font-size: 2rem; font-weight: bold; color: #55c938; }
</style>
</head>
<body>
<h1>Weekly Metrics</h1>
<div class="metric" id="count">Loading...</div>
<script>
fetch('./data.json')
.then(r => r.json())
.then(d => document.getElementById('count').textContent = d.value)
</script>
</body>
</html>No build step required. Version controlled via git automatically.
在下的任意文件夹中放入文件,Cabinet会自动将其渲染为支持全屏切换的嵌入式iframe:
data/index.htmldata/
my-dashboard/
index.html ← Cabinet会将其渲染为嵌入式应用
data.json
style.css示例:
data/my-dashboard/index.htmlhtml
<!DOCTYPE html>
<html>
<head>
<title>Metrics Dashboard</title>
<style>
body { font-family: sans-serif; padding: 20px; background: #1a1a1a; color: #eee; }
.metric { font-size: 2rem; font-weight: bold; color: #55c938; }
</style>
</head>
<body>
<h1>Weekly Metrics</h1>
<div class="metric" id="count">Loading...</div>
<script>
fetch('./data.json')
.then(r => r.json())
.then(d => document.getElementById('count').textContent = d.value)
</script>
</body>
</html>无需构建步骤,自动通过Git进行版本控制。
Git-Backed History
Git支撑的版本历史
Every save auto-commits. Cabinet wraps git operations in :
src/lib/git.tstypescript
// Auto-commit on every page save (Cabinet handles this internally)
// To access history via the UI:
// 1. Open any page
// 2. Click the history icon in the toolbar
// 3. Browse diffs and restore any version
// To inspect from the shell:
cd data
git log --oneline
git diff HEAD~1 HEAD -- my-project/research.md
git checkout HEAD~5 -- my-project/research.md # Restore older version每次保存都会自动提交。Cabinet在中封装了Git操作:
src/lib/git.tstypescript
// 每次页面保存自动提交(Cabinet内部自动处理)
// 要通过UI访问历史版本:
// 1. 打开任意页面
// 2. 点击工具栏的历史图标
// 3. 浏览差异并恢复任意版本
// 要通过shell查看历史:
cd data
git log --oneline
git diff HEAD~1 HEAD -- my-project/research.md
git checkout HEAD~5 -- my-project/research.md # 恢复旧版本Markdown Page Format
Markdown页面格式
Cabinet pages are standard markdown files with optional frontmatter:
markdown
---
title: Competitor Analysis
tags: [research, competitors, q2-2026]
created: 2026-04-07
agent: research-scout
---Cabinet页面是标准的markdown文件,支持可选的前置元数据:
markdown
---
title: Competitor Analysis
tags: [research, competitors, q2-2026]
created: 2026-04-07
agent: research-scout
---Competitor Analysis
竞品分析
Summary
摘要
...
...
Last Updated by Agent
Agent最后更新
<!-- Agent appends updates here -->
---<!-- Agent会自动将更新追加到此处 -->
---API Routes
API路由
Cabinet exposes Next.js API routes under :
src/app/api/typescript
// Read a page
GET /api/pages?path=my-project/research
// Save a page
POST /api/pages
Body: { path: "my-project/research", content: "# Research\n..." }
// List directory
GET /api/files?dir=my-project
// Run an agent manually
POST /api/agents/run
Body: { agentId: "research-scout" }
// Get agent status
GET /api/agents/status?id=research-scout
// Search all pages
GET /api/search?q=competitor+analysisCabinet在下暴露了Next.js API路由:
src/app/api/typescript
// 读取页面
GET /api/pages?path=my-project/research
// 保存页面
POST /api/pages
Body: { path: "my-project/research", content: "# Research\n..." }
// 列出目录内容
GET /api/files?dir=my-project
// 手动运行Agent
POST /api/agents/run
Body: { agentId: "research-scout" }
// 获取Agent运行状态
GET /api/agents/status?id=research-scout
// 搜索所有页面
GET /api/search?q=competitor+analysisExample: Calling the API from TypeScript
示例:从TypeScript调用API
typescript
// Read a knowledge base page
const response = await fetch('/api/pages?path=my-project/research')
const { content, path } = await response.json()
// Save a page
await fetch('/api/pages', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
path: 'my-project/research',
content: '# Research\n\nUpdated content...'
})
})
// Trigger an agent run
await fetch('/api/agents/run', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ agentId: 'research-scout' })
})typescript
// 读取知识库页面
const response = await fetch('/api/pages?path=my-project/research')
const { content, path } = await response.json()
// 保存页面
await fetch('/api/pages', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
path: 'my-project/research',
content: '# Research\n\nUpdated content...'
})
})
// 触发Agent运行
await fetch('/api/agents/run', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ agentId: 'research-scout' })
})Zustand State Management
Zustand状态管理
Cabinet uses Zustand stores in . Key patterns:
src/stores/typescript
// Access the page store in a component
import { usePageStore } from '@/stores/pageStore'
function MyComponent() {
const { currentPage, savePage, pages } = usePageStore()
const handleSave = async (content: string) => {
await savePage({ path: currentPage.path, content })
}
return <div>{currentPage?.title}</div>
}
// Access agent store
import { useAgentStore } from '@/stores/agentStore'
function AgentPanel() {
const { agents, runAgent, agentStatus } = useAgentStore()
return (
<ul>
{agents.map(agent => (
<li key={agent.id}>
{agent.name} — {agentStatus[agent.id]}
<button onClick={() => runAgent(agent.id)}>Run</button>
</li>
))}
</ul>
)
}Cabinet在目录下使用Zustand存储,核心用法:
src/stores/typescript
// 在组件中访问页面存储
import { usePageStore } from '@/stores/pageStore'
function MyComponent() {
const { currentPage, savePage, pages } = usePageStore()
const handleSave = async (content: string) => {
await savePage({ path: currentPage.path, content })
}
return <div>{currentPage?.title}</div>
}
// 访问Agent存储
import { useAgentStore } from '@/stores/agentStore'
function AgentPanel() {
const { agents, runAgent, agentStatus } = useAgentStore()
return (
<ul>
{agents.map(agent => (
<li key={agent.id}>
{agent.name} — {agentStatus[agent.id]}
<button onClick={() => runAgent(agent.id)}>运行</button>
</li>
))}
</ul>
)
}Pre-Built Agent Templates
预置Agent模板
Located in . Available roles:
data/.agents/.library/| Department | Agents |
|---|---|
| Leadership | CEO, COO, CFO, CTO |
| Product | Product Manager, UX Designer |
| Marketing | Content Marketer, SEO Specialist, Social Media, Growth Marketer, Copywriter |
| Engineering | Editor, QA Agent, DevOps Engineer |
| Sales & Support | Sales Agent, Customer Success |
| Analytics | Data Analyst |
| Operations | People Ops, Legal Advisor, Researcher |
To activate a template:
bash
undefined位于目录下,可用角色:
data/.agents/.library/| 部门 | Agent |
|---|---|
| 管理层 | CEO, COO, CFO, CTO |
| 产品 | 产品经理, UX设计师 |
| 营销 | 内容营销, SEO专家, 社交媒体运营, 增长营销, 文案 |
| 研发 | 编辑器, QA Agent, DevOps工程师 |
| 销售与支持 | 销售Agent, 客户成功 |
| 分析 | 数据分析师 |
| 运营 | 人力运营, 法律顾问, 研究员 |
要激活一个模板:
bash
undefinedCopy a template to active agents
复制模板到活跃Agent目录
cp data/.agents/.library/researcher.md data/.agents/active/my-researcher/index.md
cp data/.agents/.library/researcher.md data/.agents/active/my-researcher/index.md
Then edit goals and schedule in the copied file
然后编辑复制后文件中的目标和schedule
---
---Adding a New Agent Template
添加新的Agent模板
markdown
<!-- data/.agents/.library/custom-scout.md -->
---
name: Custom Scout
role: researcher
schedule: "0 8 * * *"
skills:
- web-search
- summarization
goals:
- Monitor industry news daily
- Summarize top 5 findings
- Append to data/research/daily-digest.md
---markdown
<!-- data/.agents/.library/custom-scout.md -->
---
name: Custom Scout
role: researcher
schedule: "0 8 * * *"
skills:
- web-search
- summarization
goals:
- Monitor industry news daily
- Summarize top 5 findings
- Append to data/research/daily-digest.md
---Custom Scout
Custom Scout
You are a research agent. Each morning you will search for recent developments
in [TOPIC] and append a dated summary to the daily digest.
You are a research agent. Each morning you will search for recent developments
in [TOPIC] and append a dated summary to the daily digest.
Instructions
说明
- Search for "[TOPIC] news" from the last 24 hours
- Select the 5 most relevant items
- Write a 2-3 sentence summary per item
- Append to with today's date as a heading
data/research/daily-digest.md
- 搜索过去24小时内的「[TOPIC] 新闻」
- 选择5个最相关的条目
- 每个条目写2-3句话的摘要
- 以当天日期为标题,追加到中
data/research/daily-digest.md
Memory
记忆
<!-- Populated automatically -->
---<!-- 自动填充 -->
---Common Patterns
常用场景
Pattern 1: Knowledge Base with Agent Automation
场景1:带Agent自动化的知识库
data/
company/
overview.md ← Human-maintained
competitors/
analysis.md ← Agent-updated weekly
index.html ← Auto-generated dashboard
agents/
competitor-scout/
index.md ← Runs every Monday
memory.md ← Tracks what it found last weekdata/
company/
overview.md ← 人工维护
competitors/
analysis.md ← Agent每周更新
index.html ← 自动生成的仪表盘
agents/
competitor-scout/
index.md ← 每周一运行
memory.md ← 记录上周发现的内容Pattern 2: Research Pipeline
场景2:研究流水线
1. Researcher agent scouts Reddit/HN every 6h → writes to data/inbox/
2. Analyst agent summarizes inbox daily → writes to data/research/weekly.md
3. CEO agent reads weekly.md every Monday → writes strategic notes1. 研究员Agent每6小时扫描Reddit/HN → 写入data/inbox/
2. 分析师Agent每天汇总收件箱内容 → 写入data/research/weekly.md
3. CEO Agent每周一读取weekly.md → 输出战略笔记Pattern 3: Using the Web Terminal
场景3:使用网页终端
The web terminal (xterm.js + node-pty) gives full shell access inside the browser:
- Press `Ctrl+`` or click the terminal icon in the sidebar
- Run Claude Code directly:
claude "analyze the data in research/competitors.md" - Full shell: edit files, run scripts, commit to git
网页终端(xterm.js + node-pty)支持在浏览器中直接访问完整的shell:
- 按`Ctrl+``或点击侧边栏的终端图标
- 直接运行Claude Code:
claude "analyze the data in research/competitors.md" - 完整shell能力:编辑文件、运行脚本、提交Git变更
Troubleshooting
故障排查
Daemon not starting
守护进程无法启动
bash
undefinedbash
undefinedCheck if port 3001 is in use
检查3001端口是否被占用
lsof -i :3001
lsof -i :3001
Kill if needed
如果需要,杀死占用进程
kill -9 $(lsof -t -i:3001)
kill -9 $(lsof -t -i:3001)
Restart
重启
npm run dev:all
undefinednpm run dev:all
undefinedClaude Code not found
找不到Claude Code
bash
npm install -g @anthropic-ai/claude-codebash
npm install -g @anthropic-ai/claude-codeVerify
验证安装
claude --version
undefinedclaude --version
undefinedAgent jobs not running
Agent任务不运行
bash
undefinedbash
undefinedCheck daemon logs
查看守护进程日志
npm run dev:daemon
npm run dev:daemon
Verify cron syntax at https://crontab.guru
Check agent frontmatter has valid schedule field
检查Agent前置元数据中是否有合法的schedule字段
undefinedundefinedGit history not working
Git历史不工作
bash
cd data
git statusbash
cd data
git statusIf not initialized:
如果没有初始化:
git init
git add .
git commit -m "initial"
undefinedgit init
git add .
git commit -m "initial"
undefinedPort conflicts
端口冲突
bash
undefinedbash
undefinedNext.js uses 3000, daemon uses 3001
Next.js默认使用3000端口,守护进程默认使用3001端口
Override in package.json scripts or set PORT env var
可以在package.json脚本中覆盖,或者设置PORT环境变量
PORT=3002 npm run dev
undefinedPORT=3002 npm run dev
undefinedEmbedded HTML app not rendering
嵌入式HTML应用不渲染
- File must be named exactly
index.html - Must be inside a folder under
data/ - Check browser console for CSP/iframe errors
- Try accessing directly:
http://localhost:3000/apps/my-folder
- 文件名必须严格为
index.html - 必须放在目录下的某个子文件夹中
data/ - 检查浏览器控制台是否有CSP/iframe错误
- 尝试直接访问:
http://localhost:3000/apps/my-folder
Self-Hosting in Production
生产环境自托管
bash
npm run build
npm run start # Runs both Next.js and daemon in production modebash
npm run build
npm run start # 生产模式同时运行Next.js和守护进程With PM2
使用PM2托管
pm2 start npm --name "cabinet" -- run start
pm2 save
pm2 startup
```nginxpm2 start npm --name "cabinet" -- run start
pm2 save
pm2 startup
```nginxNginx reverse proxy
Nginx反向代理配置
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
}
location /ws {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
}
}
---server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
}
location /ws {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
}
}
---Resources
资源
- Website: runcabinet.com
- Discord: discord.gg/rxd8BYnN
- Cloud Waitlist: runcabinet.com/waitlist
- GitHub: github.com/hilash/cabinet
- Author: @HilaShmuel
- Changelog: in the repo root
CHANGELOG.md
- 官网: runcabinet.com
- Discord: discord.gg/rxd8BYnN
- 云服务等候名单: runcabinet.com/waitlist
- GitHub: github.com/hilash/cabinet
- 作者: @HilaShmuel
- 变更日志: 仓库根目录下的
CHANGELOG.md