空间内嵌应用:应用模板
Knodo 应用模板机制:把工作空间的「形态」沉淀为可复用的模板,AI 辅助开发,一键分发给团队
应用生态
Knodo 应用生态(App Ecosystem)让你把一个工作空间的「形态」 —— 包括侧边栏布局、自定义面板、业务视图 —— 沉淀成可复用的模板,然后一键分发给团队其他人。
比起从零搭建一个新空间,基于 App 模板创建的空间开箱即用:侧边栏已经按业务流程排好,自定义面板(比如"客户列表"、"销售漏斗")直接显示业务数据,团队成员打开即用。
核心概念
什么是 App(应用模板)
App = 工作空间的形态。它描述了:
- 侧边栏布局:显示/隐藏哪些内置面板(任务、知识、变更等),追加哪些自定义面板
- 面板组件:自定义面板的 UI 是什么样、放哪些数据
- 文案重命名:把「知识」改为「代码」、把「任务」改为「跟进」之类
- 元数据:名称、版本、图标、作者、分类
一个 App 可被多个工作空间同时绑定,每个空间独立拥有自己的数据,但 UI 形态完全一致。
App vs Plugin 的区别
Knodo 平台现有两个扩展机制,分工清晰:
| 维度 | Plugin(插件) | App(应用模板) |
|---|---|---|
| 解决什么 | AI 能做什么 | 空间长什么样 |
| 组成 | Agent 角色、Skill 技能、命令、Hook | 面板、侧边栏、布局 |
| 绑定关系 | 多对多(一个空间装多个插件) | 一对一(一个空间用一个 App) |
| 运行时 | AI 对话期间调用 | 打开空间就生效 |
两者独立运作:一个基于「销售 CRM」App 创建��空间,可以同时装 Javis 插件跟 AI 对话、装 Pagecraft 插件生成页面。
内置 App
平台预置两个 App 模板:
- 通用(general):默认布局——知识库 + 任务 + 对话三栏,大多数场景开箱即用。老工作空间自动绑定此 App
- 应用模板开发(app-dev):平台内 AI 辅助开发应用模板的专用模板。点击即可进入,一句话描述需求就能生成面板 → 实时预览 → 发布到应用模板库。详见应用模板开发章节
使用流程
1. 发现和使用
空间列表页右上角 → 「应用模板」按钮 打开管理弹窗。这里能看到:
- 内置 App(如「通用」)
- 组织内其他成员发布的 App(INTERNAL 可见性)
- 自己发布的 App(PRIVATE 可见性)
- 公开的 App(PUBLIC 可见性,跨组织可见)
点击任一 App 进入详情,可以看:
- 面板定义:这个 App 有哪些自定义面板
- 布局配置:隐藏了哪些内置面板、面板顺序
- 原始 Manifest:完整的
app.yaml内容
2. 基于 App 模板创建工作空间
在 「新建工作空间」 弹窗(AI 创建 / 从模板创建两种路径都支持),新增了 「应用模板」 区域。
- 不选 → 默认使用「通用」
- 选中某个 App → 新空间的侧边栏、面板会按该 App 的 manifest 渲染

3. 为现有空间切换 App
进入空间 → 设置 → 应用模板 Tab:
- 看到当前绑定的 App 信息
- 点 「切换模板」 展开选择器
- 确认后侧边栏立即按新 App 配置重新渲染
- 空间内容(知识库、任务、对话记录)不受影响,只是「外壳」变了

应用模板开发
为什么这么做
传统做法开发��个前端应用要:搭脚手架 → 选组件库 → 写代码 → 调样式 → 打包 → 部署。对非程序员用户,这条路基本走不通。
Knodo 的做法是把开发环境做成一个工作空间,让 AI 完成所有技术细节:
- 知识库(= 代码目录):AI 把源码写在这里
- AI 对话:你用自然语言提需求、改样式、加功能
- 预览面板:浏览器端编译 + 实时预览,所见即所得
- 一键发布:AI 自动打包上传
整个过程你只需要:想清楚要什么 + 看预览说满意还是不满意。
创建开发空间
新建工作空间 → 选择 「应用模板开发」 应用模板 → 完成创建。
进入后左栏是 预览 面板,默认展开;还能看到 代码 面板(其实是知识库,专门为此模板重命名)。

