证据快照复核于 2026-09-03GitHub 数据核对日期: 2026-08-21
来源已审查独立 Skill开发工具developer Profile

mobius-extension

用于构建 Mobius AI 扩展,涵盖后端处理器、前端 SDK 集成和扩展清单规范。

快速了解

它能做什么

用于构建 Mobius AI 扩展,涵盖后端处理器、前端 SDK 集成和扩展清单规范。

本站提供的是中文说明,不代表该项目或 Plugin 自身提供中文界面;语言支持请以上游文档为准。

能力
开发工具编码配置文档

选择前先看

当需求适合作为 Mobius 扩展而不是独立项目时使用。该技能说明扩展目录结构、无状态 CommonJS 后端处理器协议、前端 extCall SDK、零编译或 Vite/Webpack 构建方式、命名与可见性规则、重载步骤及调试接口。

适合谁

需要为 Mobius AI 部署开发扩展的开发者。

常见任务

  • 创建包含 extension.json、后端处理器和前端入口页的新扩展。
  • 通过 extCall SDK 调用扩展后端,而非自行拼接 API 请求。
  • 选择免编译前端或 Vite/Webpack 构建,并排查重建或处理器日志。

权限与数据

文档所述的扩展运行时会处理用户身份和扩展请求。

权限
  • 后端处理器会收到经 JWT 注入的用户名和显示名。
  • 处理器只能写入 ext_data_dir。
  • 前端 SDK 会读取本地 cc-token JWT 来发起扩展调用。
数据处理
  • 扩展数据保存在扩展专属的 protected_data 目录中。
  • 必须校验输入载荷的类型和边界。
凭据
  • 测试文档中的接口需要使用 Mobius JWT 密钥签发的 JWT。

局限

  • 仅适用于 Mobius 扩展,不适用于独立应用。
  • 后端处理器必须保持无状态,并遵守文档中的时长、载荷、速率和内存限制。
  • 商业使用需另行取得商业许可证。

DSHub 已核对

  • 已捕获完整的固定版本技能文档。
  • 源代码提交已固定。

DSHub 未核对

  • DSHub 未安装或执行该技能。
  • 提供的证据未声明 Mobius Harness 版本范围。

固定版本安装

主要操作

这个独立 Skill没有 DSH Plugin 安装操作,请根据源码文档使用真实交付方式。

访问源码项目

维护者原文

Skill 使用说明

查看 commit 1eb8750 对应的 SKILL.md
维护者编写的上游内容原文于 2026/8/30skills/mobius-extension/SKILL.md 获取,正文和仓库相对媒体固定到 commit 1eb8750d2d90,内容哈希为 189b2e01b5a6。以下是未经 DSHub 翻译的上游原文,语言可能与当前页面不同;第三方托管的 badge 可能独立更新。

name: mobius-extension description: 在莫比乌斯 AI 中开发一个新拓展插件 (特殊应用). 含后端 handler 协议、前端 SDK / 编译策略、目录与命名规范。一旦用户选择了这个SKILL(当然,也不排除选错的可能性),你需要认真考虑如何把用户的需求做成 Mobius 拓展,而不是一个完全独立的项目。

开发 mobius 拓展

拓展 = mobius/extension/<name>/ 一个目录. 新 tab 打开 /extension/<name>/ 运行, 后端走 /api/ext 转发, 数据落到 APP_DIR/protected_data/extension/<name>/. 样例: mobius/extension/pacman/.

mobius/extension/<name>/
├── extension.json
├── backend/extension_backend_handler.js
├── backend/...others...
└── frontend/index.html
└── frontend/...others(main.js / package.json / ...)...

1. 后端

文件固定 backend/extension_backend_handler.js, CommonJS, 导出 async 函数:

module.exports = async function ({
  username,           // string, JWT 注入, 可信
  display_name,
  ext_main_payload,   // any JSON, 前端传的 payload
  ext_data_dir,       // 绝对路径, 你唯一可写区
  extension_name,
  logger,             // info/warn/error → ext_data_dir/_handler.log
}) {
  // 推荐按 ext_main_payload.action 分发
  return { ok: true, /* ... */ };  // 或 { ok: false, error: '...' }
};

硬约束 (违反 → 504/502/500/429):

上限
单次时长 30 s
返回 JSON 5 MB
入参 payload 1 MB
速率 5 rps / 用户
内存 256 MB
状态 stateless -- 模块顶层不能有连接/定时器/cache, 每次新 worker_thread
文件 IO 只能 path.join(ext_data_dir, ...), 不能 process.chdir() (worker_thread 禁用)
stdout 不回流, 用 logger.*

样例 (吃豆人排行榜):

const path = require('path'), fs = require('fs/promises');
module.exports = async function ({ username, ext_main_payload, ext_data_dir }) {
  const lb = path.join(ext_data_dir, 'leaderboard.json');
  if (ext_main_payload.action === 'submit_score') {
    const score = Number(ext_main_payload.score) | 0;
    if (score < 0 || score > 1e7) return { ok: false, error: 'invalid score' };
    let list = []; try { list = JSON.parse(await fs.readFile(lb, 'utf8')); } catch {}
    list.push({ username, score, ts: Date.now() });
    list.sort((a, b) => b.score - a.score);
    await fs.writeFile(lb, JSON.stringify(list.slice(0, 100)));
    return { ok: true };
  }
};

handler 改动按 mtime 自动失效 require 缓存, 不用重启.


2. 前端

frontend/index.html 是入口. 后端自动注入 <script>window.__EXT_NAME__="<name>";</script><head>.

