运维安装
- 作者仓库星标 0
- 作者更新于 实时读取
- 作者仓库 nano-core
- 领域
- 通用
- 兼容 Agent
-
- Claude Code
- Cursor
- Cline
- Codex
- Windsurf
- Gemini CLI
- +20
- 信任分
- 83 / 100 · 社区维护
- 作者 / 版本 / 许可
- @0-CYBERDYNE-SYSTEMS-0 · 未声明 license
- Token 消耗评级
- 低消耗
- 接入复杂程度
- 需手动接入
- 是否需要外部 API Key
- 需要 · Anthropic
- 兼容的系统
- macOS · Linux · Docker
- 底层运行要求
- Node.js · Docker
- 文件与系统权限
-
- 只读
- 允许写入 / 修改
- Shell 执行
- 读取环境变量
- 网络行为
- 允许外网请求
- 安装命令数
- 26 条
档案由构建时根据 SKILL.md 与安装命令自动衍生,可能与作者实际意图存在差异。
需要注意: 未限定 allowed-tools,默认拥有全部工具权限。;检出高风险片段:pipe_curl_to_shell
---
name: setup
description: Run initial nano-core setup. Use when user wants to install dependencies, authenticate WhatsApp…
category: 通用
runtime: Node.js / Docker
---
# setup 输出预览
## PART A: 任务判断
- 适用问题:通用任务拆解、检查和交付。
- 输入要求:目标材料、限制条件、期望输出和验收方式。
- 证据边界:围绕“1. Install Dependencies / 2. Install Runtime (Docker Default, Host Optional) / Preferred Path: Docker Runtime”读取原文规则,不把推断写成作者承诺。
## PART B: 执行结果
- **01** 任务判断:确认你的需求是否属于通用任务拆解、检查和交付,并标出输入、限制和预期结果。
- **02** 执行计划:优先按“1. Install Dependencies / 2. Install Runtime (Docker Default, Host Optional) / Preferred Path: Docker Runtime”拆成步骤,说明每一步会读取什么、修改什么、产出什么。
- **03** 交付结果:给出可复制的命令、文件改动、检查清单或内容草稿,并说明如何继续迭代。
- **04** 风险边界:结合 读取文件、写入/修改文件、执行终端命令、读取环境变量、会按任务需要访问外部网络、需要准备 Anthropic API Key 给出执行前确认项。
## Running Rules
- 读取文件、写入/修改文件、执行终端命令、读取环境变量;会按任务需要访问外部网络;需要准备 Anthropic API Key。
- 先小样例验证,再放大到真实任务。
- 交付时同时给结果、检查口径和下一步迭代建议。 原文出现了 `/path`、`/bin` 这类斜杠命令;如果你的 Agent 支持命令触发,优先用命令开场,再补充目标和边界。
告诉 Agent 目标文件或材料、期望结果、不可改范围、是否允许联网或执行命令。本 Skill 的权限画像是:读取文件、写入/修改文件、执行终端命令、读取环境变量。
先用一个小任务确认它会围绕“1. Install Dependencies / 2. Install Runtime (Docker Default, Host Optional) / Preferred Path: Docker Runtime”工作;涉及文件或命令时,先看 diff、日志、预览或测试结果。
检查最终产物是否包含明确结果、必要证据和下一步动作;如果输出泛泛而谈,就补充输入、边界和验收标准后重跑。
---
name: setup
description: Run initial nano-core setup. Use when user wants to install dependencies, authenticate WhatsApp…
category: 通用
source: 0-CYBERDYNE-SYSTEMS-0/nano-core
---
# setup
## 什么时候使用
- setup 是一个通用扩展技能,按 SKILL 适合处理通用任务拆解、检查、交付和复盘,核心价值是把输入、判断、执行、验证和交付边界固定下来,避免 Agent 泛泛回答。 把任务拆成可执行、可检查、可继续迭代的步骤;使用前要准备 Ant…
- 面向通用任务拆解、检查和交付,优先处理能明确输入、步骤和验收标准的工作。
## 需要提供什么
- 目标材料、目录范围、期望结果和不可改动内容。
- 是否允许联网、执行命令、读写文件或调用外部服务。
## 执行规则
- 围绕「1. Install Dependencies / 2. Install Runtime (Docker Default, Host Optional) / Preferred Path: Docker Runtime」组织步骤,不把推断写成作者事实。
- 读取文件、写入/修改文件、执行终端命令、读取环境变量;会按任务需要访问外部网络;需要准备 Anthropic API Key。
- 先跑小样例,确认结果可检查后再扩大任务范围。
## 输出要求
- 给出最终产物、关键证据、验证方式和下一步动作。
- 信息不足时标记 unknown,不编造命令、平台或依赖。 作者原文负责流程事实;仓库文件负责来源和命令;流狐只补充适用场景、限制和质量判断。
skill "setup" {
输入层 -> 用户目标 + 目标文件 + 禁止范围 + 验收标准
上下文层 -> 1. Install Dependencies / 2. Install Runtime (Docker Default, Host Optional) / Preferred Path: Docker Runtime
规则层 -> SKILL.md 触发条件 / 执行顺序 / 输出格式
运行层 -> Node.js / Docker | 读取文件、写入/修改文件、执行终端命令、读取环境变量 | 会按任务需要访问外部网络
安全层 -> 需要准备 Anthropic API Key + 小任务验证 + diff / 日志复核
输出层 -> 可复制结果 + 检查清单 + 下一步迭代
} nano-core Setup
Run all commands automatically. Only pause when user action is required (scanning QR codes).
UX Note: When asking the user questions, prefer using the AskUserQuestion tool instead of just outputting text. This integrates with Claude's built-in question/answer system for a better experience.
1. Install Dependencies
npm install
2. Install Runtime (Docker Default, Host Optional)
First, detect what is available:
echo "Platform: $(uname -s)"
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
echo "Docker: installed and running"
else
echo "Docker: not installed or not running"
fi
Preferred Path: Docker Runtime
Tell the user:
nano-core now defaults to Docker for isolated execution. I'll configure that as the primary runtime.
If Docker is missing or stopped, guide installation:
macOS
- Install Docker Desktop from https://www.docker.com/products/docker-desktop/
- Open Docker Desktop and wait until it reports "Engine running"
Linux
- Install Docker Engine:
curl -fsSL https://get.docker.com | sh - Start daemon:
sudo systemctl start docker - Optional non-root usage:
sudo usermod -aG docker $USER(then re-login)
Verify:
docker --version
docker info >/dev/null && echo "Docker ready"
Advanced Path: Host Runtime (No Container)
Only use if user explicitly wants no-container mode.
Set:
cat <<'EOF' >> .env
CONTAINER_RUNTIME=host
FFT_NANO_ALLOW_HOST_RUNTIME=1
EOF
For production, require an explicit second opt-in:
echo "FFT_NANO_ALLOW_HOST_RUNTIME_IN_PROD=1" >> .env
3. Configure Claude Authentication
Ask the user:
Do you want to use your Claude subscription (Pro/Max) or an Anthropic API key?
Option 1: Claude Subscription (Recommended)
Tell the user:
Open another terminal window and run:
claude setup-tokenA browser window will open for you to log in. Once authenticated, the token will be displayed in your terminal. Either:
- Paste it here and I'll add it to
.envfor you, or- Add it to
.envyourself asCLAUDE_CODE_OAUTH_TOKEN=<your-token>
If they give you the token, add it to .env:
echo "CLAUDE_CODE_OAUTH_TOKEN=<token>" > .env
Option 2: API Key
Ask if they have an existing key to copy or need to create one.
Copy existing:
grep "^ANTHROPIC_API_KEY=" /path/to/source/.env > .env
Create new:
echo 'ANTHROPIC_API_KEY=' > .env
Tell the user to add their key from https://console.anthropic.com/
Verify:
KEY=$(grep "^ANTHROPIC_API_KEY=" .env | cut -d= -f2)
[ -n "$KEY" ] && echo "API key configured: ${KEY:0:10}...${KEY: -4}" || echo "Missing"
4. Build Runtime Artifacts
Docker mode (default)
./container/build.sh
echo '{}' | docker run -i --entrypoint /bin/echo nano-core-agent:latest "Container OK"
Host mode (advanced)
npm --prefix container/agent-runner install
npm --prefix container/agent-runner run build
test -f container/agent-runner/dist/index.js && echo "Host runner OK"
5. WhatsApp Authentication
USER ACTION REQUIRED
Run the authentication script:
npm run auth
Tell the user:
A QR code will appear. On your phone:
- Open WhatsApp
- Tap Settings → Linked Devices → Link a Device
- Scan the QR code
Wait for the script to output "Successfully authenticated" then continue.
If it says "Already authenticated", skip to the next step.
6. Configure Assistant Name
Ask the user:
What trigger word do you want to use? (default:
Andy)Messages starting with
@TriggerWordwill be sent to Claude.
If they choose something other than Andy, update it in these places:
groups/CLAUDE.md- Change "# Andy" and "You are Andy" to the new namegroups/main/CLAUDE.md- Same changes at the topdata/registered_groups.json- Use@NewNameas the trigger when registering groups
Store their choice - you'll use it when creating the registered_groups.json and when telling them how to test.
7. Understand the Security Model
Before registering your main channel, you need to understand an important security concept.
Use the AskUserQuestion tool to present this:
Important: Your "main" channel is your admin control portal.
The main channel has elevated privileges:
- Can see messages from ALL other registered groups
- Can manage and delete tasks across all groups
- Can write to global memory that all groups can read
- Has read-write access to the entire nano-core project
Recommendation: Use your personal "Message Yourself" chat or a solo WhatsApp group as your main channel. This ensures only you have admin control.
Question: Which setup will you use for your main channel?
Options:
- Personal chat (Message Yourself) - Recommended
- Solo WhatsApp group (just me)
- Group with other people (I understand the security implications)
If they choose option 3, ask a follow-up:
You've chosen a group with other people. This means everyone in that group will have admin privileges over nano-core.
Are you sure you want to proceed? The other members will be able to:
- Read messages from your other registered chats
- Schedule and manage tasks
- Access any directories you've mounted
Options:
- Yes, I understand and want to proceed
- No, let me use a personal chat or solo group instead
8. Register Main Channel
Ask the user:
Do you want to use your personal chat (message yourself) or a WhatsApp group as your main control channel?
For personal chat:
Send any message to yourself in WhatsApp (the "Message Yourself" chat). Tell me when done.
For group:
Send any message in the WhatsApp group you want to use as your main channel. Tell me when done.
After user confirms, start the app briefly to capture the message:
timeout 10 npm run dev || true
Then find the JID from the database:
# For personal chat (ends with @s.whatsapp.net)
sqlite3 store/messages.db "SELECT DISTINCT chat_jid FROM messages WHERE chat_jid LIKE '%@s.whatsapp.net' ORDER BY timestamp DESC LIMIT 5"
# For group (ends with @g.us)
sqlite3 store/messages.db "SELECT DISTINCT chat_jid FROM messages WHERE chat_jid LIKE '%@g.us' ORDER BY timestamp DESC LIMIT 5"
Create/update data/registered_groups.json using the JID from above and the assistant name from step 5:
{
"JID_HERE": {
"name": "main",
"folder": "main",
"trigger": "@ASSISTANT_NAME",
"added_at": "CURRENT_ISO_TIMESTAMP"
}
}
Ensure the groups folder exists:
mkdir -p groups/main/logs
9. Configure External Directory Access (Mount Allowlist)
Ask the user:
Do you want the agent to be able to access any directories outside the nano-core project?
Examples: Git repositories, project folders, documents you want Claude to work on.
Note: This is optional. Without configuration, agents can only access their own group folders.
If no, create an empty allowlist to make this explicit:
mkdir -p ~/.config/nano-core
cat > ~/.config/nano-core/mount-allowlist.json << 'EOF'
{
"allowedRoots": [],
"blockedPatterns": [],
"nonMainReadOnly": true
}
EOF
echo "Mount allowlist created - no external directories allowed"
Skip to the next step.
If yes, ask follow-up questions:
9a. Collect Directory Paths
Ask the user:
Which directories do you want to allow access to?
You can specify:
- A parent folder like
~/projects(allows access to anything inside)- Specific paths like
~/repos/my-appList them one per line, or give me a comma-separated list.
For each directory they provide, ask:
Should
[directory]be read-write (agents can modify files) or read-only?Read-write is needed for: code changes, creating files, git commits Read-only is safer for: reference docs, config examples, templates
9b. Configure Non-Main Group Access
Ask the user:
Should non-main groups (other WhatsApp chats you add later) be restricted to read-only access even if read-write is allowed for the directory?
Recommended: Yes - this prevents other groups from modifying files even if you grant them access to a directory.
9c. Create the Allowlist
Create the allowlist file based on their answers:
mkdir -p ~/.config/nano-core
Then write the JSON file. Example for a user who wants ~/projects (read-write) and ~/docs (read-only) with non-main read-only:
cat > ~/.config/nano-core/mount-allowlist.json << 'EOF'
{
"allowedRoots": [
{
"path": "~/projects",
"allowReadWrite": true,
"description": "Development projects"
},
{
"path": "~/docs",
"allowReadWrite": false,
"description": "Reference documents"
}
],
"blockedPatterns": [],
"nonMainReadOnly": true
}
EOF
Verify the file:
cat ~/.config/nano-core/mount-allowlist.json
Tell the user:
Mount allowlist configured. The following directories are now accessible:
~/projects(read-write)~/docs(read-only)Security notes:
- Sensitive paths (
.ssh,.gnupg,.aws, credentials) are always blocked- This config file is stored outside the project, so agents cannot modify it
- Changes require restarting the nano-core service
To grant a group access to a directory, add it to their config in
data/registered_groups.json:"containerConfig": { "additionalMounts": [ { "hostPath": "~/projects/my-app", "containerPath": "my-app", "readonly": false } ] }
10. Configure launchd Service
Generate the plist file with correct paths automatically:
NODE_PATH=$(which node)
PROJECT_PATH=$(pwd)
HOME_PATH=$HOME
cat > ~/Library/LaunchAgents/com.nano-core.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.nano-core</string>
<key>ProgramArguments</key>
<array>
<string>${NODE_PATH}</string>
<string>${PROJECT_PATH}/dist/index.js</string>
</array>
<key>WorkingDirectory</key>
<string>${PROJECT_PATH}</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:${HOME_PATH}/.local/bin</string>
<key>HOME</key>
<string>${HOME_PATH}</string>
</dict>
<key>StandardOutPath</key>
<string>${PROJECT_PATH}/logs/nano-core.log</string>
<key>StandardErrorPath</key>
<string>${PROJECT_PATH}/logs/nano-core.error.log</string>
</dict>
</plist>
EOF
echo "Created launchd plist with:"
echo " Node: ${NODE_PATH}"
echo " Project: ${PROJECT_PATH}"
Build and start the service:
npm run build
mkdir -p logs
launchctl load ~/Library/LaunchAgents/com.nano-core.plist
Verify it's running:
launchctl list | grep nano-core
11. Test
Tell the user (using the assistant name they configured):
Send
@ASSISTANT_NAME helloin your registered chat.
Check the logs:
tail -f logs/nano-core.log
The user should receive a response in WhatsApp.
Troubleshooting
Service not starting: Check logs/nano-core.error.log
Agent runtime fails with "Claude Code process exited with code 1":
- Ensure runtime is available:
- Docker mode:
docker info(start Docker Desktop on macOS, orsudo systemctl start dockeron Linux) - Host mode: verify
.envhasCONTAINER_RUNTIME=hostandFFT_NANO_ALLOW_HOST_RUNTIME=1
- Docker mode:
- Check per-run logs:
cat groups/main/logs/runtime-*.log | tail -50
No response to messages:
- Verify the trigger pattern matches (e.g.,
@AssistantNameat start of message) - Check that the chat JID is in
data/registered_groups.json - Check
logs/nano-core.logfor errors
WhatsApp disconnected:
- The service will show a macOS notification
- Run
npm run authto re-authenticate - Restart the service:
launchctl kickstart -k gui/$(id -u)/com.nano-core
Unload service:
launchctl unload ~/Library/LaunchAgents/com.nano-core.plist
先判断是否适合
作者设计意图
作者的方法与取舍
边界和复核