# 长大智耘开发者文档(全量) > 本文件由 https://zhiyun.lansuan.cc/docs/llms.txt 索引的全部文档正文拼接而成,供 AI 助手一次性读取。文档门户:https://zhiyun.lansuan.cc/docs/ --- # 快速开始 > 开发者中心登录、能力目录确认、创建项目与版本流程、错误处理。 ## 接入步骤 1. 用平台账号登录开发者中心(`/developer/login`,与业务前台/管理后台是相互独立的会话域)。 2. 确认可用能力:`GET /api/developer/capabilities`(全量目录)与 `GET /api/developer/tools`(系统工具名清单)。 3. 创建项目:Skill 走「创建 Skill 项目 + skill.zip 上传」;Plugin 在创建弹窗里选 HTTP API 或 MCP Server 接入;App 在「应用开发」里新建后上传 app.zip。 4. 版本流程:保存草稿 → 服务端校验 → 提交审核 → 管理员通过后发布,进入平台能力目录 / 技能目录 / 应用中心。 ## 错误处理 - 401:会话失效,前端会清除本地令牌并要求重新登录。 - 403:权限不足,例如开发者访问 `/api/admin/**` 管理接口。 - 权限在服务端逐请求判定,前端隐藏菜单不构成安全边界。 --- # Extension Manifest > apiVersion / kind / id / runtime / capabilities 字段结构与 JSON Schema 校验约束。 ## 结构 - `apiVersion` 固定为 `zhiyun/v1`;`kind` 取 `Skill / Plugin / App / Bundle`(App 的打包清单是 app.json,见「App SDK」)。 - `id` 为全局唯一标识,格式 `cn.edu.yangtzeu.〈开发者账号〉.skill|plugin|app.〈短码〉`(如 `cn.edu.yangtzeu.smartagri.weather`);创建项目时只需填最后一段短码(如 `rice-pest-guard`),完整 id 由平台按会话身份拼装,清单中的 `id` 必须与拼装结果一致;`version` 必须是语义化版本。 - Plugin 的 `runtime`:remote-http(`url` 必须 https,`method` 取 GET/POST,可选 `auth.header` + `auth.secretRef`)或 remote-mcp(`url` 必须 https,可选 auth)。 - 每个能力(`capabilities[]`)声明 `id / name / description / type / risk / inputSchema / outputSchema / rateLimitPerMinute`。 - `risk` 取 `LOW / MEDIUM / HIGH / CRITICAL`,缺省 `LOW`;密钥值在「Secret 声明与值」面板录入,接口不回显。 > Schema 校验约束:inputSchema / outputSchema 是 JSON Schema 字符串;能力经 MCP 暴露给 Agent 时只下发 type=object 的 outputSchema,其他形态会被网关拒绝。 ## 示例 ### Plugin Manifest(remote-http) ```yaml apiVersion: zhiyun/v1 kind: Plugin id: cn.edu.yangtzeu.smartagri.weather name: 天气查询插件 version: 0.1.0 publisher: developer description: 查询指定城市当前天气 runtime: name: remote-http url: https://api.example.com/weather method: POST auth: header: X-Api-Key secretRef: API_KEY permissions: capabilities: [] secrets: - API_KEY capabilities: - id: weather_query name: weather_query description: 按城市名查询当前天气 type: TOOL risk: LOW inputSchema: '{"type":"object","properties":{"city":{"type":"string","description":"城市名"}},"required":["city"],"additionalProperties":false}' outputSchema: '{"type":"object"}' rateLimitPerMinute: 30 ``` ### Plugin Manifest(remote-mcp 骨架,工具经「发现」确认后写入) ```yaml apiVersion: zhiyun/v1 kind: Plugin id: cn.edu.yangtzeu.smartagri.mcp.demo name: MCP 示例插件 version: 0.1.0 publisher: developer runtime: name: remote-mcp url: https://mcp.example.com/mcp permissions: capabilities: [] capabilities: [] ``` --- # 技能开发 > skill.zip 包结构、SKILL.md 指令要求、目录白名单、版本流程与 Manifest 示例。 ## skill.zip 包结构 - 包根(或唯一顶层目录)必须有 `SKILL.md`:技能指令内容(Markdown),不能为空。 - 允许的目录:`scripts/` `references/` `assets/` `agents/` 与根下任意文件;白名单外条目会被拒绝。 - 限制:包体 ≤ 10MB,条目 ≤ 200 个,解压总量 ≤ 20MB,单文件 ≤ 2MB;`__MACOSX/`、`.DS_Store`、`._*` 等系统杂项会被忽略并提示。 ## 版本流程 - 上传即写入草稿(已有草稿则覆盖,否则自动开新补丁版本草稿)。 - `requires.capabilities` 中的能力 ID 必须已在平台注册,校验不通过则无法提交审核。 - 管理员审核通过并发布后,技能对所有平台用户可见(`/api/skills`)。 ## 示例 ### Skill Manifest ```yaml apiVersion: zhiyun/v1 kind: Skill id: cn.edu.yangtzeu.smartagri.fieldnote name: 田间记录助手 version: 0.1.0 publisher: developer requires: capabilities: - get_current_time ``` --- # Plugin 接入 > remote-http / remote-mcp / local-node / local-python 三种接入方式选型、真实案例与认证密钥。 ## 30 秒选型 有现成的 https 接口 → **HTTP API**;对方本身是 MCP 服务器 → **MCP Server**;要自己写逻辑计算 → **上传代码**。 ## HTTP API(remote-http):把现成接口包装成 Agent 工具 - **本质**:把别人服务器上现成的 https 接口包装成 Agent 可调用的工具——你只填 URL 和参数表,平台自动生成 `inputSchema`;GET 请求的扁平标量参数展开为查询串,POST 走 JSON body。 - **真实案例**:已上线的「农区天气实况」就是把 Open-Meteo 的 `https://api.open-meteo.com/v1/forecast` 包了一把,参数 lat / lon,无密钥。需要密钥的站点用 `auth.header` + `secretRef`,密钥值在平台「Secret 声明与值」面板录入、不回显。 - **适合**:想接的 API 已经存在且公网可达。**不适合**:需要自己写业务逻辑、或没有现成 API 的场景(那是「上传代码」)。 ## MCP Server(remote-mcp):接入生态里现成的 MCP 服务 - 对方本身就是一台 MCP 服务器:平台真实握手 `initialize` → `tools/list` 拉取工具清单,你勾选确认后每个工具自动成为一个能力;Agent 调用时平台转发 `tools/call`。 - **适合**:工具已由对方维护、你只想接入(如内部知识库 MCP、第三方工具 MCP)。 ## 上传代码(local-node / local-python):自己写逻辑跑在沙箱里 - 自己写纯函数,跑在平台 Extension Host 隔离子进程里——**无网络、无文件系统、无第三方依赖**(local-node 禁止 package.json,只用运行时内置模块)。 - **真实案例**:「测土配方施肥计算器」(Python,按土壤养分与目标产量算施肥量)、「农产品价格牌生成器」(Node,输入价格数据输出价格牌文案)。 - **适合**:数值计算、格式转换等纯计算逻辑。**不适合**:需要访问外部 API 的场景(用 HTTP API 或 MCP)。 ## 认证与密钥 - 选择 API Key 认证时,声明请求头名称与 `secretRef`;manifest 顶层 `secrets:` 列出声明名,真实值在「Secret 声明与值」面板录入(加密存储、不回显)。 - 沙箱测试经平台完整安全链路真实调用一次:仅 https 公网地址(SSRF 防护)、15 秒超时、响应截断。 > 远端地址必须为 https 公网地址;内网、回环、fake-ip 等会被 SSRF 防护拒绝。 --- # App SDK 与 AppBridge > app.json 应用清单、iframe 沙箱与 CSP 安全方案、window.zhiyun AppBridge API。 ## app.zip 包与应用清单 - 包内必须有 `app.json`(字段与约束见 app.json 示例),且 `entry.path` 指向包内存在的入口 HTML。 - `permissions` 只能取平台已开放的权限词(`profile / storage / agent.run / capability.invoke` 等),越权声明会被拒绝。 - 上传 app.zip 会校验清单并把入口 HTML 写入当前草稿;包结构与文件大小限制与 skill.zip 相同。 ## 托管与安全方案 - App 以 iframe(`sandbox="allow-scripts"`,不含 allow-same-origin)嵌入,响应携带 `Content-Security-Policy: sandbox`,以不透明源运行。 - 平台会话凭据不进入 App;opaque origin 下无法使用 localStorage,持久化统一走 zhiyun.storage.*(按用户+App 隔离)。 ## window.zhiyun(SDK) - `user.getCurrent()`:当前用户基本资料(需 profile 权限)。 - `storage.get / set / remove`:应用自身存储读写(需 storage 权限)。 - `navigation.open`:仅白名单站内路径(/app、/app/chat、/app/tasks 等)。 - `agent.run / status / result / stop / runAndWait`(需 agent.run 权限):以当前用户身份创建真实智耘会话并启动模型-工具循环;联网与技能沿用会话默认(关闭),App 不得静默开启。 - `capability.invoke`(需 capability.invoke 权限):经 CapabilityBroker 全链路执行;风险 EXTERNAL 的能力不执行,返回 `APPROVAL_REQUIRED` 审批状态;未注册能力 404。 ## 示例 ### app.json ```json { "schemaVersion": 1, "id": "cn.edu.yangtzeu.smartagri.note", "name": "农情速记", "version": "1.0.0", "description": "试验数据快速记录", "entry": { "type": "web", "path": "index.html" }, "permissions": ["profile", "storage"], "dependencies": {} } ``` --- # 知识库 > 平台/个人知识库生命周期、knowledge_search 能力调用方式与管理 API。 ## 平台知识库与个人知识库 - 「知识库」页(`/developer/knowledge-bases`)展示平台知识库与我的知识库;个人库添加纯文本文档,保存时自动按 500 字符 / 50 重叠分块建立检索索引。 - 个人库提交审核(至少一篇文档),管理员在 `/admin/reviews` 通过后上线为平台知识库,对所有用户可见;驳回必须附意见,可修改后重新提审;审核中不能改文档,可撤回。 ## knowledge_search 能力(应用 / 插件 / 技能通用) - 能力 ID:`knowledge_search`(系统内置、只读、scope=PLATFORM),在 `GET /api/developer/capabilities` 目录中可见。 - 输入:`{"query": "检索问题", "kb": "kb-xxxxxxxx(可选,限定知识库)", "topK": 4}`;返回 `results[]`(kb / kbName / documentTitle / seq / score / snippet)。 - 检索范围 = 全部平台知识库 + 调用者自己的知识库(含草稿);无权访问他人的个人库。 - 技能引用:manifest 的 `requires.capabilities` 加 `knowledge_search`;应用经 AppBridge `window.zhiyun.capability.invoke("knowledge_search", input)` 调用;对话与定时任务中智能体可作为工具直接调用。 ## 管理 API - `GET /api/developer/knowledge-bases`:我的知识库;`/platform` 为平台知识库目录。 - `POST /api/developer/knowledge-bases/{id}/documents`:添加文档(≤50,000 字,可选来源链接)。 - `POST /api/developer/knowledge-bases/{id}/submit|withdraw`:提审 / 撤回。 - `POST /api/developer/knowledge-bases/{id}/search`:指定库内检索测试。 - 配额:每人 20 个知识库,每库 100 篇文档。 --- # Capability API > 能力目录端点、字段说明与同名能力冲突规则。 ## 接口 - `GET /api/developer/capabilities`:全量能力目录(系统内置 + 已启用扩展)。 - `GET /api/developer/tools`:系统工具名清单。 - `GET /api/models`:已接入模型清单。 ## 字段说明 - scope:PLATFORM 平台级 / USER 用户级。 - availability:ALWAYS 常驻可用 / CONDITIONAL 依赖运行策略(如联网开关)。 - rateLimitPerMinute:每分钟调用上限,0 表示未单独限制。 - source:SYSTEM 系统内置 / EXTENSION 扩展提供。 - risk:扩展声明取 LOW / MEDIUM / HIGH / CRITICAL;平台系统能力可能标注 EXTERNAL,App 经 capability.invoke 调用 EXTERNAL 能力时返回 APPROVAL_REQUIRED 审批语义。 > 同名能力冲突规则:系统内置优先,其次取最早安装的扩展提供者。 --- # 权限模型 > SUPER_ADMIN / DEVELOPER / MEMBER 角色权限与 服务端逐请求判定原则。 ## 角色与权限 - SUPER_ADMIN:管理后台域全量权限(用户、模型、扩展、审核、审计等),使用独立管理员账号登录 /admin/login。 - DEVELOPER:PLATFORM_USE + DEVELOPER_ACCESS(开发者中心目录接口)。 - MEMBER:PLATFORM_USE(普通使用)。 - 权限按 subject / role / scope_type / scope_id 绑定,每个请求由服务端重新判定;扩展安装等管理操作需要 `EXTENSION_MANAGE`。 --- # 发布规范 > 版本状态机与服务端校验点。 ## 版本状态机 DRAFT(草稿)→ IN_REVIEW(审核中)→ APPROVED(可发布)→ PUBLISHED(已发布);REJECTED(被驳回)可修改后重新提审;审核中可主动撤回回到草稿。所有流转都有服务端审计。 ## 服务端校验点 - kind 必须是 Skill / Plugin / App / Bundle,否则拒绝。 - 能力 risk 必须在允许的分级内;inputSchema / outputSchema 必须是合法 JSON Schema。 - 技能依赖的能力必须已注册;SKILL.md 内容不能为空。 - runtime.url 必须 https 公网地址;manifest 声明的 secrets 必须与 secretRef 对应。 > 审核在管理后台「扩展审核」队列完成(/admin/reviews);驳回必须填写意见,会展示在开发者的版本历史里。 --- # 开发流程总览 > 三种产物(Skill / Plugin / App)通用全流程与 API 速查。 ## 全流程(三种产物通用) 1. 准备:平台账号 + DEVELOPER 角色(开发者中心 `/developer/login`);创建项目时只需填 ID 短码(2-40 位小写字母/数字/连字符,如 `rice-pest-guard`),平台自动拼装为 `cn.edu.yangtzeu.〈你的账号〉.skill|plugin|app.〈短码〉`,`cn.edu.yangtzeu.zhiyun.*` 为平台保留段。 2. 创建项目:开发者中心对应面板新建;App 的 appId 即清单里的 id,创建后不可改。 3. 本地开发 + 打包:按「技能开发 / Plugin 接入 / App SDK」的包结构准备文件并 zip(命令见「AI 提示词模板」各模板末尾)。 4. 上传草稿:Skill/Plugin 在项目工作台上传 zip;App 上传 app.zip(会覆盖当前草稿,版本号取包内清单)。 5. 提审 → 审核 → 发布:草稿 → IN_REVIEW → APPROVED → PUBLISHED;驳回改后可重新提审。 ## API 速查(可用脚本/让 AI 代跑) - 技能/插件(Bearer 开发者 JWT):`POST /api/developer/projects`(kind 取 `Skill / Plugin`,App 走 /apps)→ `POST /api/developer/projects/{id}/package`(multipart,字段名 file)→ `POST /api/developer/projects/{id}/versions/{vid}/submit` → 通过后 `POST .../versions/{vid}/publish`。 - 应用:`POST /api/developer/apps`(先建草稿)→ `POST /api/developer/apps/{appId}/package`(app.zip)→ `POST /api/developer/apps/{appId}/releases/{version}/submit` → `POST /api/admin/apps/{appId}/releases/{version}/review`(`{"approve":true}`,通过即上架)。 - 审核管理:`POST /api/admin/reviews/{vid}/approve` / `/reject`(管理员会话)。 - 目录验证:`GET /api/skills`(技能)、`GET /api/apps`(应用)、`GET /api/developer/capabilities`(能力)。 > App 的 category 只能取:科研分析 / 智慧种植 / 病虫害 / 农业气象 / 遥感与 GIS / 数据工具 / 文献研究 / 项目管理,其他值会被 400 拒绝;应用必须至少声明一项 AppBridge 权限。 --- # AI 提示词模板 > 可直接复制给任意 AI 的技能 / 插件 / 应用开发提示词模板,内置平台硬性校验规则。 ## 用法 把对应模板整段复制给任意 AI(豆包/ChatGPT/Claude 等),替换〈〉占位符后发送,AI 会产出符合平台包结构的全部文件;再按模板末尾的 zip 命令打包上传即可。模板内置了平台的硬性校验规则(命名空间、包限制、权限词、分类枚举),可显著减少提审被驳回的往返。 ## 三套模板 ### 技能(Skill)提示词模板 ```text 你是资深农业知识工程师。请为我开发一个可在"长大智耘"平台上架的技能(Skill), 只输出文件内容,不要解释。 【需求】 - 技能名称:〈技能名称,如"水稻病虫害诊治助手"〉 - 解决的问题:〈一两句话描述目标用户与场景〉 - 核心内容:〈希望技能教 Agent 掌握的知识/决策规则/话术,可分点〉 【产出要求】 1. 输出一个 Markdown 文件 SKILL.md(技能指令正文,非空,≤2MB)。 - 开头用一句话定位技能,随后给出结构化正文:决策规则用表格、 流程用有序列表、关键阈值/禁忌用加粗标注。 - 内容必须可执行、可判断,避免空泛描述;宁可窄而深,不要宽而浅。 2. 如需辅助资料,可额外输出 scripts/、references/、assets/、agents/ 目录下的文件 (包内条目 ≤200 个,单文件 ≤2MB,解压总量 ≤20MB,包体 ≤10MB)。 【打包与上架(我手动执行)】 - 我会在平台"开发者中心"创建 Skill 项目:只需填 ID 短码〈英文名〉(小写字母/数字/连字符,2-40 位), 平台自动拼装完整 id(cn.edu.yangtzeu.〈我的账号〉.skill.〈英文名〉), 然后把以上文件打包成 zip(SKILL.md 必须在包根或唯一顶层目录): zip -X skill.zip SKILL.md(有多目录时一并加入) - 技能如果需要调用平台已有能力,请只从这些已注册能力里选: get_current_time / web_search / search_agri_news(以 GET /api/developer/capabilities 实际返回为准), 平台会校验 requires.capabilities,未注册能力无法提审。 - 上传后进入 草稿 → 提交审核 → 管理员通过 → 发布,全平台用户可见。 ``` ### 插件(Plugin)提示词模板 ```text 你是资深后端工程师。请为我开发一个可在"长大智耘"平台上架的插件(Plugin), 只输出文件内容与必要的本地验证命令,不要解释。 【需求】 - 插件名称:〈插件名称,如"农区天气实况"〉 - 要提供的能力:〈1-3 个具体能力,每个一句话说明输入输出〉 【先选接入方式(按优先级)】 A. remote-http:我已有一个稳定的 https 公网 API。只产出 manifest.yaml,无代码。 - GET 请求的扁平标量入参会被展开为查询串,POST 走 JSON body; - API Key 认证用 auth.header + auth.secretRef,密钥值我在平台录入。 B. local-node / local-python:纯本地计算(推荐无外部依赖的能力)。 - 产出 manifest.yaml + capabilities/〈能力id〉.js|py; - 代码必须是纯函数:禁止网络请求、文件系统、数据库与第三方依赖 (local-node 不允许 package.json,只用运行时内置模块); - 输入是 JSON 对象,输出直接 return 一个可 JSON 序列化的对象。 【manifest.yaml 结构(B 方式示例)】 apiVersion: zhiyun/v1 kind: Plugin id: cn.edu.yangtzeu.〈我的账号〉.plugin.〈英文名〉 ← 平台创建项目只填短码〈英文名〉,前缀自动拼装 name: 〈插件名〉 version: 0.1.0 publisher: 〈发布者〉 description: 〈一句话〉 runtime: name: local-python # 或 local-node / remote-http / remote-mcp entry: capabilities/〈能力id〉.py permissions: capabilities: [] capabilities: - id: 〈能力id〉 name: 〈能力id〉 description: 〈一句话,Agent 靠它决定何时调用〉 type: TOOL risk: LOW inputSchema: '{"type":"object",...,"additionalProperties":false}' # JSON Schema 字符串 outputSchema: '{"type":"object"}' rateLimitPerMinute: 30 【产出要求】 1. manifest.yaml(根)+ capabilities/ 下每个能力一个入口文件; 2. 每个能力附一段本地自测:用示例输入真实跑一遍并给出预期输出, 数值计算类要自己验证数学正确性后再给我; 3. 打包(我手动执行):zip -X plugin.zip manifest.yaml capabilities/* (B 方式包内含 manifest.yaml 与入口文件;A 方式只需 manifest.yaml)。 【上架(我手动执行)】远端地址必须 https 公网;提审前平台会做沙箱测试与 SSRF 校验。 ``` ### 应用(App)提示词模板 ```text 你是资深前端工程师。请为我开发一个可在"长大智耘"平台上架的应用(App), 只输出文件内容,不要解释。 【需求】 - 应用名称:〈应用名称〉 - 功能描述:〈目标用户 + 核心交互 + 数据是否需要持久化〉 - 视觉:与平台一致的农业绿风格,移动端可用,中文文案。 【硬性运行环境约束(必须遵守,否则无法通过审核)】 1. 应用以 iframe 沙箱(opaque origin)运行:禁止 fetch/XHR/外链资源, 所有样式脚本内联或随包相对路径引用;不依赖 localStorage(不可用)。 2. 数据持久化只能用平台 SDK(需声明 storage 权限): window.zhiyun.storage.get({key}) / set({key, value}) / remove({key}),按用户+应用隔离; window.zhiyun.user.getCurrent() 可获取当前用户(需 profile 权限)。 3. SDK 由平台注入,宿主外预览时 window.zhiyun 可能不存在:所有调用必须 判空并给出本地降级(如内存/会话态兜底),不得报错白屏。 4. permissions 至少声明 1 项,只能取:profile / storage / agent.run / capability.invoke, 按最小权限原则只声明真正用到的。 5. app.json 的分类(category)只能取: 科研分析 / 智慧种植 / 病虫害 / 农业气象 / 遥感与 GIS / 数据工具 / 文献研究 / 项目管理。 【产出文件】 1. app.json: {"schemaVersion":1,"id":"cn.edu.yangtzeu.〈我的账号〉.app.〈英文名〉","name":"〈应用名〉", ← 平台创建项目只填短码〈英文名〉,前缀自动拼装为完整 id "version":"1.0.0","description":"〈一句话〉","entry":{"type":"web","path":"index.html"}, "permissions":["..."],"dependencies":{}} (id 必须与我创建应用时填的 appId 完全一致) 2. index.html(入口,≤60000 字符)+ 相对路径引用的 css/js 资源; 3. 如使用了 window.zhiyun.*,逐处标注注释说明权限依据与降级逻辑; 4. README.md:功能说明与手动验证步骤。 【打包与上架(我手动执行)】 zip -X app.zip app.json index.html css/* js/* README.md (包限制与技能包相同:≤10MB / ≤200 条目 / 单文件 ≤2MB;上传 app.zip 会覆盖当前草稿, 之后 提交审核 → 管理员通过 → 用户可在应用中心打开) ``` > 模板里的能力清单(get_current_time / web_search / search_agri_news)是当前平台已注册能力,新能力上架后会变化——以 GET /api/developer/capabilities 的实时返回为准。 --- # 示例项目 > 可直接使用的四类 Manifest 样例。 ## 可直接使用的 Manifest 样例 ### Plugin(remote-http) ```yaml apiVersion: zhiyun/v1 kind: Plugin id: cn.edu.yangtzeu.smartagri.weather name: 天气查询插件 version: 0.1.0 publisher: developer description: 查询指定城市当前天气 runtime: name: remote-http url: https://api.example.com/weather method: POST auth: header: X-Api-Key secretRef: API_KEY permissions: capabilities: [] secrets: - API_KEY capabilities: - id: weather_query name: weather_query description: 按城市名查询当前天气 type: TOOL risk: LOW inputSchema: '{"type":"object","properties":{"city":{"type":"string","description":"城市名"}},"required":["city"],"additionalProperties":false}' outputSchema: '{"type":"object"}' rateLimitPerMinute: 30 ``` ### Plugin(remote-mcp 骨架) ```yaml apiVersion: zhiyun/v1 kind: Plugin id: cn.edu.yangtzeu.smartagri.mcp.demo name: MCP 示例插件 version: 0.1.0 publisher: developer runtime: name: remote-mcp url: https://mcp.example.com/mcp permissions: capabilities: [] capabilities: [] ``` ### Skill ```yaml apiVersion: zhiyun/v1 kind: Skill id: cn.edu.yangtzeu.smartagri.fieldnote name: 田间记录助手 version: 0.1.0 publisher: developer requires: capabilities: - get_current_time ``` ### App(app.json) ```json { "schemaVersion": 1, "id": "cn.edu.yangtzeu.smartagri.note", "name": "农情速记", "version": "1.0.0", "description": "试验数据快速记录", "entry": { "type": "web", "path": "index.html" }, "permissions": ["profile", "storage"], "dependencies": {} } ```