跟 AI 说需求
在对话里描述你要做什么,越具体越好:
/javis:app-developer 做一个电影收藏管理应用,要能新增电影(名字、年份、评分)、按年份筛选、按评分排序
AI 会:
- javis 插件内置了一个 app-developer 的 skill,他知道如何构建应用模板
- 根据需求推导 slug(例如
movies) - 写
app.yaml定义面板和布局 - 写
src/panels/movies.tsx实现 UI 逻辑;需要时再补src/libs/**或*.module.css - 保存文件
几秒后 预览 面板会自动编译、自动挂载你的组件。
预览模式
预览面板顶部有两个按钮,切换查看效果:
| 模式 | 切换方式 | 效果 |
|---|---|---|
| 开发 | 默认 | 不改变布局,面板清单里展开看每个面板的组件(内嵌预览) |
| 预览 | 点「预览」 | 完全切换为你的 App 布局,对话区也会隐藏,自动打开第一个面板 |

预览模式下右下角有 「返回开发」 悬浮球,双击 ESC 也能退出。即使 AI 写出了死循环代码,逃生球一样能点。点击「返回开发」后会自动回到预览面板。

迭代优化
看到预览后,可以继续跟 AI 说:
把电影卡片的背景改成渐变色
加一个「已看过」的筛选条件
把评分数字字体放大一点
AI 会 Read → Edit 现有文件。由于 AppPreview 监听了源码变化,保存后自动重新编译刷新。
样式
默认有两档方式:
- 基础模式:直接在 TSX 里写
className,配合 Tailwind utility class。大多数场景够用,也是兼容性最稳的方式 - 增强模式:在当前环境已启用时,使用
*.module.css做局部样式抽离,并可在 App 根容器上定义局部 CSS 变量
增强模式的边界:
- 只支持
src/panels/**、src/libs/**下的*.module.css - 不支持普通
.css - 不支持
:global、html、body、:root、.dark - App 根容器变量只保证作用于当前 App 的非 Portal 子树
发布
满意后点 预览 工具栏的 「发布」 按钮。会弹出确认对话框,点击确认后:
- 指令会自动发到对话框(你不需要手动打字)
- AI 执行
app-developerSkill 的pack-and-upload.sh脚本 - 脚本用
build-panels.mjs编译 TSX、校验 import / CSS 规则 → 打 ZIP → 直接调POST /api/v1/apps - 返回新 App ID
完成后:
- 此 App 出现在空间列表页 「应用模板」 管理弹窗里
- 任何成员创建工作空间时可以选择这个 App
- 你自己可以在设置里切换任意空间到此 App
外部开发 + 手动上传
如果你有现成的应用包 ZIP(含 app.yaml + panels/*.js,必要时带 sibling panels/*.css),在 应用模板管理弹窗 → 「上传应用」 上传即可。
参考示例:apps/app-plugins/customer-management/(源码结构 + 打包脚本)。
可见性与管理
可见性管理
| 可见性 | 谁能看到 | 典型用途 |
|---|---|---|
| 私有(PRIVATE) | 仅创建者 | 自用的个人工具、开发中未稳定的版本 |
| 组织内(INTERNAL) | 同组织成员 | 团队内部复用的标准应用 |
| 公开(PUBLIC) | 所有组织 | 平台级模板、合作伙伴开放的公共应用 |
上传后可在 应用模板管理 → 某个 App → 编辑信息 里修改可见性。
覆盖发布(迭代已有 App)
同一个 slug 的 App 再次发布时,系统会判断:
- 你是原创建者 → 弹出确认对话框,提示会覆盖当前版本,所有绑定此 App 的工作空间会立即使用新版。你点「覆盖」后完成更新
- 你不是原创建者 → 拒绝覆盖,必须修改
slug后重新发布(或联系原作者)
⚠️ 覆盖发布会立即影响所有绑定此 App 的工作空间 —— 如果跨团队共用,建议版本号同步升级,并提前告知相关成员
使用应用模板开发空间修改后再发布时,如果是同一个 slug,AI 会先发一次请求 → 后端返回 409 冲突 → AI 问你是否覆盖。你确认后 AI 再发一次带覆盖标识的请求,成功后告诉你「已覆盖更新」。
权限保护:只有原作者能覆盖。如果你在别人的空间里发布一个同 slug 的 App,会被后端拒绝(403),需要你改 slug 重试。
删除 App
在应用模板管理 → [⋯] → 删除 后:
- 如果当前没有空间使用此 App → 直接删除
- 如果有空间使用此 App → 弹出确认对话框,列出受影响的空间。确认后:
- App 被删除
- 这些空间的
appId自动降级为「通用」App - 空间内容完全保留(只是失去了自定义面板,回到默认布局)
技术规范
文件约定
AI 生成的文件结构(你能在「代码」面板里看到):
<workspace-root>/
├── app.yaml # App Manifest(必需)
├── package.json # npm 依赖声明(可选)
├── src/
│ ├── panels/
│ │ ├── <view-key-1>.tsx # 每个 view 对应一个 TSX 文件
│ │ ├── <view-key-1>.module.css # 局部样式(仅在当前环境已启用时)
│ │ └── <view-key-2>.tsx
│ └── libs/ # 共享组件 / hooks / utils(可选)
└── dist/ # 打包产物(脚本生成,无需手动编辑)
└── <slug>.zip严格命名约定
view key ⇄ entry 文件名 ⇄ 源码文件名 必须三者对齐:
app.yaml的views.<key>.entry = ./panels/<key>.js(发布后的路径)- 源码
src/panels/<key>.tsx - 如果启用了 CSS Modules,构建后可能还会生成
./panels/<key>.css作为样式 sidecar;这是产物文件,不是源码入口 - 已发布 App 会尝试加载同名 CSS sidecar;旧 App 没有
./panels/<key>.css时继续只加载 JS,不会白屏
违反约定会导致预览报"源文件不存在"。AI 会严格遵守这个约定。
app.yaml 约束
name: 客户管理
slug: crm
version: 1.0.0
description: CRM 客户关系管理
category: CRM
views:
customers:
title: 客户列表
type: component
entry: ./panels/customers.js
layout:
sidebar:
hide: [tasks, changes] # 隐藏的内置面板
rename:
files: 资料 # 把"知识"重命名为"资料"
panels:
- key: customers
title: 客户列表
icon: Users| 字段 | 说明 |
|---|---|
name | 必填 |
slug | 必填,小写字母 + 数字 + 连字符 |
version | 必填,x.y.z 格式 |
views | 必填,至少一个面板定义 |
layout.sidebar.hide | 可选,要隐藏的内置面板 ID 数组 |
layout.sidebar.rename | 可选,内置面板重命名映射(如 { files: 代码 }) |
发布后,这份 manifest + 编译好的面板资产(panels/<key>.js,必要时带 panels/<key>.css sibling CSS)会被平台注册到应用模板库,供组织内/外成员复用。运行时会尝试加载同名 CSS sidecar;旧 App 没有 CSS 文件时仍按原有 JS 面板加载。
TSX 文件约束
AI 生成的面板组件需要满足:
export default导出 React 组件- 组件接收
{ workspaceId: string }props - 可以 import
react(Hook 都能用) - 可以 import 下列平台能力(详见面板可用的平台能力):
@knodo/api:调用平台前端行为(发对话消息等)@knodo/ui:复用平台桥接组件(目前稳定开放:ChatInterface)- 可以直接
fetch任何/api/v1/...后端接口(same-origin 自动带凭证) - 不能 import 平台私有模块(
@/components/...、@/stores/...等)
- Tailwind 类名可用
- 在当前环境已启用时,可以 import
*.module.css并与className混用 - 普通
.css不可用;也不要写:global、html、body、:root、.dark
面板可用的平台能力
除了纯 React 组件能力,面板还可以调用平台暴露的三类能力做更复杂的事。
1. @knodo/api — 调用平台前端行为
用在「面板想让 AI 帮我做事」这类场景。这些能力不是后端 API(没有 HTTP endpoint),必须走 @knodo/api。
| 方法 | 作用 |
|---|---|
chat.send(text) | 把一段文本直接作为用户消息发送到当前激活的对话 Tab,AI 立即开始回复 |
chat.fill(text) | 把文本填进输入框(不自动发送),留给用户改完再点发送 |
示例:
import { chat } from '@knodo/api'
<button onClick={() => chat.send('帮我分析这条订单异常')}>
交给 AI 分析
</button>2. @knodo/ui — 复用平台组件
有些组件实现极复杂,自己写不划算。平台把它们以 @knodo/ui 形式对面板开放。
| 当前可用 | 说明 |
|---|---|
ChatInterface | 完整的 AI 对话窗口。包含消息列表、流式渲染、命令选择、文件上传、模型切换等。面板可以直接嵌入用 |
示例(把对话嵌进自己的面板):
import { ChatInterface } from '@knodo/ui'
export default function MyPanel({ workspaceId }) {
return (
<div className="flex h-full flex-col">
<header>...我的业务内容...</header>
<div className="flex-1">
<ChatInterface
workspaceId={workspaceId}
welcomeMessage="💡 可以问我任何关于这份数据的问题"
hideFileSelector
/>
</div>
</div>
)
}
@knodo/ui会随着平台迭代逐步增加新组件(看板、Markdown 查看器等)。
3. 直接 fetch 后端 API
面板运行在 same-origin,所有 /api/v1/... 接口都能用标准 fetch 调用,凭证自动携带:
fetch(`/api/v1/workspaces/${workspaceId}/tasks`, {
credentials: 'include',
}).then((r) => r.json())注意事项
- 面板跑在平台主 React 树里,不是 iframe。基础主题 token 会在非 Portal 子树中自动继承;高级场景可在启用后使用
*.module.css和 App 根容器 CSS 变量 @knodo/api和@knodo/ui的类型提示需要编辑器支持,AI 直接写就行- 所有能力都有版本承诺:
@knodo/api和@knodo/ui的破坏性变更会通过 Skill 文档和发版说明告知 - 不要尝试绕过去 import
@/...,会编译失败 - 不要指望 App 根容器变量自动影响
Dialog、Popover、Tooltip等 Portal 浮层
隐藏 / 重命名内置面板
默认平台空间有 7 个内置面板:
| ID | 默认文案 | 说明 |
|---|---|---|
tasks | 任务 | 任务管理 |
files / knowledge | 知识 | 知识库文件树(两个 ID 互为别名) |
changes | 变更 | Git 变更视图 |
views | 分析 | 数据视图 |
automation | 自动化 | 定时任务 |
guideline | 指引 | 工作指引 |
chat | —— | 右侧对话区 |
你可以告诉 AI:「不要任务和变更面板」→ AI 会在 manifest 加 hide: [tasks, changes]。也可以重命名:「把知识改名为资料」→ AI 加 rename: { files: 资料 }。完全沉浸式应用(只留一个面板)也可以:「只保留我的面板,其他全部隐藏,包括对话区」。

适用场景
适合做纯前端的业务工具:
- 数据看板(内嵌 echarts / recharts 后可视化)
- 清单工具(待办、笔记、收藏)
- 表单类应用
- 轻量 CRM / 跟进工具
- 文档展示 / 知识库门户
目前不适合做的:
- 需要重度 UI 组件库的应用(暂不共享 shadcn/ui,但可以用 Tailwind + 原生 HTML)
- 需要服务端逻辑的应用(只支持纯前端,没有专属后端接口注册机制)
- 强依赖全局 CSS 覆盖或复杂 Portal 主题联动的应用(当前只保证局部 CSS Modules 和非 Portal 子树变量)
这些会在后续迭代中放开。
常见问题
Q: 预览报"未找到面板组件"?
A: 大概率是 view key 和源码文件名不对齐。让 AI 检查 app.yaml 里 views.<key>.entry 是否等于 ./panels/<key>.js,对应源码是否在 src/panels/<key>.tsx。
Q: 预览报"编译失败"?
A: AppPreview 顶部会显示编译错误,点击具体 view 的「失败」badge 看详细错误行。把错误原文发给 AI,让 AI 修。
Q: 面板里能发消息给对话区吗?
A: 能。import { chat } from '@knodo/api'; chat.send('你的消息') 就会把消息发到当前激活的对话 Tab。如果你只想预填入输入框让用户确认,用 chat.fill('...')。
Q: 面板里能调用平台后端 API 吗?
A: 可以,直接 fetch('/api/v1/...', { credentials: 'include' }),凭证会自动带,后端按当前登录用户鉴权。
Q: 发布失败 409 但我是作者?
A: 重启 backend 让 DTO 字段生效(overwrite 字段是新加的)。正常情况下会弹确认对话框让你点「覆盖」。
Q: 预览模式下页面崩了,怎么回去?
A: 右下角逃生悬浮球永远可点,或者双击 ESC。
Q: 发布的 App 别人看不到?
A: 检查可见性:默认是 PRIVATE(只有你自己)。在应用模板管理里编辑可见性为 INTERNAL(组织内)或 PUBLIC(跨组织)。
相关文档
- 独立应用认证对接 - M2M API 密钥接入指南
- 站点发布 - 独立站点发布与授权
- API Key 使用指南(模型调用) - AI 模型渠道 API Key
- 源码位置:
apps/plugins/javis/skills/app-developer/(Skill 定义)