调用后端只用 SDK, 别自己拼 fetch('/api/ext'):

import { extCall } from '/extension/_sdk/ext.js';
const r = await extCall({ action: 'submit_score', score: 1234 });
// SDK 自动: 从 localStorage['cc-token'] 取 JWT + 填 extension_name + 包 ext_main_payload

编译策略二选一:

  • 零编译: 不写 package.json. 首访时后端把 frontend/* 拷到 dist/. 用浏览器原生 ESM. 改完调 POST /api/admin/extensions/<name>/rebuild.
  • vite/webpack: frontend/package.json"build": "vite build", 产物必须在 frontend/dist/index.html. 首访自动 npm install + npm run build, 用户看 loading 页轮询. 日志: protected_data/extension/<name>/_build.log, 或 GET /api/extensions/<name>/build-status.

隔离: 新 tab = 独立 JS 引擎. 不要 import 主前端代码, 不要覆盖 localStorage['cc-token'].


3. 规范

命名: <name> 必须 ^[a-z][a-z0-9-]{0,31}$, 且 extension.json:name = 目录名.

manifest (extension.json):

{ "name": "<name>", "display_name": "中文名", "description": "...", "version": "0.1.0", "icon": "favicon.svg", "project": { "sync": true } }

不要写 entry / handler 路径, 是约定固定的. project 可选, 只有一个字段:

  • project.sync (默认 true): false 时该拓展不进 DB, 完全不出现在任何项目列表里 (等同于"不启用"). 其它情况都会作为一个 kind=extension 的项目入库.
  • project.default_hidden: 已移除. 拓展一律默认可见, 不再支持"默认隐藏"; 想让某拓展不出现, 用 sync: false 或直接不放进 mobius/extension/.

可见性规则 (简单版): 每个拓展默认对所有人可见. 用户可在项目页隐藏任意拓展, 也可在「已屏蔽项目」里随时恢复显示——只对自己生效, 不影响别人, 不删数据. 后端只有一个可见性来源 (用户屏蔽 = user_muted_projects); 拓展卡片只提供"隐藏"一个动作. 彻底删除某用户在该拓展的数据是管理员专属操作 (管理中心 → 拓展 → 已隐藏的拓展 → 彻底删除), 普通用户没有这个能力.

特殊拓展项目 (kind=extension 的 project) 由 registry 自动 upsert, 锁死: bind_path=APP_DIR, worktree=false, research=false, created_by=system (但每个用户的项目页都能看到). 不能从 UI 删, 不能改 name/desc/path/repos/worktree/research, 可改 forgotten_flag.* 与星标.

生命周期: 新增 → POST /api/admin/extensions/reload (或 python3 start.py 重启). 删除 → 删目录 + reload, DB 行保留 (标 disabled), 用户在该项目下的 issue/session 不丢; 目录补回 → reload → 自动恢复.

调试套路:

# JWT
TOKEN=$(node -e "console.log(require('jsonwebtoken').sign({id:'<uid>'},'<JWT_SECRET>',{expiresIn:'1h'}))")
# 列表 / 调 handler / 重 reload / 重新 build
# find $MOBIUS_PORT in `env var` or `.env` or `.env.default`, default 33314
curl -H "Authorization: Bearer $TOKEN" http://localhost:$MOBIUS_PORT/api/extensions
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"extension_name":"<name>","ext_main_payload":{"action":"..."}}' \
  http://localhost:$MOBIUS_PORT/api/ext
curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:$MOBIUS_PORT/api/admin/extensions/reload
curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:$MOBIUS_PORT/api/admin/extensions/<name>/rebuild
tail -f APP_DIR/protected_data/extension/<name>/_handler.log
tmux attach -t mobius-system   # 看后端实时日志

禁忌:

  • handler 顶层持有状态 / 用 process.chdir / 写 ext_data_dir 之外的路径
  • 直接 fetch('/api/...') 调 mobius 其他接口 (走 extCall 之外的 API 没有授权也没必要)
  • node_modules/ / dist/ 提交进仓库
  • 信任 ext_main_payload: 一律校验类型 + 边界
  • 回显 stack trace, 只返回 { ok:false, error:'简短' }

4. 主项目联合修改

有时候只修改extension无法优雅地解决问题,需要主项目配合修改。这是允许的,但修改需要足够的通用性,不能只为一个特定的extension服务。

有意识地管理

安装与管理

前置条件与目标 Profile

目标 developer Profile

交付方式 Skill 文件 — https://raw.githubusercontent.com/nutshellai-tech/mobius/1eb8750d2d9012e1f50a18f7c60c2ad040c04889/skills/mobius-extension/SKILL.md

兼容性与访问范围

For developing extensions for Mobius AI Not declared in supplied evidence

检查兼容性证据

风险事实

license

Source-available license permits non-commercial use; commercial use requires a separate license.

证据
data-access

Extension handlers receive trusted user identity fields and may write only inside their assigned extension data directory.

证据
证据与编辑审查Manifest、Bundle patch、分发与新鲜度

不可变证据

审查状态与源码活动

人工已批准

在核对来源内容和不可变发布记录后,已由人工批准发布。AI 参与了内容草稿生成,最终发布决定由人工完成。

人工审查于 2026/9/4 UTC 11:38GitHub 事实核对日期: 2026/9/3 UTC 15:47

自当前证据基线以来,没有记录到重要源码变化。

下一步

比较生态 Artifact 类型

订阅重要变化: mobius-extension