@kanyun-ai-infra/band-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/examples/aitutor-tool/band/views/release/package.json +1 -1
- package/bundled/examples/aitutor-tool/band/views/tool-preview/package.json +1 -1
- package/bundled/examples/analysis/band/views/intake/package.json +1 -1
- package/bundled/examples/compliance/band/views/compliance/package.json +1 -1
- package/bundled/examples/content-review/band/views/checklist/package.json +1 -1
- package/bundled/examples/rush-site/band/views/rush-db/package.json +1 -1
- package/bundled/examples/rush-site/band/views/rush-deploy/package.json +1 -1
- package/bundled/examples/video/band/views/timeline/package.json +1 -1
- package/bundled/kernel/fixture.js +1 -1
- package/bundled/kernel/index.js +1 -1
- package/bundled/official/activity/package.json +4 -4
- package/bundled/official/approval/package.json +4 -4
- package/bundled/official/artifacts/package.json +4 -4
- package/bundled/official/chat/package.json +4 -4
- package/bundled/official/chunks/chunk-DIL5YSVK.js +1 -0
- package/bundled/official/comment/dist/index.js +2 -2
- package/bundled/official/comment/package.json +4 -4
- package/bundled/official/header/package.json +4 -4
- package/bundled/official/home/package.json +4 -4
- package/bundled/official/layouts/package.json +4 -4
- package/bundled/official/library/dist/index.js +1 -1
- package/bundled/official/library/package.json +4 -4
- package/bundled/official/members/dist/index.js +1 -1
- package/bundled/official/members/package.json +4 -4
- package/bundled/official/memory/dist/index.js +2 -2
- package/bundled/official/memory/package.json +4 -4
- package/bundled/official/native/package.json +2 -2
- package/bundled/official/params-form/package.json +4 -4
- package/bundled/official/plugins/package.json +4 -4
- package/bundled/official/project/dist/index.js +1 -1
- package/bundled/official/project/package.json +4 -4
- package/bundled/official/queue/package.json +4 -4
- package/bundled/official/settings/dist/index.js +1 -1
- package/bundled/official/settings/package.json +4 -4
- package/bundled/official/settings/plugin.yaml +7 -0
- package/bundled/official/shell/dist/index.js +1 -1
- package/bundled/official/shell/package.json +4 -4
- package/bundled/official/stages/package.json +4 -4
- package/bundled/official/threads/package.json +4 -4
- package/bundled/official/turn-bar/package.json +4 -4
- package/bundled/official/turn-trace/package.json +4 -4
- package/bundled/official/version-switch/dist/index.js +1 -1
- package/bundled/official/version-switch/package.json +4 -4
- package/bundled/official/viewer-entity/package.json +2 -2
- package/bundled/official/viewer-external/package.json +2 -2
- package/bundled/official/viewer-image/package.json +2 -2
- package/bundled/official/viewer-media/index.js +2 -2
- package/bundled/official/viewer-media/package.json +2 -2
- package/bundled/official/viewer-storyboard/index.js +2 -2
- package/bundled/official/viewer-storyboard/package.json +2 -2
- package/bundled/official/viewer-text/dist/index.js +2 -2
- package/bundled/official/viewer-text/package.json +4 -4
- package/bundled/official/viewer-tool/package.json +2 -2
- package/bundled/official/viewer-web/package.json +2 -2
- package/bundled/official/viewer-web-app/package.json +2 -2
- package/bundled/official/workshops/dist/index.js +2 -2
- package/bundled/official/workshops/package.json +4 -4
- package/bundled/official/workshops/plugin.yaml +2 -2
- package/bundled/skills/band-plugin/SKILL.md +20 -273
- package/bundled/skills/band-plugin/references/code.md +58 -0
- package/bundled/skills/band-plugin/references/dev.md +37 -0
- package/bundled/skills/band-plugin/references/execution.md +26 -0
- package/bundled/skills/band-plugin/references/manifest.md +65 -0
- package/bundled/skills/band-plugin/references/placement.md +34 -0
- package/bundled/skills/band-plugin/references/reuse.md +38 -0
- package/bundled/skills/band-plugin/references/rules.md +13 -0
- package/bundled/skills/band-plugin/references/shape.md +17 -0
- package/bundled/skills/band-plugin/references/testing-publish.md +35 -0
- package/bundled/skills/band-plugin/references/viewer-comments.md +25 -0
- package/bundled/skills/band-plugin/templates/dev/fixture.ts +15 -0
- package/bundled/skills/band-plugin/templates/dev/resources.ts +6 -0
- package/bundled/skills/band-plugin/templates/panel/index.ts +24 -0
- package/bundled/skills/band-plugin/templates/panel/package.json +12 -0
- package/bundled/skills/band-plugin/templates/panel/plugin.yaml +5 -0
- package/bundled/skills/band-plugin/templates/toolbar-dock/plugin.yaml +11 -0
- package/dev-host/Inspector.tsx +28 -10
- package/dev-host/app.tsx +11 -6
- package/dev-host/host.css +11 -0
- package/dev-host/main.tsx +5 -0
- package/dist/bin.js +3 -3
- package/dist/build-plugin.d.ts +1 -1
- package/dist/build-plugin.js +1 -1
- package/dist/{chunk-TN7Z3OF6.js → chunk-LGYGWMSY.js} +19 -17
- package/dist/{chunk-VVJNG5GV.js → chunk-Q2XJXNVH.js} +22 -15
- package/dist/{chunk-RAD6MMSL.js → chunk-XPLYTHNX.js} +1 -1
- package/dist/{dev-server-RAZQ32W7.js → dev-server-Q7NTJ3QD.js} +116 -11
- package/dist/fixture.d.ts +11 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +2 -2
- package/dist/{workshop-repo-CO6YMDee.d.ts → workshop-repo-DqoVdcGu.d.ts} +10 -10
- package/package.json +10 -7
- package/src/dev-managers.ts +16 -0
- package/src/inspector-plugins.ts +18 -0
- package/bundled/official/chunks/chunk-JI6ZNGOE.js +0 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# 先找现成的、Agent 怎么选
|
|
2
|
+
|
|
3
|
+
> 什么时候读:动手写代码之前,判断要不要写新插件、该用哪个官方插件或哪一档 Agent 时。
|
|
4
|
+
|
|
5
|
+
顺序:**先用官方插件,再找别的工坊共享的插件,都不合适才写新的**。官方插件在 `workshop.yaml` 的 `views` 里按 id 选用,不用写代码:查看器写在 `artifactTypes.<类型>.viewer`,面板写在 `panels` 的区里,要换掉某个官方面板写 `replace`。
|
|
6
|
+
|
|
7
|
+
| 种类 | id(`views` 里写的) | 管什么 |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| 查看器 | `web` | 网页类产物:预览、元素标注、实时预览、直接编辑(`band-viewer-web`) |
|
|
10
|
+
| 查看器 | `text` | Markdown 与纯文本,按段落、选中文字提意见(`band-viewer-text`) |
|
|
11
|
+
| 查看器 | `image` | 图片与候选网格,框选提意见,版本并排对比(`band-viewer-image`) |
|
|
12
|
+
| 查看器 | `media` | 音频与视频,按时间点提意见(`band-viewer-media`) |
|
|
13
|
+
| 查看器 | `shots` | 分镜的镜头表:逐镜看静帧、时长、画面说明与旁白,和上一版按镜头 id 对比(`band-viewer-storyboard`) |
|
|
14
|
+
| 查看器 | `web-app` | Web 应用走查:内嵌打开加了走查 SDK 的真实页面,按设备尺寸看、点元素提意见(`band-viewer-web-app`) |
|
|
15
|
+
| 查看器 | `tool-pack` | 教具包:直接体验(投屏、平板、手机),调试指令(换示例、按指令集生成参数表单、看状态与事件记录),意见挂画面元素或某条指令(`band-viewer-tool`) |
|
|
16
|
+
| 查看器 | `entity` | 实体集合(角色表这类结构化条目),按条目提意见(`band-viewer-entity`) |
|
|
17
|
+
| 查看器 | `external` | 外部文档的快照,按文档块提意见(`band-viewer-external`) |
|
|
18
|
+
| 查看器 | `material-text` | 素材的某个版本当文档看(Markdown、纯文本、网页源码),只读、不带阶段来源(`band-viewer-text`) |
|
|
19
|
+
| 查看器 | `material-image` | 素材的某个版本当图片看,只读、不带阶段来源(`band-viewer-image`) |
|
|
20
|
+
| 查看器 | `material-media` | 素材的某个版本当音频/视频看,只读、不带阶段来源(`band-viewer-media`) |
|
|
21
|
+
| 面板 | `stages` | 阶段列表与进度,`{ stages: { compact: true } }` 收成流程条(`band-stages`) |
|
|
22
|
+
| 面板 | `artifacts` | 产物列表,点一个切换主区(`band-artifacts`) |
|
|
23
|
+
| 面板 | `threads` | 意见栏(`band-threads`) |
|
|
24
|
+
| 面板 | `chat` | 和 Agent 的对话流(`band-chat`) |
|
|
25
|
+
| 面板 | `activity` | 项目动态(`band-activity`) |
|
|
26
|
+
| 面板 | `turn-trace` | 回合轨迹:一回合的步骤、流水、在做什么与用时(`band-turn-trace`) |
|
|
27
|
+
| 面板 | `members` | 成员与角色(`band-members`) |
|
|
28
|
+
| 面板 | `params-form` | 阶段参数表单(`band-params-form`) |
|
|
29
|
+
|
|
30
|
+
完整目录(说明、关键词、在用的工坊数)在 Band 的 `GET /api/plugins`,每个插件的详情(README、版本、对外面、资源权限、谁在用)在 `GET /api/plugins/<作用域>/<名>`,人看插件页(`/plugins`)。别的工坊共享的插件在 `views.plugins` 里钉精确版本(`'@rush-site/rush-db@1.2.0'`)或写 `^` 兼容区间(`'@rush-site/rush-db@^1.2.0'`,解析成区间内最大的可用版本)引用,发布工坊时由服务端从插件登记处解析;`band check` 配了登记处才核对,没配逐条标「未校验」;`band dev` 不装载,只在页面上列出来。写了新插件、别的工坊也用得上时,去掉 `package.json` 的 `"private": true` 就是共享。
|
|
31
|
+
|
|
32
|
+
Agent 写在工坊级(`workshop.yaml` 顶层的 `agent`),作所有 agent 阶段的缺省;某个阶段确实要另一个 Agent 时,在那个阶段上写 `agent` 覆盖。按这个顺序选:
|
|
33
|
+
|
|
34
|
+
1. 先用 Rondo(缺省,不用写)。
|
|
35
|
+
2. 不够时扩展 Rondo:在 `band/agent/` 写工坊说明(`instructions.md`,按阶段写 `stages/<阶段>.md`);项目记忆由 Agent 自己积累;要特殊系统环境时选 Band 维护的环境档 `runtime`,没有合适的档先向 Band 申请。
|
|
36
|
+
3. 还不够,比如要 MCP、自己的模型服务或密钥,或者申请不到合适的环境档,才写 `agenthub/agents/<名字>/` 定制 Agent,在工坊级 `agent` 写它的名字。
|
|
37
|
+
|
|
38
|
+
按阶段的差异优先写进 `stages/<阶段>.md`;只有某个阶段确实要另一套插件、环境或提示词时才给它单独写 `agent`。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# 规矩
|
|
2
|
+
|
|
3
|
+
> 什么时候读:写完代码自查,或不确定某个写法能不能做(异步、样式、凭据、错误边界)时。
|
|
4
|
+
|
|
5
|
+
- **不碰协作状态**:评论、批准、队列、回合、版本只有锁定插件能改。工坊插件要提意见就 `openAt`,要批准就 `gate.open`。
|
|
6
|
+
- **异步要防乱序**:换版本、切环境时旧请求的结果可能晚到。每次加载记一个序号,结果回来时对不上就丢掉;读不到新数据时清空界面,不留旧数据(尤其是带「删除」按钮的表格)。
|
|
7
|
+
- **读不到不抛错**:版本里可能没有你要的文件、JSON 可能坏了。界面显示「这个版本没有……」,锚点解析返回 null。
|
|
8
|
+
- **路径参数要编码**:`ctx.resources.fetch` 的 path 里拼进去的 id 用 `encodeURIComponent`。
|
|
9
|
+
- **选人/选产物、标签、列表筛选、回执用现成组件**:`@kanyun-ai-infra/band-plugin-react` 导出 `Combobox`(可搜索单选/多选,受控 `items`/`value`/`onChange`,`label` 必写)、`TagInput`(字符串数组,回车或逗号确认、粘贴拆开、重复提示)、`FilterMenu` + `filterRows`(按几个单值维度筛,带计数)、`toast()`(一次性回执,只调不挂 `ToastHost`;失败用 `kind: "bad"` 带「重试」)。不要手写下拉搜索、标签输入、临时提示条。设置与表单里的保存反馈不弹 toast。详见用户文档「用 React 写插件」与 Band Design 站「组件」。
|
|
10
|
+
- **样式只用 Band Design token**:页面提供 `--panel`、`--ink`、`--muted`、`--accent`、`--r-lg` 等 CSS 变量,插件里不写死颜色,类名带插件名前缀。琥珀色(`--warn*`)只给部署方案装的插件(锁定插件、应用级页面)用,工坊插件不用。
|
|
11
|
+
- **工坊页面跟工坊最新发布走,项目页跟项目钉住的版本走**:同一工坊里两者可能是不同版本的插件代码。页面里不要假设项目页的面板、服务是同一版;页面只读本工坊的应用数据(`ctx.app.data` 已固定在本工坊,没有 `write`)。路由只写 `/w/:workshop/x/<页面>`,不写 `aliases`、`opens`。
|
|
12
|
+
- **不放凭据**:接口身份由 Band 代理注入,插件代码和仓库里都不出现 token、连接串。
|
|
13
|
+
- **渲染出错只坏自己那一块**:用 React 就用 `@kanyun-ai-infra/band-plugin-react` 的 `reactMount` 挂,它给每个挂载面包了错误边界,渲染期抛错显示插件名、原因和「重试」。自己 `createRoot` 或用别的框架的,要自己包错误边界;不包的话那一块只剩空白,没有说明也没有重试,宿主管不到。挂载函数同步抛错由宿主画错误卡。
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# 先定形态与 band new plugin
|
|
2
|
+
|
|
3
|
+
> 什么时候读:已经决定要写新插件,要选模板、选往哪个插槽贡献时。
|
|
4
|
+
|
|
5
|
+
| 想做 | 模板 | 往这个插槽贡献 |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| 页面四周的一块面板(分镜墙、时间轴) | `panel` | `@kanyun-ai-infra/band-project/panels`,写 `title` |
|
|
8
|
+
| 某种产物的显示方式 | `viewer` | `@kanyun-ai-infra/band-project/viewers`,写 `title` |
|
|
9
|
+
| 某个阶段的专属界面(发布进度) | `stage-view` | `@kanyun-ai-infra/band-project/stage-views`,写 `stage` |
|
|
10
|
+
| 查看器工具栏上的按钮 + 停靠位(数据库、环境变量) | 用 `panel` 起步改 | `@kanyun-ai-infra/band-viewer-web/toolbar`(写 `label`、`dock`)+ `@kanyun-ai-infra/band-project/docks`(写 `title`) |
|
|
11
|
+
| 项目之外的整页(看板、报表、素材总览) | 用 `panel` 起步改 | `@kanyun-ai-infra/band-shell/pages`,写 `route: /w/:workshop/x/<页面>` 与 `title`;`peerDependencies` 加 `@kanyun-ai-infra/band-shell`(见用户文档「给工坊加页面」) |
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
band new plugin <名> --template panel|viewer|stage-view [--stage <阶段>] [--title <标题>]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
它生成 `band/views/<名>/package.json`、`plugin.yaml` 与 `index.ts`,并把 `./views/<名>` 加进 `workshop.yaml` 的 `views.plugins`。插件名用小写 kebab-case,不能和平台插件重名(comment、approval、threads、stages……)。
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# 提交前与发布
|
|
2
|
+
|
|
3
|
+
> 什么时候读:提交前自检、写插件测试,或要 `band publish` / `band preview` 时。
|
|
4
|
+
|
|
5
|
+
- `band check`:校验 `workshop.yaml`、每个插件的 `package.json` 与 `plugin.yaml`,再拼一遍装配(插槽在不在、字段对不对、声明者写没写进 `peerDependencies`)。
|
|
6
|
+
- 在 `band dev` 里走一遍:换版本、联动选中、提意见、资源读写(看「夹具」栏的审计)。
|
|
7
|
+
- 插件逻辑能抽成纯函数的(解析文件、时间点落在哪个镜头),给它写单测。
|
|
8
|
+
- 要测挂载后的行为,用 `@kanyun-ai-infra/band-kernel/testing` 的测试台,不用自己拼内核。它要从 `node_modules` 装官方插件(外壳、项目页),这些不发 npm,所以**只在 Band 仓库里能用**;工坊仓库里挂载后的行为在 `band dev` 里走。Band 仓库里的写法:
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
// @vitest-environment jsdom
|
|
12
|
+
import { createTestbed, loadPluginPackage } from "@kanyun-ai-infra/band-kernel/testing";
|
|
13
|
+
const bed = await createTestbed({
|
|
14
|
+
plugins: [
|
|
15
|
+
// 插槽的声明者要一起装,和真实宿主一样
|
|
16
|
+
await loadPluginPackage("@kanyun-ai-infra/band-shell", import.meta.url),
|
|
17
|
+
await loadPluginPackage("@kanyun-ai-infra/band-project", import.meta.url),
|
|
18
|
+
{ packageJson, manifest, module: plugin }, // 被测插件
|
|
19
|
+
],
|
|
20
|
+
data: fixture,
|
|
21
|
+
});
|
|
22
|
+
const root = bed.mount("@kanyun-ai-infra/band-project/panels", {
|
|
23
|
+
key: "@<工坊>/checklist/main", // 插件全名 / 贡献 id
|
|
24
|
+
owner: { projectId: fixture.projectId },
|
|
25
|
+
});
|
|
26
|
+
await bed.settle();
|
|
27
|
+
// 断言 root 的 DOM、bed.requests(开线程等发给锁定插件的请求)、bed.ctx("@<工坊>/checklist").selection.get()
|
|
28
|
+
bed.dispose();
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 发布工坊
|
|
32
|
+
|
|
33
|
+
`band publish <工坊仓库目录> --url <Band 服务地址> --workshop <id>` 先校验并要求工作区干净,用作者的 git 凭据推送远端同名分支(须与工坊发布分支一致),再用 `BAND_TOKEN` 的 Bearer 身份只调一次 POST releases,不调用工坊 GET。`--workshop` 必填,id 从工坊页地址 `/w/<id>` 获取。可 `--no-push` 跳过推送。不要将 token 写进工坊仓库或命令文本;真实服务发布依赖平台 token 功能,缺少鉴权时继续用页面。构建命令与带依赖预设在生产隔离端口未装配前仍关闭。
|
|
34
|
+
|
|
35
|
+
`band preview [分支] --workshop <id> [--project <项目 id>]`:把已 push 的分支建成预览快照(只读工坊仓库、不发新版本),带 `--project` 时打印 `?preview=` 的项目链接,只有工坊管理员能打开;token 要 `workshops:preview` scope。预览页的写入会落到打开的那个项目(试用项目就落在试用项目里)。
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 查看器接评论
|
|
2
|
+
|
|
3
|
+
> 什么时候读:做的是查看器、要让用户在内容上提意见(意见编号、锚点宿主、标注模式)时。
|
|
4
|
+
|
|
5
|
+
查看器回答「意见在哪」,意见编号、评论框、孤儿列表、标注模式的开关都归锁定的评论插件。查看器里不画意见编号,也不自己画评论框。完整例子见用户文档「自定义查看器接评论」,示例工坊 `aitutor-tool` 的 `band/views/tool-preview` 是完整的工坊查看器。
|
|
6
|
+
|
|
7
|
+
1. 提意见:把点的地方 `ctx.anchors.make(...)` 成锚点,`ctx.threads.openAt(anchor)`。能用内置类型就用内置类型(条目、卡片用 `entity`,视频镜头用 `shot`):自己注册的 `plugin:*` 类型现在评论框不贴着内容弹,只贴在按钮下。
|
|
8
|
+
2. 挂载时登记锚点宿主,评论插件按它画意见编号:
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
const off = ctx.anchors.host({
|
|
12
|
+
kinds: ["entity"], // 内置类型名;自己注册的写 register 的返回值
|
|
13
|
+
locate, // (anchor) => AnchorPlace,必须同步
|
|
14
|
+
reveal, // async (anchor) => boolean,用 band-plugin-react/scroll 的 scrollIntoPanel 滚到它;做不到返回 false
|
|
15
|
+
onLayout(fn) { // 内容重画、换文件、图片撑高时调 fn(页面滚动、挂载点尺寸评论插件自己跟)
|
|
16
|
+
listeners.add(fn);
|
|
17
|
+
return () => listeners.delete(fn);
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`locate` 返回 `{ at: "rects", rects: [{ x, y, width, height }], status? }`(相对挂载点,文字跨行多个矩形,宽高为 0 是一个点)、`{ at: "track", x, y, w? }`(音视频时间轴)、`{ at: "elsewhere" }`(这一版里有、不在视口)、`{ at: "pending" }`(布局没好,等 `onLayout`)或 `{ at: "none" }`(孤儿)。`status` 是跨版本结果:不写是原位,`"changed"` 内容改过,`"moved"` 挪了位置。要读文件才判得出的先异步算好,`locate` 里只取结果。
|
|
23
|
+
3. 点击本身有含义的内容(图片、网页、iframe):宿主写 `annotate: true`(评论插件因此接 C 进、Esc 出),`ctx.anchors.annotating.subscribe` 跟着开关,只在模式开着时把点击变成锚点。文字、清单类查看器可以不写,不开模式也能提意见。
|
|
24
|
+
4. Esc 一次只关一样,先后是评论框 > 标注模式 > 浮层。查看器自己也接 Esc 时,先看 `e.defaultPrevented`,已被处理过的不再处理,处理了就 `preventDefault`。
|
|
25
|
+
5. 可选:音视频给 `candidates()` 报锚点小标,视觉类给 `thumbnail(anchor)` 附截图。
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// band/dev/fixture.ts —— band dev 必须有;形状以 @kanyun-ai-infra/band-cli/fixture 的 FixtureData 为准。
|
|
2
|
+
import type { FixtureData } from "@kanyun-ai-infra/band-cli/fixture";
|
|
3
|
+
|
|
4
|
+
export const fixture: FixtureData = {
|
|
5
|
+
projectId: "prj_demo",
|
|
6
|
+
runId: "run_demo_1",
|
|
7
|
+
versions: [
|
|
8
|
+
/* Version;打开时看第一个版本所在的产物 */
|
|
9
|
+
],
|
|
10
|
+
artifacts: [{ id: "art_storyboard", name: "分镜", artifactType: "storyboard" }],
|
|
11
|
+
files: {
|
|
12
|
+
/* "<versionId>": { "storyboard.json": "{...}" } */
|
|
13
|
+
},
|
|
14
|
+
stages: [{ stage: "deploy", status: "ready" }],
|
|
15
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ProjectCtx, definePlugin } from "@kanyun-ai-infra/band-plugin-sdk";
|
|
2
|
+
|
|
3
|
+
// 面板:显示当前版本与共享选中。plugin.yaml 里的贡献 id(main)就是 surfaces 的键。
|
|
4
|
+
export default definePlugin({
|
|
5
|
+
surfaces: {
|
|
6
|
+
main(ctx: ProjectCtx, mount: unknown) {
|
|
7
|
+
const root = mount as HTMLElement;
|
|
8
|
+
const text = root.ownerDocument.createElement("p");
|
|
9
|
+
root.append(text);
|
|
10
|
+
const draw = () => {
|
|
11
|
+
const v = ctx.version.current();
|
|
12
|
+
const sel = ctx.selection.get();
|
|
13
|
+
text.textContent = `版本 ${v?.id ?? "(无)"};选中 ${sel ? JSON.stringify(sel) : "(无)"}`;
|
|
14
|
+
};
|
|
15
|
+
const offVersion = ctx.version.subscribe(draw);
|
|
16
|
+
const offSelection = ctx.selection.subscribe(draw);
|
|
17
|
+
draw();
|
|
18
|
+
return () => {
|
|
19
|
+
offVersion();
|
|
20
|
+
offSelection();
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@my-workshop/example",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "一句话说明插件做什么(显示在插件目录里)",
|
|
6
|
+
"keywords": ["示例"],
|
|
7
|
+
"type": "module",
|
|
8
|
+
"peerDependencies": {
|
|
9
|
+
"@kanyun-ai-infra/band-plugin-sdk": "^2.0.0",
|
|
10
|
+
"@kanyun-ai-infra/band-project": "*"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# 查看器工具栏上的一个按钮 + 一个停靠位。peerDependencies 要加 band-viewer-web(optional)与 band-project。
|
|
2
|
+
entry: ./index.ts
|
|
3
|
+
contributes:
|
|
4
|
+
- slot: "@kanyun-ai-infra/band-viewer-web/toolbar"
|
|
5
|
+
id: open-db
|
|
6
|
+
optional: true # 工坊没用网页查看器时静默不生效
|
|
7
|
+
label: 数据库
|
|
8
|
+
dock: db # 点了打开本插件的停靠位 db
|
|
9
|
+
- slot: "@kanyun-ai-infra/band-project/docks"
|
|
10
|
+
id: db
|
|
11
|
+
title: 数据库
|
package/dev-host/Inspector.tsx
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/** 「夹具」栏:插件调了什么一眼看清。数据都来自夹具 transport 与运行时,不经插件。 */
|
|
2
2
|
import type { BandEvent } from "@kanyun-ai-infra/band-contracts";
|
|
3
3
|
import type { FixtureTransport } from "@kanyun-ai-infra/band-kernel/fixture";
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
AssembledPlugin,
|
|
6
|
+
AssemblyView,
|
|
7
|
+
ProjectCtx,
|
|
8
|
+
Selection,
|
|
9
|
+
} from "@kanyun-ai-infra/band-plugin-sdk";
|
|
5
10
|
import { useEffect, useReducer, useState } from "react";
|
|
11
|
+
import { splitInspectorPlugins } from "../src/inspector-plugins.ts";
|
|
6
12
|
|
|
7
13
|
export function Inspector({
|
|
8
14
|
ctx,
|
|
@@ -38,6 +44,7 @@ export function Inspector({
|
|
|
38
44
|
// 运行时的诊断(插件激活、挂载失败)有新的就重画
|
|
39
45
|
useEffect(() => ctx.app.subscribeDiagnostics(refresh), [ctx]);
|
|
40
46
|
const threads = transport.threads();
|
|
47
|
+
const plugins = splitInspectorPlugins(view.plugins);
|
|
41
48
|
// 同一个挂载面每次重挂失败都会再记一条:按内容去重
|
|
42
49
|
const failures = [
|
|
43
50
|
...new Map(
|
|
@@ -65,15 +72,12 @@ export function Inspector({
|
|
|
65
72
|
)}
|
|
66
73
|
<section>
|
|
67
74
|
<h2>插件</h2>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
</li>
|
|
75
|
-
))}
|
|
76
|
-
</ul>
|
|
75
|
+
{/* 作者自己的插件在上;三十来个官方插件默认折起,免得把选中、线程、审计挤出首屏 */}
|
|
76
|
+
<PluginList plugins={plugins.own} view={view} />
|
|
77
|
+
<details className="dev-inspector-official">
|
|
78
|
+
<summary>官方插件 {plugins.official.length} 个</summary>
|
|
79
|
+
<PluginList plugins={plugins.official} view={view} />
|
|
80
|
+
</details>
|
|
77
81
|
</section>
|
|
78
82
|
{stageViews.length > 0 && (
|
|
79
83
|
<section>
|
|
@@ -138,3 +142,17 @@ export function Inspector({
|
|
|
138
142
|
</aside>
|
|
139
143
|
);
|
|
140
144
|
}
|
|
145
|
+
|
|
146
|
+
function PluginList({ plugins, view }: { plugins: AssembledPlugin[]; view: AssemblyView }) {
|
|
147
|
+
return (
|
|
148
|
+
<ul>
|
|
149
|
+
{plugins.map((p) => (
|
|
150
|
+
<li key={p.name}>
|
|
151
|
+
<code>{p.name}</code>
|
|
152
|
+
{p.roles.length > 0 ? `(锁定:${p.roles.join("、")})` : ""}
|
|
153
|
+
{p.name in view.failed ? " · 没装上" : ""}
|
|
154
|
+
</li>
|
|
155
|
+
))}
|
|
156
|
+
</ul>
|
|
157
|
+
);
|
|
158
|
+
}
|
package/dev-host/app.tsx
CHANGED
|
@@ -34,6 +34,8 @@ import "./host.css";
|
|
|
34
34
|
import * as dev from "virtual:band-dev";
|
|
35
35
|
import { useEffect, useRef, useState } from "react";
|
|
36
36
|
import { createRoot } from "react-dom/client";
|
|
37
|
+
import { devManagers } from "../src/dev-managers.ts";
|
|
38
|
+
import { DEV_HOST_PLUGIN } from "../src/inspector-plugins.ts";
|
|
37
39
|
import { loadPlugins } from "../src/load-plugins.ts";
|
|
38
40
|
import { Inspector } from "./Inspector.tsx";
|
|
39
41
|
|
|
@@ -41,7 +43,7 @@ import { Inspector } from "./Inspector.tsx";
|
|
|
41
43
|
* 宿主自己在运行时里的身份:不贡献任何东西,只为拿一份项目作用域的 ctx(读诊断、顶栏的「产物」改选中),
|
|
42
44
|
* 选中的来源、诊断里写的是它,不冒用别的插件。
|
|
43
45
|
*/
|
|
44
|
-
const HOST_PLUGIN =
|
|
46
|
+
const HOST_PLUGIN = DEV_HOST_PLUGIN;
|
|
45
47
|
const hostPlugin: LoadedPlugin = {
|
|
46
48
|
input: {
|
|
47
49
|
packageJson: {
|
|
@@ -116,11 +118,14 @@ async function boot() {
|
|
|
116
118
|
}
|
|
117
119
|
: base;
|
|
118
120
|
const fixture = withStageDefs(withArtifacts(dev.fixture));
|
|
119
|
-
const transport = createFixtureTransport(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
const transport = createFixtureTransport(
|
|
122
|
+
{ ...fixture, managers: devManagers(roleParam, dev.roles, member.id) },
|
|
123
|
+
{
|
|
124
|
+
actor: { kind: "human", id: member.id },
|
|
125
|
+
defaultAgent: dev.agent,
|
|
126
|
+
resources: dev.resources,
|
|
127
|
+
},
|
|
128
|
+
);
|
|
124
129
|
|
|
125
130
|
// 插件入口并行导入;一个失败只让它进「没加载的插件」
|
|
126
131
|
const official: LoadedPlugin[] = [];
|
package/dev-host/host.css
CHANGED
|
@@ -87,6 +87,17 @@ body {
|
|
|
87
87
|
gap: 4px;
|
|
88
88
|
overflow-wrap: anywhere;
|
|
89
89
|
}
|
|
90
|
+
.dev-inspector-official {
|
|
91
|
+
margin-top: 4px;
|
|
92
|
+
}
|
|
93
|
+
.dev-inspector-official summary {
|
|
94
|
+
cursor: pointer;
|
|
95
|
+
color: var(--muted);
|
|
96
|
+
font-size: 12px;
|
|
97
|
+
}
|
|
98
|
+
.dev-inspector-official ul {
|
|
99
|
+
margin-top: 4px;
|
|
100
|
+
}
|
|
90
101
|
.dev-inspector pre {
|
|
91
102
|
margin: 0;
|
|
92
103
|
font-family: var(--mono);
|
package/dev-host/main.tsx
CHANGED
|
@@ -22,6 +22,11 @@ function showFailure() {
|
|
|
22
22
|
root.replaceChildren(pre);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
// 预览 ingress 会断掉空闲约 180 秒的 WebSocket:页面也定时发一条,两个方向都有流量(服务端的在 dev-server.ts)
|
|
26
|
+
if (import.meta.hot) {
|
|
27
|
+
const hot = import.meta.hot;
|
|
28
|
+
setInterval(() => hot.send("band:heartbeat", {}), 60_000);
|
|
29
|
+
}
|
|
25
30
|
import.meta.hot?.on("vite:error", (payload: { err: { message: string } }) => {
|
|
26
31
|
viteErrors.push(payload.err.message);
|
|
27
32
|
showFailure();
|
package/dist/bin.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
main
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q2XJXNVH.js";
|
|
5
5
|
import "./chunk-CL3FV65M.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-XPLYTHNX.js";
|
|
7
|
+
import "./chunk-LGYGWMSY.js";
|
|
8
8
|
|
|
9
9
|
// src/bin.ts
|
|
10
10
|
process.exitCode = await main(process.argv.slice(2));
|
package/dist/build-plugin.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { SHARED_MODULES } from '@kanyun-ai-infra/band-plugin-sdk';
|
|
2
|
-
export { W as WORKSHOP_FORBIDDEN_IMPORTS, c as checkPlugin, a as checkPluginSources } from './workshop-repo-
|
|
2
|
+
export { W as WORKSHOP_FORBIDDEN_IMPORTS, c as checkPlugin, a as checkPluginSources } from './workshop-repo-DqoVdcGu.js';
|
|
3
3
|
import '@kanyun-ai-infra/band-contracts';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
package/dist/build-plugin.js
CHANGED
|
@@ -442,7 +442,7 @@ var ROLE_PERMISSIONS = [
|
|
|
442
442
|
"confirm",
|
|
443
443
|
"approve",
|
|
444
444
|
"publish",
|
|
445
|
-
/** @deprecated 管理权限由服务端的工坊与项目成员管理角色决定(`workshop_members`、`members.role`),这里照常校验但不起作用,`band check`
|
|
445
|
+
/** @deprecated 管理权限由服务端的工坊与项目成员管理角色决定(`workshop_members`、`members.role`),这里照常校验但不起作用,`band check` 告警;以后的协议大版本会改成拒绝。 */
|
|
446
446
|
"admin"
|
|
447
447
|
];
|
|
448
448
|
var RolePermissions = z2.array(z2.enum(ROLE_PERMISSIONS));
|
|
@@ -539,7 +539,7 @@ var WorkshopSchema = z2.object({
|
|
|
539
539
|
* 工坊的缺省 agent(1.11.0),缺省 `rondo`;agent 阶段写了 `agent` 就用阶段的(owner 11-02 启用阶段级 agent,
|
|
540
540
|
* [note](../../../.agents/notes/proposed/architecture/2026-10-27-single-agent-per-flow.md) 的部分取代头)。
|
|
541
541
|
* 写工坊项目里的 agent slug;阶段级 `agent` 覆盖它。`{ hubProject, slug }`(1.18.0)已弃用:1.x 照收并给告警,
|
|
542
|
-
* 解析出同一个 agent
|
|
542
|
+
* 解析出同一个 agent,以后的协议大版本会改成报错。
|
|
543
543
|
*/
|
|
544
544
|
agent: z2.union([Name, AgentRefSchema]).optional(),
|
|
545
545
|
/**
|
|
@@ -555,9 +555,9 @@ var WorkshopSchema = z2.object({
|
|
|
555
555
|
* 决定 3)。这里只认字段;发布检查与派发在服务端读它。
|
|
556
556
|
*/
|
|
557
557
|
userModelKey: z2.enum(["off", "allow", "require"]).optional(),
|
|
558
|
-
/** 已弃用:工坊只复制、不继承。1.x
|
|
558
|
+
/** 已弃用:工坊只复制、不继承。1.x 照旧合并并给警告,以后的协议大版本会改成报错;`overrides` 同。 */
|
|
559
559
|
extends: z2.string().min(1).optional(),
|
|
560
|
-
/** 已弃用:迭代方式写在 `repos.<名>.iteration` 上。1.x 只在没写 `repos`
|
|
560
|
+
/** 已弃用:迭代方式写在 `repos.<名>.iteration` 上。1.x 只在没写 `repos` 时接受并给警告(不再起作用),以后的协议大版本会改成报错。 */
|
|
561
561
|
iteration: IterationSchema.optional(),
|
|
562
562
|
repos: recordSchema2(Name, RepoSchema).optional(),
|
|
563
563
|
connectors: recordSchema2(Name, WorkshopConnectorSchema).optional(),
|
|
@@ -847,17 +847,17 @@ function inferConcept(s, kind, at, warnings) {
|
|
|
847
847
|
case "human":
|
|
848
848
|
if (s.gate !== void 0) return "check";
|
|
849
849
|
warnings.push(
|
|
850
|
-
`${at}: human \u9636\u6BB5\u65E2\u6CA1\u5199 produces \u4E5F\u6CA1\u5199\u95E8\u7981\uFF0C\u65E0\u4E8B\u53EF\u505A\uFF1B\u8981\u4EBA\u4EA4\u4E1C\u897F\u5199 produces\uFF08type: collect\uFF09\uFF0C\u8981\u4EBA\u9A8C\u5199\u95E8\u7981\uFF08type: review\uFF09\
|
|
850
|
+
`${at}: human \u9636\u6BB5\u65E2\u6CA1\u5199 produces \u4E5F\u6CA1\u5199\u95E8\u7981\uFF0C\u65E0\u4E8B\u53EF\u505A\uFF1B\u8981\u4EBA\u4EA4\u4E1C\u897F\u5199 produces\uFF08type: collect\uFF09\uFF0C\u8981\u4EBA\u9A8C\u5199\u95E8\u7981\uFF08type: review\uFF09\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519`
|
|
851
851
|
);
|
|
852
852
|
return "produce";
|
|
853
853
|
case "agent":
|
|
854
854
|
warnings.push(
|
|
855
|
-
`${at}: agent \u9636\u6BB5\u6CA1\u5199 produces\
|
|
855
|
+
`${at}: agent \u9636\u6BB5\u6CA1\u5199 produces\uFF0C\u5F53\u524D\u5F53\u4EA7\u51FA\u9636\u6BB5\u5904\u7406\uFF0C\u4EA7\u7269\u7C7B\u578B\u7B49\u4EA4\u4ED8\u65F6\u5B9A\uFF1B\u8865\u4E0A produces\uFF0C\u6216\u5199 type\uFF08\u4EA7\u51FA\u5199 generate\uFF09\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519`
|
|
856
856
|
);
|
|
857
857
|
return "produce";
|
|
858
858
|
case "external":
|
|
859
859
|
warnings.push(
|
|
860
|
-
`${at}: external \u9636\u6BB5\u6CA1\u5199 produces\
|
|
860
|
+
`${at}: external \u9636\u6BB5\u6CA1\u5199 produces\uFF0C\u5F53\u524D\u5F53\u4EA7\u51FA\u9636\u6BB5\u5904\u7406\uFF0C\u4EA7\u7269\u7C7B\u578B\u7B49\u5916\u90E8\u56DE\u8C03\u65F6\u5B9A\uFF1B\u8865\u4E0A produces\uFF0C\u6216\u5199 type\uFF08\u4EA7\u51FA\u5199 generate\uFF0C\u53D1\u5E03\u5199 publish\uFF0C\u68C0\u6D4B\u5199 check\uFF09\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519`
|
|
861
861
|
);
|
|
862
862
|
return "produce";
|
|
863
863
|
}
|
|
@@ -1388,12 +1388,12 @@ function compileWorkshop(input, options = {}) {
|
|
|
1388
1388
|
checkConnectors(def, options.connectors, issues, warnings);
|
|
1389
1389
|
if (isPlainObject(input) && (input.extends !== void 0 || input.overrides !== void 0))
|
|
1390
1390
|
warnings.push(
|
|
1391
|
-
"extends / overrides: \u5DF2\u5F03\u7528\uFF0C\u5DE5\u574A\u53EA\u590D\u5236\u3001\u4E0D\u7EE7\u627F\uFF1B\u8981\u5728\u522B\u7684\u5DE5\u574A\u4E0A\u6539\uFF0C\u5230\u5B83\u7684\u8BE6\u60C5\u9875\u70B9\u300C\u590D\u5236\u4E00\u4EFD\u300D\uFF0C\u4E4B\u540E\u4E24\u8FB9\u5404\u6539\u5404\u7684\
|
|
1391
|
+
"extends / overrides: \u5DF2\u5F03\u7528\uFF0C\u5DE5\u574A\u53EA\u590D\u5236\u3001\u4E0D\u7EE7\u627F\uFF1B\u8981\u5728\u522B\u7684\u5DE5\u574A\u4E0A\u6539\uFF0C\u5230\u5B83\u7684\u8BE6\u60C5\u9875\u70B9\u300C\u590D\u5236\u4E00\u4EFD\u300D\uFF0C\u4E4B\u540E\u4E24\u8FB9\u5404\u6539\u5404\u7684\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519"
|
|
1392
1392
|
);
|
|
1393
1393
|
for (const [name, role] of Object.entries(def.roles ?? {}))
|
|
1394
1394
|
if (permissionsOf(role).includes("admin"))
|
|
1395
1395
|
warnings.push(
|
|
1396
|
-
`roles.${name}: admin \u6743\u9650\u5DF2\u5F03\u7528\uFF0C\u5199\u4E86\u4E0D\u8D77\u4F5C\u7528\uFF1B\u7BA1\u7406\u6743\u9650\u6539\u7531\u5DE5\u574A\u4E0E\u9879\u76EE\u7684\u7BA1\u7406\u89D2\u8272\u7ED9\uFF08\u5DE5\u574A\u6210\u5458 workshop_members\u3001\u9879\u76EE\u6210\u5458 members.role\uFF09\
|
|
1396
|
+
`roles.${name}: admin \u6743\u9650\u5DF2\u5F03\u7528\uFF0C\u5199\u4E86\u4E0D\u8D77\u4F5C\u7528\uFF1B\u7BA1\u7406\u6743\u9650\u6539\u7531\u5DE5\u574A\u4E0E\u9879\u76EE\u7684\u7BA1\u7406\u89D2\u8272\u7ED9\uFF08\u5DE5\u574A\u6210\u5458 workshop_members\u3001\u9879\u76EE\u6210\u5458 members.role\uFF09\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519`
|
|
1397
1397
|
);
|
|
1398
1398
|
const types = def.artifactTypes ?? {};
|
|
1399
1399
|
const repos = compileRepos(def, options, issues, warnings);
|
|
@@ -1492,14 +1492,14 @@ function compileWorkshop(input, options = {}) {
|
|
|
1492
1492
|
const reservedFor = d.artifactType ? reservedTypeUse(d.artifactType) : void 0;
|
|
1493
1493
|
if (d.artifactType && d.artifactType !== PASS_ARTIFACT_TYPE && reservedFor !== void 0) {
|
|
1494
1494
|
warnings.push(
|
|
1495
|
-
`${at}.needs: ${d.stage}:${d.artifactType} \u6307\u5411\u5E73\u53F0\u4FDD\u7559\u540D\uFF08${reservedFor}\uFF09\uFF1B\u7ED9\u5DE5\u574A\u7684\u4EA7\u7269\u7C7B\u578B\u6362\u4E2A\u540D\u5B57\
|
|
1495
|
+
`${at}.needs: ${d.stage}:${d.artifactType} \u6307\u5411\u5E73\u53F0\u4FDD\u7559\u540D\uFF08${reservedFor}\uFF09\uFF1B\u7ED9\u5DE5\u574A\u7684\u4EA7\u7269\u7C7B\u578B\u6362\u4E2A\u540D\u5B57\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519`
|
|
1496
1496
|
);
|
|
1497
1497
|
}
|
|
1498
1498
|
}
|
|
1499
1499
|
for (const w of bypasses(stages, st)) warnings.push(`${at}.needs: ${w}`);
|
|
1500
1500
|
if (st.concept === "check" && st.deps.length === 0) {
|
|
1501
1501
|
warnings.push(
|
|
1502
|
-
`${at}: \u68C0\u67E5\u9636\u6BB5\u6CA1\u5199 needs\uFF0C\u6CA1\u6709\u4E1C\u897F\u53EF\u9A8C\uFF0C\u4E0D\u51FA\u5019\u9009\u4E5F\u4E0D\u53D1\u4EFB\u52A1\uFF1B\u5199\u4E0A\u8981\u9A8C\u7684\u4E0A\u6E38\u9636\u6BB5\
|
|
1502
|
+
`${at}: \u68C0\u67E5\u9636\u6BB5\u6CA1\u5199 needs\uFF0C\u6CA1\u6709\u4E1C\u897F\u53EF\u9A8C\uFF0C\u4E0D\u51FA\u5019\u9009\u4E5F\u4E0D\u53D1\u4EFB\u52A1\uFF1B\u5199\u4E0A\u8981\u9A8C\u7684\u4E0A\u6E38\u9636\u6BB5\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519`
|
|
1503
1503
|
);
|
|
1504
1504
|
}
|
|
1505
1505
|
if (st.concept === "check" && st.fanOut !== void 0) {
|
|
@@ -1639,7 +1639,7 @@ function compileWorkshop(input, options = {}) {
|
|
|
1639
1639
|
warnNonAgentStageAgent(workflows, warnings);
|
|
1640
1640
|
if (typeof def.agent === "object")
|
|
1641
1641
|
warnings.push(
|
|
1642
|
-
`agent: { hubProject, slug } \u5199\u6CD5\u5DF2\u5F03\u7528\uFF1B\u5DE5\u574A\u7EA7 agent \u76F4\u63A5\u5199\u5DE5\u574A\u9879\u76EE\u91CC\u7684 agent slug\uFF08agent: ${def.agent.slug}\uFF09\uFF0C\u9636\u6BB5\u7EA7 agent \u8986\u76D6\u5B83\u3002\u6539\u5199\u540E\u8FD9\u4E2A agent \u8981\u5728 agents \u91CC\u58F0\u660E\uFF0C\u4E14\u4E0D\u518D\u6309\u539F hubProject \u6D3E\u53D1\
|
|
1642
|
+
`agent: { hubProject, slug } \u5199\u6CD5\u5DF2\u5F03\u7528\uFF1B\u5DE5\u574A\u7EA7 agent \u76F4\u63A5\u5199\u5DE5\u574A\u9879\u76EE\u91CC\u7684 agent slug\uFF08agent: ${def.agent.slug}\uFF09\uFF0C\u9636\u6BB5\u7EA7 agent \u8986\u76D6\u5B83\u3002\u6539\u5199\u540E\u8FD9\u4E2A agent \u8981\u5728 agents \u91CC\u58F0\u660E\uFF0C\u4E14\u4E0D\u518D\u6309\u539F hubProject \u6D3E\u53D1\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519`
|
|
1643
1643
|
);
|
|
1644
1644
|
const agents = compileAgents(
|
|
1645
1645
|
def,
|
|
@@ -1777,7 +1777,7 @@ function compileRepos(def, options, issues, warnings) {
|
|
|
1777
1777
|
issues.push("iteration: \u8FED\u4EE3\u65B9\u5F0F\u5199\u5728 repos.<\u540D>.iteration \u4E0A\uFF0C\u5DE5\u574A\u7EA7\u7684 iteration \u5220\u6389");
|
|
1778
1778
|
} else {
|
|
1779
1779
|
warnings.push(
|
|
1780
|
-
"iteration: \u5DF2\u5F03\u7528\uFF0C\u4E0D\u518D\u8D77\u4F5C\u7528\uFF08\u5DE5\u574A\u4ED3\u5E93\u4E0D\u653E\u4EA7\u7269\uFF0C\u4E5F\u6CA1\u6709\u9879\u76EE\u5206\u652F\uFF09\uFF1B\u8981\u63D0\u4EA4\u4EE3\u7801\u7684\u4EA7\u7269\u5199\u5230 repos \u58F0\u660E\u7684\u76EE\u6807\u4ED3\u5E93\uFF0Citeration \u5199\u5728 repos.<\u540D> \u4E0A\
|
|
1780
|
+
"iteration: \u5DF2\u5F03\u7528\uFF0C\u4E0D\u518D\u8D77\u4F5C\u7528\uFF08\u5DE5\u574A\u4ED3\u5E93\u4E0D\u653E\u4EA7\u7269\uFF0C\u4E5F\u6CA1\u6709\u9879\u76EE\u5206\u652F\uFF09\uFF1B\u8981\u63D0\u4EA4\u4EE3\u7801\u7684\u4EA7\u7269\u5199\u5230 repos \u58F0\u660E\u7684\u76EE\u6807\u4ED3\u5E93\uFF0Citeration \u5199\u5728 repos.<\u540D> \u4E0A\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519"
|
|
1781
1781
|
);
|
|
1782
1782
|
}
|
|
1783
1783
|
}
|
|
@@ -1819,7 +1819,9 @@ function compileRepos(def, options, issues, warnings) {
|
|
|
1819
1819
|
function checkSurfaces(def, warnings) {
|
|
1820
1820
|
const surfaces = def.views?.surfaces;
|
|
1821
1821
|
if (surfaces === void 0) return;
|
|
1822
|
-
warnings.push(
|
|
1822
|
+
warnings.push(
|
|
1823
|
+
"views.surfaces: \u5F53\u524D\u8FD8\u6CA1\u6709\u6E32\u67D3\uFF0C\u5199\u4E86\u4E0D\u8D77\u4F5C\u7528\uFF1B\u5F62\u72B6\u5F85\u5B9A\uFF0C\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6309 schema \u6821\u9A8C"
|
|
1824
|
+
);
|
|
1823
1825
|
for (const [name, fields] of Object.entries(surfaces)) {
|
|
1824
1826
|
const at = `views.surfaces.${name}`;
|
|
1825
1827
|
if (!/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(name))
|
|
@@ -1877,7 +1879,7 @@ function checkArtifactTypes(def, repos, issues, warnings) {
|
|
|
1877
1879
|
const reservedFor = reservedTypeUse(name);
|
|
1878
1880
|
if (reservedFor !== void 0) {
|
|
1879
1881
|
warnings.push(
|
|
1880
|
-
`${at}: ${name} \u662F\u5E73\u53F0\u4FDD\u7559\u7684\u4EA7\u7269\u7C7B\u578B\u540D\uFF08${reservedFor}\uFF09\uFF0C\u6362\u4E2A\u540D\u5B57\
|
|
1882
|
+
`${at}: ${name} \u662F\u5E73\u53F0\u4FDD\u7559\u7684\u4EA7\u7269\u7C7B\u578B\u540D\uFF08${reservedFor}\uFF09\uFF0C\u6362\u4E2A\u540D\u5B57\u3002\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519`
|
|
1881
1883
|
);
|
|
1882
1884
|
}
|
|
1883
1885
|
if (t.role === "process" && t.storage !== void 0 && t.storage !== "store") {
|
|
@@ -1901,7 +1903,7 @@ function checkArtifactTypes(def, repos, issues, warnings) {
|
|
|
1901
1903
|
}
|
|
1902
1904
|
if (t.repo === void 0 && t.paths === void 0) {
|
|
1903
1905
|
warnings.push(
|
|
1904
|
-
`${at}: storage: git \u8981\u5199 repo\uFF08repos \u91CC\u7684\u540D\u5B57\uFF09\u4E0E paths\uFF1B\u6CA1\u5199\u7684\u4EA7\u7269\u6CA1\u6709\u76EE\u6807\u4ED3\u5E93\
|
|
1906
|
+
`${at}: storage: git \u8981\u5199 repo\uFF08repos \u91CC\u7684\u540D\u5B57\uFF09\u4E0E paths\uFF1B\u6CA1\u5199\u7684\u4EA7\u7269\u6CA1\u6709\u76EE\u6807\u4ED3\u5E93\uFF0C\u4EE5\u540E\u7684\u534F\u8BAE\u5927\u7248\u672C\u4F1A\u6539\u6210\u62A5\u9519`
|
|
1905
1907
|
);
|
|
1906
1908
|
continue;
|
|
1907
1909
|
}
|
|
@@ -2094,7 +2096,7 @@ function checkPlugin(manifestPath, spec, within) {
|
|
|
2094
2096
|
const entry = resolve(dirname(manifestPath), r.data.entry);
|
|
2095
2097
|
const rel = relative(resolve(within), entry);
|
|
2096
2098
|
if (rel.startsWith("..") || isAbsolute(rel)) {
|
|
2097
|
-
return { spec, reason: `\u5165\u53E3 ${r.data.entry} \u8DF3\u51FA\u4E86
|
|
2099
|
+
return { spec, reason: `\u5165\u53E3 ${r.data.entry} \u8DF3\u51FA\u4E86\u4ED3\u5E93\u76EE\u5F55\uFF08\u5165\u53E3\u8981\u6307\u5411\u4ED3\u5E93\u91CC\u7684\u6587\u4EF6\uFF09` };
|
|
2098
2100
|
}
|
|
2099
2101
|
return {
|
|
2100
2102
|
spec,
|