@kanyun-ai-infra/band-cli 0.1.1 → 0.2.1
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/dist/index.js +1 -1
- package/bundled/official/chat/package.json +4 -4
- package/bundled/official/chunks/chunk-7XYETT7C.js +1 -0
- package/bundled/official/comment/dist/index.js +1 -1
- package/bundled/official/comment/package.json +4 -4
- package/bundled/official/header/package.json +4 -4
- package/bundled/official/home/dist/index.js +1 -1
- 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/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/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/dist/index.js +1 -1
- 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/package.json +2 -2
- package/bundled/official/viewer-storyboard/package.json +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/references/code.md +2 -2
- package/bundled/skills/band-plugin/references/manifest.md +2 -2
- package/bundled/skills/band-plugin/references/rules.md +1 -0
- package/bundled/skills/band-plugin/references/testing-publish.md +1 -1
- package/bundled/skills/band-plugin/templates/panel/package.json +1 -1
- package/bundled/tokens/components.css +1 -1
- package/dev-host/app.tsx +32 -12
- package/dev-host/host.css +7 -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-VTAJX7NN.js → chunk-FGPWXAOA.js} +165 -26
- package/dist/{chunk-TQHHHXXU.js → chunk-LGYGWMSY.js} +18 -16
- package/dist/{chunk-JWZU3NOD.js → chunk-XPLYTHNX.js} +1 -1
- package/dist/{dev-server-SB5FMSVP.js → dev-server-IBR3PKDE.js} +33 -5
- package/dist/fixture.d.ts +11 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +3 -3
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +2 -2
- package/dist/{workshop-repo-Uq6blxyt.d.ts → workshop-repo-DqoVdcGu.d.ts} +9 -9
- package/package.json +10 -7
- package/src/dev-managers.ts +16 -0
- package/src/inspector-default.ts +9 -0
- package/bundled/official/chunks/chunk-SB74RUTN.js +0 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanyun-ai-infra/band-workshops",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "工坊目录、工坊详情、新建项目、新建与复制工坊、工坊设置与对话改工坊九个页面",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"@kanyun-ai-infra/band-plugin-sdk": "^1.
|
|
11
|
-
"react": "^
|
|
12
|
-
"react-dom": "^
|
|
10
|
+
"@kanyun-ai-infra/band-plugin-sdk": "^2.1.0",
|
|
11
|
+
"react": "^19.0.0",
|
|
12
|
+
"react-dom": "^19.0.0",
|
|
13
13
|
"@kanyun-ai-infra/band-shell": "*"
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 官方插件:工坊目录、工坊详情、新建项目、新建工坊与基于已有工坊新建、工坊设置(v8 §7)。往外壳的 pages 贡献九页:/workshops 目录,
|
|
2
2
|
# /w/<工坊>/about 详情(工坊轻应用的「关于工坊」),/w/<工坊>/new 用这个工坊新建项目,/workshops/new 新建工坊,
|
|
3
3
|
# /workshops/<工坊>/copy 复制这个工坊(不放在 /w/ 下:那一层的第二段是项目短名),/w/<工坊>/about/model 工坊设置 ·
|
|
4
4
|
# 模型,/w/<工坊>/about/secrets 工坊设置 · 密钥,/w/<工坊>/new/resume 从「我的模型与凭据」配好回来后接着新建。旧地址写在 aliases,打开时改写成新地址。
|
|
@@ -39,7 +39,7 @@ contributes:
|
|
|
39
39
|
- slot: "@kanyun-ai-infra/band-shell/pages"
|
|
40
40
|
id: copy
|
|
41
41
|
route: /workshops/:workshop/copy
|
|
42
|
-
title:
|
|
42
|
+
title: 基于已有工坊新建
|
|
43
43
|
frame: shell
|
|
44
44
|
# 工坊设置 · 模型(建工坊的第 2 步也是这一页):/w/<工坊>/about/model,比 about 更具体;部署没开代建时页面写明没有这一步
|
|
45
45
|
- slot: "@kanyun-ai-infra/band-shell/pages"
|
|
@@ -44,7 +44,7 @@ export default definePlugin({
|
|
|
44
44
|
|
|
45
45
|
- `ctx.version`:`current()` 当前版本(可能是 null),`subscribe` 换版本,`list(artifactId)` 一份产物的全部版本(从旧到新),`readFile(path)`、`objectUrl(path)` 读当前版本的文件(可传 `{ versionId }` 读别的版本)。查看器的 `ctx.version` 钉在正在看的版本上,换版本时整个重挂。
|
|
46
46
|
- `ctx.selection`:本项目里插件共享的选中,`get` / `set` / `subscribe`。五种:`{ kind: "artifact", artifactId }`、`{ kind: "entity", entityType, id, artifactId? }`、`{ kind: "timecode", seconds, end?, artifactId?, path? }`、`{ kind: "anchor", anchor }`、`{ kind: "stage", stage }`。`subscribe` 收到 `{ value, source }`,`source === ctx.plugin` 是自己的回声,跳过;不认识的 `kind` 当作与己无关。插件之间联动只靠它,不要互相 import 状态。
|
|
47
|
-
- `ctx.anchors.make(kind, payload, snapshot?)`:在当前版本上造锚点。内置类型直接写;自己注册的写短名,内核补成 `plugin:<包名>/<kind>`。内置类型的 payload 都要带 `label`,内容在文件里的还要带 `path
|
|
47
|
+
- `ctx.anchors.make(kind, payload, snapshot?)`:在当前版本上造锚点。内置类型直接写;自己注册的写短名,内核补成 `plugin:<包名>/<kind>`。内置类型的 payload 都要带 `label`,内容在文件里的还要带 `path`,多写字段也算不合写法(当前只在控制台警告,以后的协议大版本会改成报错;`shot` 现在就抛错)。自己注册的类型也把 `label` 写进 payload:线程里显示的位置文字取它,`AnchorType.label` 现在没人调用。形状:`entity` 是 `{ path, label, entityType, id, hash?, point? }`,`text-range` 是 `{ path, label, quote: { exact, prefix?, suffix? }, pos?, lines? }`,`region` 是 `{ path, label, rect: { x, y, w, h }, page? }`(0–1 比例),`timecode` 是 `{ path, label, seconds, end?, rect? }`,`shot` 是 `{ path: "storyboard.json", label, shotId, takeId? }`。
|
|
48
48
|
- `ctx.threads.list(filter)` 读线程;`ctx.threads.openAt(anchor, { draft, handToAgent, intent })` 请锁定的评论框在锚点上打开(`intent` 只有 `"pick"`:镜头候选上「用这条」,锚点是带 `takeId` 的 `shot`);`ctx.threads.open(id)` 打开已有线程。插件不能自己建线程。
|
|
49
49
|
- 引用:`ctx.threads.quote(threadId, commentId)` 把一条消息、`ctx.threads.quoteAnchor(anchor)` 把一处位置作为引用放进发送框,都不发送。
|
|
50
50
|
- `ctx.gate.open(stage, key?)` 请批准面板打开;`ctx.stages.list / get / start / rerun / rerunWith` 读写阶段运行。
|
|
@@ -55,4 +55,4 @@ export default definePlugin({
|
|
|
55
55
|
- `ctx.events.subscribe("thread.*", fn)`:按类型或前缀订阅事件。事件名以 `EVENT_TYPES`(`@kanyun-ai-infra/band-plugin-sdk` 导出)为准;关心意见就订 `EVENT_GROUPS.threads`(含评论、改动请求、回合),关心流程就订 `EVENT_GROUPS.stages`,别只订 `thread.*`。
|
|
56
56
|
- 打开停靠位:`(ctx.services.get("@kanyun-ai-infra/band-project/dock") as { open(key: string): void }).open("<包名>/<停靠位 id>")`。工具栏按钮写了 `dock` 的,查看器替你开。
|
|
57
57
|
- `ctx.member`(`can("comment")` 判能不能提意见)、`ctx.params`、`ctx.plugin`(本插件的包名)。
|
|
58
|
-
- 只给官方插件、工坊插件拿到 `undefined` 的:`notify`、`approvalSettings`、`memberSettings`、`visibilitySettings`、`artifactShares`、`version.archiveUrl`、`turns.requestStop`、`project.shared`、`project.notices`、`project.upgrade`、`project.remove`;`app.data.write.workshopArchive
|
|
58
|
+
- 只给官方插件、工坊插件拿到 `undefined` 的:`notify`、`approvalSettings`、`memberSettings`、`visibilitySettings`、`artifactShares`、`version.archiveUrl`、`turns.requestStop`、`project.shared`、`project.notices`、`project.upgrade`、`project.remove`;`app.data.write.workshopArchive`、`people`(人员目录)只给部署方案插件。不要写依赖它们的功能。
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"keywords": ["数据库", "表格"],
|
|
14
14
|
"type": "module",
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"@kanyun-ai-infra/band-plugin-sdk": "^
|
|
16
|
+
"@kanyun-ai-infra/band-plugin-sdk": "^2.0.0",
|
|
17
17
|
"@kanyun-ai-infra/band-project": "*",
|
|
18
18
|
"@kanyun-ai-infra/band-viewer-web": "*"
|
|
19
19
|
},
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
- 包名带作用域,工坊插件用工坊名(`band new plugin` 取工坊仓库的目录名,去掉 `band-` 前缀);`@kanyun-ai-infra/band-` 前缀只留给官方插件。
|
|
25
25
|
- `description`(一句话说明)与 `keywords` 显示在插件目录里,人和 Rondo 靠它们挑插件,写上。`"private": true` 表示只在本工坊用;工坊插件不发 npm 包。
|
|
26
|
-
- `peerDependencies` 必须有 `@kanyun-ai-infra/band-plugin-sdk`(协议版本,`^
|
|
26
|
+
- `peerDependencies` 必须有 `@kanyun-ai-infra/band-plugin-sdk`(协议版本,`^2.0.0`)。往谁的插槽贡献、用谁的服务,就把谁写进来;官方插件还没有对外版本号,写 `"*"`。
|
|
27
27
|
|
|
28
28
|
`plugin.yaml`:Band 的声明,不写 `name`(顶层写了 `name` 的是已废弃的 0.x 清单,`band check` 直接报错)。
|
|
29
29
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
- **异步要防乱序**:换版本、切环境时旧请求的结果可能晚到。每次加载记一个序号,结果回来时对不上就丢掉;读不到新数据时清空界面,不留旧数据(尤其是带「删除」按钮的表格)。
|
|
7
7
|
- **读不到不抛错**:版本里可能没有你要的文件、JSON 可能坏了。界面显示「这个版本没有……」,锚点解析返回 null。
|
|
8
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 站「组件」。
|
|
9
10
|
- **样式只用 Band Design token**:页面提供 `--panel`、`--ink`、`--muted`、`--accent`、`--r-lg` 等 CSS 变量,插件里不写死颜色,类名带插件名前缀。琥珀色(`--warn*`)只给部署方案装的插件(锁定插件、应用级页面)用,工坊插件不用。
|
|
10
11
|
- **工坊页面跟工坊最新发布走,项目页跟项目钉住的版本走**:同一工坊里两者可能是不同版本的插件代码。页面里不要假设项目页的面板、服务是同一版;页面只读本工坊的应用数据(`ctx.app.data` 已固定在本工坊,没有 `write`)。路由只写 `/w/:workshop/x/<页面>`,不写 `aliases`、`opens`。
|
|
11
12
|
- **不放凭据**:接口身份由 Band 代理注入,插件代码和仓库里都不出现 token、连接串。
|
|
@@ -32,4 +32,4 @@ bed.dispose();
|
|
|
32
32
|
|
|
33
33
|
`band publish <工坊仓库目录> --url <Band 服务地址> --workshop <id>` 先校验并要求工作区干净,用作者的 git 凭据推送远端同名分支(须与工坊发布分支一致),再用 `BAND_TOKEN` 的 Bearer 身份只调一次 POST releases,不调用工坊 GET。`--workshop` 必填,id 从工坊页地址 `/w/<id>` 获取。可 `--no-push` 跳过推送。不要将 token 写进工坊仓库或命令文本;真实服务发布依赖平台 token 功能,缺少鉴权时继续用页面。构建命令与带依赖预设在生产隔离端口未装配前仍关闭。
|
|
34
34
|
|
|
35
|
-
`band preview [分支] --workshop <id> [--project <项目 id>]`:把已 push 的分支建成预览快照(只读工坊仓库、不发新版本),带 `--project` 时打印 `?preview=` 的项目链接,只有工坊管理员能打开;token 要 `workshops:preview` scope
|
|
35
|
+
`band preview [分支] --workshop <id> [--project <项目 id>]`:把已 push 的分支建成预览快照(只读工坊仓库、不发新版本),带 `--project` 时打印 `?preview=` 的项目链接,只有工坊管理员能打开;token 要 `workshops:preview` scope。预览页的写入会落到打开的那个项目(试用项目就落在试用项目里)。
|
|
@@ -210,7 +210,7 @@ input.field[type="number"] { font-variant-numeric: tabular-nums; }
|
|
|
210
210
|
/* 输入框下面一行:提示、出错、计数。计数靠右,超了写 .over(DESIGN.md「控件」) */
|
|
211
211
|
.field-note { display: flex; align-items: center; gap: 6px; margin: 0; min-height: 16px; font-size: var(--fs-badge); color: var(--muted); }
|
|
212
212
|
.field-note.err { color: var(--bad); }
|
|
213
|
-
.field-count { font-family: var(--mono); }
|
|
213
|
+
.field-count { font-family: var(--mono); white-space: nowrap; }
|
|
214
214
|
.field-note > .field-count { margin-left: auto; }
|
|
215
215
|
.field-count.over { color: var(--bad); }
|
|
216
216
|
|
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 { inspectorOpenByDefault } from "../src/inspector-default.ts";
|
|
37
39
|
import { DEV_HOST_PLUGIN } from "../src/inspector-plugins.ts";
|
|
38
40
|
import { loadPlugins } from "../src/load-plugins.ts";
|
|
39
41
|
import { Inspector } from "./Inspector.tsx";
|
|
@@ -117,11 +119,14 @@ async function boot() {
|
|
|
117
119
|
}
|
|
118
120
|
: base;
|
|
119
121
|
const fixture = withStageDefs(withArtifacts(dev.fixture));
|
|
120
|
-
const transport = createFixtureTransport(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
const transport = createFixtureTransport(
|
|
123
|
+
{ ...fixture, managers: devManagers(roleParam, dev.roles, member.id) },
|
|
124
|
+
{
|
|
125
|
+
actor: { kind: "human", id: member.id },
|
|
126
|
+
defaultAgent: dev.agent,
|
|
127
|
+
resources: dev.resources,
|
|
128
|
+
},
|
|
129
|
+
);
|
|
125
130
|
|
|
126
131
|
// 插件入口并行导入;一个失败只让它进「没加载的插件」
|
|
127
132
|
const official: LoadedPlugin[] = [];
|
|
@@ -312,6 +317,10 @@ function focusOf(s: Selection | null): string | undefined {
|
|
|
312
317
|
}
|
|
313
318
|
|
|
314
319
|
function App() {
|
|
320
|
+
// 夹具栏占 300px:视口不到 1600 默认收起,免得挤坏项目页右栏;收起时仍挂着,事件与诊断照常记
|
|
321
|
+
const [inspectorOpen, setInspectorOpen] = useState(() =>
|
|
322
|
+
inspectorOpenByDefault(window.innerWidth),
|
|
323
|
+
);
|
|
315
324
|
return (
|
|
316
325
|
<div className="dev-page">
|
|
317
326
|
<header className="dev-bar">
|
|
@@ -341,16 +350,27 @@ function App() {
|
|
|
341
350
|
) : (
|
|
342
351
|
<span className="chip plain">{member.displayName}</span>
|
|
343
352
|
)}
|
|
353
|
+
<button
|
|
354
|
+
type="button"
|
|
355
|
+
className="btn"
|
|
356
|
+
aria-expanded={inspectorOpen}
|
|
357
|
+
aria-controls="dev-inspector-slot"
|
|
358
|
+
onClick={() => setInspectorOpen((v) => !v)}
|
|
359
|
+
>
|
|
360
|
+
夹具
|
|
361
|
+
</button>
|
|
344
362
|
</header>
|
|
345
363
|
<div className="dev-body">
|
|
346
364
|
<ProjectPage />
|
|
347
|
-
<
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
365
|
+
<div id="dev-inspector-slot" className="dev-inspector-slot" hidden={!inspectorOpen}>
|
|
366
|
+
<Inspector
|
|
367
|
+
ctx={hostCtx}
|
|
368
|
+
view={view}
|
|
369
|
+
transport={transport}
|
|
370
|
+
problems={problems}
|
|
371
|
+
stageViews={stageViews}
|
|
372
|
+
/>
|
|
373
|
+
</div>
|
|
354
374
|
</div>
|
|
355
375
|
</div>
|
|
356
376
|
);
|
package/dev-host/host.css
CHANGED
|
@@ -63,6 +63,13 @@ body {
|
|
|
63
63
|
.dev-project > .band-react-surface {
|
|
64
64
|
display: contents;
|
|
65
65
|
}
|
|
66
|
+
/* 夹具栏的槽:展开时不占自己的盒子(让 aside 直接当 .dev-body 的子项),收起时整块不显示 */
|
|
67
|
+
.dev-inspector-slot {
|
|
68
|
+
display: contents;
|
|
69
|
+
}
|
|
70
|
+
.dev-inspector-slot[hidden] {
|
|
71
|
+
display: none;
|
|
72
|
+
}
|
|
66
73
|
/* 锁定插件替身只标位置 */
|
|
67
74
|
.dev-inspector {
|
|
68
75
|
width: 300px;
|
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-FGPWXAOA.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
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
officialProfilePath,
|
|
11
11
|
resolvePluginRepo,
|
|
12
12
|
workshopNameOf
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XPLYTHNX.js";
|
|
14
14
|
import {
|
|
15
15
|
IMPLICIT_STAGE,
|
|
16
16
|
SELF_CONTAINED_EXTENSIONS,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
rolePermissions,
|
|
30
30
|
selfContainedProblems,
|
|
31
31
|
workshopFileReader
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-LGYGWMSY.js";
|
|
33
33
|
|
|
34
34
|
// src/index.ts
|
|
35
35
|
import { execFileSync } from "child_process";
|
|
@@ -310,6 +310,8 @@ function newPlugin(root, name, opts) {
|
|
|
310
310
|
description: title,
|
|
311
311
|
type: "module",
|
|
312
312
|
peerDependencies: {
|
|
313
|
+
react: "^19.0.0",
|
|
314
|
+
"react-dom": "^19.0.0",
|
|
313
315
|
"@kanyun-ai-infra/band-plugin-sdk": `^${BAND_PROTOCOL_VERSION}`,
|
|
314
316
|
[PROJECT]: "*"
|
|
315
317
|
}
|
|
@@ -432,6 +434,8 @@ ${t.manifest}`,
|
|
|
432
434
|
// 不带 --passWithNoTests:收不到测试要红,不吞成绿(band#456)
|
|
433
435
|
scripts: { check: "tsc -p tsconfig.json", test: "vitest run" },
|
|
434
436
|
peerDependencies: {
|
|
437
|
+
react: "^19.0.0",
|
|
438
|
+
"react-dom": "^19.0.0",
|
|
435
439
|
"@kanyun-ai-infra/band-plugin-sdk": "workspace:*",
|
|
436
440
|
[PROJECT]: "workspace:*"
|
|
437
441
|
},
|
|
@@ -642,7 +646,7 @@ import { parse } from "yaml";
|
|
|
642
646
|
// package.json
|
|
643
647
|
var package_default = {
|
|
644
648
|
name: "@kanyun-ai-infra/band-cli",
|
|
645
|
-
version: "0.
|
|
649
|
+
version: "0.2.1",
|
|
646
650
|
description: "band \u547D\u4EE4\u884C\uFF1A\u65B0\u5EFA\u3001\u672C\u5730\u8C03\u8BD5\u3001\u6821\u9A8C\u4E0E\u53D1\u5E03 Band \u5DE5\u574A\u548C\u63D2\u4EF6",
|
|
647
651
|
license: "UNLICENSED",
|
|
648
652
|
type: "module",
|
|
@@ -657,7 +661,8 @@ var package_default = {
|
|
|
657
661
|
},
|
|
658
662
|
"./build": {
|
|
659
663
|
types: "./dist/build-plugin.d.ts",
|
|
660
|
-
import: "./dist/build-plugin.js"
|
|
664
|
+
import: "./dist/build-plugin.js",
|
|
665
|
+
default: "./dist/build-plugin.js"
|
|
661
666
|
},
|
|
662
667
|
"./catalog": {
|
|
663
668
|
types: "./dist/plugin-entry.d.ts",
|
|
@@ -692,8 +697,8 @@ var package_default = {
|
|
|
692
697
|
"@kanyun-ai-infra/band-plugin-react": "workspace:^",
|
|
693
698
|
"@kanyun-ai-infra/band-plugin-sdk": "workspace:^",
|
|
694
699
|
"es-module-lexer": "^2.3.2",
|
|
695
|
-
react: "^
|
|
696
|
-
"react-dom": "^
|
|
700
|
+
react: "^19.3.1",
|
|
701
|
+
"react-dom": "^19.3.1",
|
|
697
702
|
semver: "^7.8.5",
|
|
698
703
|
vite: "^6.0.7",
|
|
699
704
|
yaml: "^2.6.1",
|
|
@@ -705,8 +710,8 @@ var package_default = {
|
|
|
705
710
|
"@kanyun-ai-infra/band-tokens": "workspace:*",
|
|
706
711
|
"@kanyun-ai-infra/band-workshop": "workspace:*",
|
|
707
712
|
"@types/node": "^22.10.0",
|
|
708
|
-
"@types/react": "^
|
|
709
|
-
"@types/react-dom": "^
|
|
713
|
+
"@types/react": "^19.3.0",
|
|
714
|
+
"@types/react-dom": "^19.3.0",
|
|
710
715
|
tsup: "^8.4.0",
|
|
711
716
|
typescript: "5.9.3",
|
|
712
717
|
vitest: "^4.0.17"
|
|
@@ -737,11 +742,13 @@ function newPluginRepo(parentDir, packageName, opts) {
|
|
|
737
742
|
const title = opts.title ?? name;
|
|
738
743
|
const dir = join2(resolve2(parentDir), name);
|
|
739
744
|
if (existsSync2(dir)) throw new NewPluginError(`${dir} \u5DF2\u7ECF\u5B58\u5728`);
|
|
745
|
+
const react = opts.react === true;
|
|
746
|
+
const entryFile = react ? "src/index.tsx" : "src/index.ts";
|
|
740
747
|
const rendered = renderPluginTemplate(opts.template, {
|
|
741
748
|
title,
|
|
742
749
|
...opts.stage ? { stage: opts.stage } : {},
|
|
743
750
|
id: name,
|
|
744
|
-
entry:
|
|
751
|
+
entry: `./${entryFile}`
|
|
745
752
|
});
|
|
746
753
|
const workshop = fixtureWorkshop(packageName, opts.template, name, opts.stage);
|
|
747
754
|
try {
|
|
@@ -752,14 +759,16 @@ function newPluginRepo(parentDir, packageName, opts) {
|
|
|
752
759
|
);
|
|
753
760
|
}
|
|
754
761
|
const files = {
|
|
755
|
-
"package.json": `${JSON.stringify(packageJson(packageName, title), null, 2)}
|
|
762
|
+
"package.json": `${JSON.stringify(packageJson(packageName, title, react), null, 2)}
|
|
763
|
+
`,
|
|
764
|
+
"tsconfig.json": `${JSON.stringify(tsconfig(react), null, 2)}
|
|
756
765
|
`,
|
|
757
766
|
"plugin.yaml": rendered.manifest,
|
|
758
|
-
|
|
767
|
+
[entryFile]: react ? reactSource(opts.template, title, opts.stage, name) : rendered.code,
|
|
759
768
|
"dev/workshop.yaml": workshop,
|
|
760
769
|
"dev/fixture.ts": fixtureSource(opts.template, opts.stage),
|
|
761
770
|
".gitlab-ci.yml": CI(packageName),
|
|
762
|
-
"README.md": readme(packageName, title, opts.template, name, parsed.scope),
|
|
771
|
+
"README.md": readme(packageName, title, opts.template, name, parsed.scope, react),
|
|
763
772
|
".gitignore": "node_modules/\ndist/\n"
|
|
764
773
|
};
|
|
765
774
|
for (const [f, body] of Object.entries(files)) {
|
|
@@ -773,7 +782,8 @@ function newPluginRepo(parentDir, packageName, opts) {
|
|
|
773
782
|
hints: [
|
|
774
783
|
`cd ${dir} && npm install\uFF1A\u88C5\u4E0A band \u547D\u4EE4\u884C\u4E0E\u63D2\u4EF6 SDK\uFF08devDependencies\uFF09`,
|
|
775
784
|
"npx band dev .\uFF1A\u7528 dev/ \u5939\u5177\u5DE5\u574A\u8D77\u9875\u9762\uFF0C\u672C\u4ED3\u5E93\u7684\u63D2\u4EF6\u81EA\u52A8\u88C5\u4E0A",
|
|
776
|
-
"npx band check .\uFF1A\u6821\u9A8C\u63D2\u4EF6\u4E0E\u5939\u5177\u5DE5\u574A\u7684\u88C5\u914D",
|
|
785
|
+
"npx band check .\uFF1A\u6821\u9A8C\u63D2\u4EF6\u4E0E\u5939\u5177\u5DE5\u574A\u7684\u88C5\u914D\uFF08\u4E0D\u67E5\u7C7B\u578B\uFF09",
|
|
786
|
+
"npm run typecheck\uFF1A\u8DD1 tsc --noEmit \u67E5\u7C7B\u578B\uFF08band check \u4E0D\u67E5\uFF09",
|
|
777
787
|
placementHint(opts.template, packageName, name, opts.stage),
|
|
778
788
|
"\u53D1\u5E03\u8FD8\u6CA1\u63A5\u4E0A\uFF08\u63D2\u4EF6\u7531 Band \u6253\u5305\u5206\u53D1\uFF0C\u4E0D\u7ECF npm \u53D1\u5305\uFF09\uFF1A\u73B0\u5728 CI \u6A21\u677F\u53EA\u8DD1 band check"
|
|
779
789
|
]
|
|
@@ -786,7 +796,7 @@ function placementHint(template, packageName, name, stage) {
|
|
|
786
796
|
return `\u9636\u6BB5 ${String(stage)} \u7684\u754C\u9762\u4F1A\u51FA\u73B0\u5728\u5F15\u7528\u5B83\u7684\u5DE5\u574A\u7684\u9636\u6BB5\u8BE6\u60C5\u91CC`;
|
|
787
797
|
}
|
|
788
798
|
var PROJECT2 = "@kanyun-ai-infra/band-project";
|
|
789
|
-
function packageJson(packageName, title) {
|
|
799
|
+
function packageJson(packageName, title, react) {
|
|
790
800
|
return {
|
|
791
801
|
name: packageName,
|
|
792
802
|
version: "0.1.0",
|
|
@@ -794,18 +804,46 @@ function packageJson(packageName, title) {
|
|
|
794
804
|
license: "UNLICENSED",
|
|
795
805
|
type: "module",
|
|
796
806
|
files: ["src", "plugin.yaml", "README.md"],
|
|
797
|
-
scripts: { dev: "band dev .", check: "band check ." },
|
|
807
|
+
scripts: { dev: "band dev .", check: "band check .", typecheck: "tsc --noEmit" },
|
|
798
808
|
peerDependencies: {
|
|
809
|
+
react: "^19.0.0",
|
|
810
|
+
"react-dom": "^19.0.0",
|
|
799
811
|
"@kanyun-ai-infra/band-plugin-sdk": `^${BAND_PROTOCOL_VERSION2}`,
|
|
800
812
|
[PROJECT2]: "*"
|
|
801
813
|
},
|
|
802
814
|
peerDependenciesMeta: { [PROJECT2]: { optional: true } },
|
|
803
815
|
devDependencies: {
|
|
804
816
|
"@kanyun-ai-infra/band-cli": `^${CLI_VERSION}`,
|
|
805
|
-
"@kanyun-ai-infra/band-plugin-sdk": `^${BAND_PROTOCOL_VERSION2}
|
|
817
|
+
"@kanyun-ai-infra/band-plugin-sdk": `^${BAND_PROTOCOL_VERSION2}`,
|
|
818
|
+
typescript: "^5.9.3",
|
|
819
|
+
// 用 React 写才要:宿主与 band dev 提供运行时的 React,这些只给类型检查与编辑器提示
|
|
820
|
+
...react ? {
|
|
821
|
+
"@kanyun-ai-infra/band-plugin-react": `^${PLUGIN_REACT_RANGE}`,
|
|
822
|
+
"@types/react": "^19.0.0",
|
|
823
|
+
"@types/react-dom": "^19.0.0",
|
|
824
|
+
react: "^19.0.0",
|
|
825
|
+
"react-dom": "^19.0.0"
|
|
826
|
+
} : {}
|
|
806
827
|
}
|
|
807
828
|
};
|
|
808
829
|
}
|
|
830
|
+
var PLUGIN_REACT_RANGE = "0.2.1";
|
|
831
|
+
function tsconfig(react) {
|
|
832
|
+
return {
|
|
833
|
+
compilerOptions: {
|
|
834
|
+
target: "ES2022",
|
|
835
|
+
module: "ESNext",
|
|
836
|
+
moduleResolution: "bundler",
|
|
837
|
+
lib: ["ES2023", "DOM", "DOM.Iterable"],
|
|
838
|
+
strict: true,
|
|
839
|
+
noUncheckedIndexedAccess: true,
|
|
840
|
+
skipLibCheck: true,
|
|
841
|
+
noEmit: true,
|
|
842
|
+
...react ? { jsx: "react-jsx" } : {}
|
|
843
|
+
},
|
|
844
|
+
include: ["src", "dev"]
|
|
845
|
+
};
|
|
846
|
+
}
|
|
809
847
|
function fixtureWorkshop(packageName, template, name, stage) {
|
|
810
848
|
const head = `# \u72EC\u7ACB\u63D2\u4EF6 ${packageName} \u7684\u672C\u5730\u5939\u5177\u5DE5\u574A\uFF1Aband dev \u8D77\u9879\u76EE\u9875\u3001band check \u67E5\u88C5\u914D\u7528\uFF0C\u4E0D\u53D1\u5E03\u3001\u4E0D\u8FDB\u4EFB\u4F55\u771F\u5B9E\u5DE5\u574A\u3002
|
|
811
849
|
# \u672C\u4ED3\u5E93\u7684\u63D2\u4EF6\u7531\u547D\u4EE4\u76F4\u63A5\u88C5\u4E0A\uFF0C\u4E0D\u7528\u5199\u8FDB views.plugins\u3002
|
|
@@ -849,6 +887,85 @@ views:
|
|
|
849
887
|
`;
|
|
850
888
|
}
|
|
851
889
|
var q2 = (s) => JSON.stringify(s);
|
|
890
|
+
function reactSource(template, title, stage, id) {
|
|
891
|
+
const head = (what) => `/**
|
|
892
|
+
* ${what.replace(/\*\//g, "* /").replace(/[\r\n]+/g, " ")}
|
|
893
|
+
* \u53EA\u7528\u516C\u5F00 ctx\uFF1B\u672C\u5730 \`band dev\` \u8FB9\u5199\u8FB9\u770B\uFF0C\`npm run typecheck\` \u67E5\u7C7B\u578B\uFF0C\u63D0\u4EA4\u524D \`band check\`\u3002
|
|
894
|
+
*/
|
|
895
|
+
`;
|
|
896
|
+
const imports = `import { reactMount, useCtxData } from "@kanyun-ai-infra/band-plugin-react";
|
|
897
|
+
import { type ProjectCtx, definePlugin } from "@kanyun-ai-infra/band-plugin-sdk";
|
|
898
|
+
import { useState } from "react";
|
|
899
|
+
`;
|
|
900
|
+
if (template === "panel")
|
|
901
|
+
return `${head(`${title}\uFF1A\u4E00\u4E2A\u9762\u677F\u3002\u663E\u793A\u5F53\u524D\u7248\u672C\u7684\u6587\u4EF6\u6570\u3002`)}${imports.replace('import { useState } from "react";\n', "")}
|
|
902
|
+
function Panel({ ctx }: { ctx: ProjectCtx }) {
|
|
903
|
+
const { data, error } = useCtxData(ctx, async () => ctx.version.current(), [], "version.*");
|
|
904
|
+
if (error) return <p>{error}</p>;
|
|
905
|
+
if (data === undefined) return <p>\u8BFB\u53D6\u4E2D\u2026</p>;
|
|
906
|
+
return <p>{data ? \`\u7248\u672C \${data.id}\uFF1A\${data.entries.length} \u4E2A\u6587\u4EF6\` : "\uFF08\u8FD8\u6CA1\u6709\u7248\u672C\uFF09"}</p>;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
export default definePlugin({
|
|
910
|
+
surfaces: {
|
|
911
|
+
main: reactMount((ctx: ProjectCtx) => <Panel ctx={ctx} />),
|
|
912
|
+
},
|
|
913
|
+
});
|
|
914
|
+
`;
|
|
915
|
+
if (template === "viewer")
|
|
916
|
+
return `${head(`${title}\uFF1A\u4E00\u4E2A\u67E5\u770B\u5668\u3002\u5217\u51FA\u5F53\u524D\u7248\u672C\u7684\u6587\u4EF6\uFF0C\u70B9\u4E00\u4E2A\u770B\u5185\u5BB9\u3002`)}${imports}
|
|
917
|
+
function Viewer({ ctx }: { ctx: ProjectCtx }) {
|
|
918
|
+
const { data: version, error } = useCtxData(ctx, async () => ctx.version.current(), [], "version.*");
|
|
919
|
+
const [body, setBody] = useState("");
|
|
920
|
+
if (error) return <p>{error}</p>;
|
|
921
|
+
return (
|
|
922
|
+
<>
|
|
923
|
+
<ul>
|
|
924
|
+
{(version?.entries ?? []).map((e) => (
|
|
925
|
+
<li key={e.path}>
|
|
926
|
+
<button
|
|
927
|
+
type="button"
|
|
928
|
+
onClick={async () => setBody(new TextDecoder().decode(await ctx.version.readFile(e.path)))}
|
|
929
|
+
>
|
|
930
|
+
{e.path}
|
|
931
|
+
</button>
|
|
932
|
+
</li>
|
|
933
|
+
))}
|
|
934
|
+
</ul>
|
|
935
|
+
<pre>{body}</pre>
|
|
936
|
+
</>
|
|
937
|
+
);
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
export default definePlugin({
|
|
941
|
+
surfaces: {
|
|
942
|
+
${JSON.stringify(id)}: reactMount((ctx: ProjectCtx) => <Viewer ctx={ctx} />),
|
|
943
|
+
},
|
|
944
|
+
});
|
|
945
|
+
`;
|
|
946
|
+
const st = JSON.stringify(stage ?? "");
|
|
947
|
+
return `${head(`${title}\uFF1A\u9636\u6BB5 ${stage ?? ""} \u7684\u754C\u9762\u3002\u663E\u793A\u9636\u6BB5\u72B6\u6001\uFF0C\u53EF\u4EE5\u542F\u52A8\u3002`)}${imports.replace('import { useState } from "react";\n', "")}
|
|
948
|
+
const STAGE = ${st};
|
|
949
|
+
|
|
950
|
+
function StageView({ ctx }: { ctx: ProjectCtx }) {
|
|
951
|
+
const { data, error } = useCtxData(ctx, () => ctx.stages.get(STAGE), [], "stage.*");
|
|
952
|
+
return (
|
|
953
|
+
<>
|
|
954
|
+
<p>{error ?? (data ? \`\${data.stage}\uFF1A\${data.status}\` : "\u8BFB\u53D6\u4E2D\u2026")}</p>
|
|
955
|
+
<button type="button" onClick={() => void ctx.stages.start(STAGE)}>
|
|
956
|
+
\u542F\u52A8
|
|
957
|
+
</button>
|
|
958
|
+
</>
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
export default definePlugin({
|
|
963
|
+
surfaces: {
|
|
964
|
+
main: reactMount((ctx: ProjectCtx) => <StageView ctx={ctx} />),
|
|
965
|
+
},
|
|
966
|
+
});
|
|
967
|
+
`;
|
|
968
|
+
}
|
|
852
969
|
function fixtureSource(template, stage) {
|
|
853
970
|
const stages = template === "stage-view" ? ` stages: [{ stage: ${q2(stage ?? "")}, status: "ready" }],
|
|
854
971
|
` : "";
|
|
@@ -909,7 +1026,8 @@ band-check:
|
|
|
909
1026
|
- npx band check .
|
|
910
1027
|
`;
|
|
911
1028
|
}
|
|
912
|
-
function readme(packageName, title, template, name, scope) {
|
|
1029
|
+
function readme(packageName, title, template, name, scope, react) {
|
|
1030
|
+
const entry = react ? "src/index.tsx" : "src/index.ts";
|
|
913
1031
|
const place = template === "panel" ? `\`views.panels\`\uFF08\u672C\u4ED3\u5E93\u7684\u5939\u5177\u653E\u5728\u53F3\u680F\uFF1A\`${packageName}/main\`\uFF09` : template === "viewer" ? `\`views.artifactTypes.<\u4EA7\u7269\u7C7B\u578B>.viewer\`\uFF08\u672C\u4ED3\u5E93\u7684\u5939\u5177\u628A \`demo\` \u7ED1\u5230 \`${packageName}/${name}\`\uFF09` : "\u5F15\u7528\u5B83\u7684\u5DE5\u574A\u7684\u6D41\u7A0B\u9636\u6BB5\u8BE6\u60C5\u91CC";
|
|
914
1032
|
return `# ${packageName}
|
|
915
1033
|
|
|
@@ -921,7 +1039,8 @@ ${title}\uFF1A\u4E00\u4E2A\u72EC\u7ACB\u7684 Band \u63D2\u4EF6\uFF08\u4E0D\u5C5E
|
|
|
921
1039
|
|---|---|
|
|
922
1040
|
| \`package.json\` | \u8EAB\u4EFD\u4E0E\u7248\u672C\uFF1A\u5305\u540D\u3001\u534F\u8BAE\u8303\u56F4\uFF1BdevDependencies \u5E26 band \u547D\u4EE4\u884C\u4E0E\u63D2\u4EF6 SDK |
|
|
923
1041
|
| \`plugin.yaml\` | \u89C6\u56FE\u9762\u6E05\u5355\uFF1A\u5F80\u54EA\u4E9B\u63D2\u69FD\u8D21\u732E |
|
|
924
|
-
| \`
|
|
1042
|
+
| \`${entry}\` | \u5165\u53E3\uFF0C\u9ED8\u8BA4\u5BFC\u51FA \`definePlugin({ surfaces })\`${react ? "\uFF0C\u7528 `reactMount` \u6302 React \u7EC4\u4EF6" : ""} |
|
|
1043
|
+
| \`tsconfig.json\` | \`npm run typecheck\`\uFF08\`tsc --noEmit\`\uFF09\u7528\uFF1B\`band check\` \u4E0D\u67E5\u7C7B\u578B |
|
|
925
1044
|
| \`dev/workshop.yaml\` | \u672C\u5730\u5939\u5177\u5DE5\u574A\uFF1A\u6700\u5C0F\u5B9A\u4E49\uFF0C\u53EA\u7ED9 \`band dev\` / \`band check\` \u7528\uFF0C\u4E0D\u53D1\u5E03 |
|
|
926
1045
|
| \`dev/fixture.ts\` | \u5939\u5177\uFF1A\u793A\u4F8B\u4EA7\u7269\u3001\u7248\u672C\u4E0E\u6587\u4EF6 |
|
|
927
1046
|
| \`.gitlab-ci.yml\` | CI \u6A21\u677F\uFF1A\u73B0\u5728\u8DD1 \`band check\`\uFF1B\u5355\u6D4B\u3001\u9632\u6CC4\u9732\u626B\u63CF\u4E0E\u53D1\u5E03\u8FDB\u884C\u4E2D |
|
|
@@ -933,7 +1052,8 @@ ${title}\uFF1A\u4E00\u4E2A\u72EC\u7ACB\u7684 Band \u63D2\u4EF6\uFF08\u4E0D\u5C5E
|
|
|
933
1052
|
\`\`\`bash
|
|
934
1053
|
npm install # \u88C5\u4E0A devDependencies \u91CC\u7684 band \u547D\u4EE4\u884C\u4E0E\u63D2\u4EF6 SDK
|
|
935
1054
|
npx band dev . # \u7528 dev/ \u5939\u5177\u5DE5\u574A\u8D77\u9879\u76EE\u9875\uFF0C\u672C\u4ED3\u5E93\u7684\u63D2\u4EF6\u81EA\u52A8\u88C5\u4E0A
|
|
936
|
-
npx band check . # \u6821\u9A8C package.json\u3001plugin.yaml \u4E0E\u5939\u5177\u5DE5\u574A\u7684\u88C5\u914D
|
|
1055
|
+
npx band check . # \u6821\u9A8C package.json\u3001plugin.yaml \u4E0E\u5939\u5177\u5DE5\u574A\u7684\u88C5\u914D\uFF08\u4E0D\u67E5\u4EE3\u7801\u548C\u7C7B\u578B\uFF09
|
|
1056
|
+
npm run typecheck # tsc --noEmit \u67E5\u7C7B\u578B
|
|
937
1057
|
\`\`\`
|
|
938
1058
|
|
|
939
1059
|
## \u53D1\u5E03\uFF08\u8FDB\u884C\u4E2D\uFF09
|
|
@@ -1063,9 +1183,19 @@ var PUBLISH_LABELS = {
|
|
|
1063
1183
|
404: "\u5DE5\u574A\u4E0D\u5B58\u5728\uFF0C\u8BF7\u68C0\u67E5 --workshop id",
|
|
1064
1184
|
409: "\u53D1\u5E03\u51B2\u7A81\uFF0C\u8BF7\u786E\u8BA4\u5DE5\u574A\u53D1\u5E03\u5206\u652F\u7684\u63D0\u4EA4\u4E0E\u672C\u5730 HEAD \u4E00\u81F4"
|
|
1065
1185
|
};
|
|
1186
|
+
async function hasCredentialsFile() {
|
|
1187
|
+
try {
|
|
1188
|
+
await readFile(join5(homedir(), ".config", "band", "credentials.json"), "utf8");
|
|
1189
|
+
return true;
|
|
1190
|
+
} catch {
|
|
1191
|
+
return false;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1066
1194
|
async function connectBand(urlOption, failureLabels = PUBLISH_LABELS, needScope = "workshops:publish") {
|
|
1067
1195
|
let url = urlOption ?? process.env.BAND_URL;
|
|
1068
1196
|
let token = process.env.BAND_TOKEN;
|
|
1197
|
+
if (!url && !token && !await hasCredentialsFile())
|
|
1198
|
+
throw new PublishError("\u7F3A\u5C11\u670D\u52A1\u5730\u5740\uFF1A\u7528 --url <\u5730\u5740>\uFF08\u6216\u8BBE BAND_URL\uFF09\uFF0C\u5E76\u914D\u7F6E BAND_TOKEN");
|
|
1069
1199
|
if (!token) {
|
|
1070
1200
|
let saved;
|
|
1071
1201
|
try {
|
|
@@ -1087,11 +1217,11 @@ async function connectBand(urlOption, failureLabels = PUBLISH_LABELS, needScope
|
|
|
1087
1217
|
}
|
|
1088
1218
|
if (requestedOrigin && requestedOrigin !== savedOrigin)
|
|
1089
1219
|
throw new PublishError("\u76EE\u6807\u670D\u52A1\u4E0E\u7528\u6237\u51ED\u636E\u6587\u4EF6\u4E0D\u5339\u914D\uFF0C\u8BF7\u4E3A\u76EE\u6807\u670D\u52A1\u63D0\u4F9B BAND_TOKEN");
|
|
1090
|
-
url
|
|
1220
|
+
if (!url) url = saved.url;
|
|
1091
1221
|
token = saved.token;
|
|
1092
1222
|
}
|
|
1093
|
-
if (!url
|
|
1094
|
-
|
|
1223
|
+
if (!url) throw new PublishError("\u7F3A\u5C11\u670D\u52A1\u5730\u5740\uFF1A\u7528 --url <\u5730\u5740> \u6216\u8BBE BAND_URL");
|
|
1224
|
+
if (!token || /\s/.test(token)) throw new PublishError("\u8BF7\u914D\u7F6E\u5408\u6CD5\u7684 BAND_TOKEN");
|
|
1095
1225
|
let base;
|
|
1096
1226
|
try {
|
|
1097
1227
|
base = new URL(url);
|
|
@@ -1813,7 +1943,7 @@ var USAGE_BASE = `\u7528\u6CD5\uFF1A
|
|
|
1813
1943
|
band preview [\u5206\u652F\u6216\u63D0\u4EA4] [--url <Band \u670D\u52A1\u5730\u5740>] --workshop <id> [--project <\u9879\u76EE id>]
|
|
1814
1944
|
band dev [\u5DE5\u574A\u4ED3\u5E93\u76EE\u5F55 | \u72EC\u7ACB\u63D2\u4EF6\u4ED3\u5E93\u76EE\u5F55] [--port 5310] [--host 127.0.0.1]
|
|
1815
1945
|
band new plugin <\u540D> --template panel|viewer|stage-view [--stage <\u9636\u6BB5>] [--title <\u6807\u9898>] [--dir <\u5DE5\u574A\u4ED3\u5E93\u76EE\u5F55>]
|
|
1816
|
-
band new plugin-repo @<\u56E2\u961F>/<\u540D> --template panel|viewer|stage-view [--stage <\u9636\u6BB5>] [--title <\u6807\u9898>] [--dir <\u7236\u76EE\u5F55>]
|
|
1946
|
+
band new plugin-repo @<\u56E2\u961F>/<\u540D> --template panel|viewer|stage-view [--react] [--stage <\u9636\u6BB5>] [--title <\u6807\u9898>] [--dir <\u7236\u76EE\u5F55>]
|
|
1817
1947
|
band new workshop <\u76EE\u5F55> [--example video]
|
|
1818
1948
|
band new skill [--dir <\u4ED3\u5E93\u76EE\u5F55>]
|
|
1819
1949
|
band --version`;
|
|
@@ -1942,7 +2072,11 @@ async function main(argv) {
|
|
|
1942
2072
|
return 0;
|
|
1943
2073
|
}
|
|
1944
2074
|
if (cmd === "new") {
|
|
1945
|
-
const { args, flags } = parseArgs(
|
|
2075
|
+
const { args, flags } = parseArgs(
|
|
2076
|
+
rest,
|
|
2077
|
+
["template", "stage", "title", "dir"],
|
|
2078
|
+
["official", "react"]
|
|
2079
|
+
);
|
|
1946
2080
|
const [kind, name] = args;
|
|
1947
2081
|
if (kind !== "plugin" && kind !== "plugin-repo" || !name) {
|
|
1948
2082
|
console.error(usage());
|
|
@@ -1953,6 +2087,10 @@ async function main(argv) {
|
|
|
1953
2087
|
console.error(`--template \u53EA\u80FD\u662F ${PLUGIN_TEMPLATES.join(" | ")}`);
|
|
1954
2088
|
return 2;
|
|
1955
2089
|
}
|
|
2090
|
+
if (kind === "plugin" && flags.react) {
|
|
2091
|
+
console.error("--react \u53EA\u7528\u4E8E band new plugin-repo\uFF08\u5DE5\u574A\u4ED3\u5E93\u91CC\u7684\u63D2\u4EF6\u81EA\u5DF1\u5199 .tsx \u5165\u53E3\uFF09");
|
|
2092
|
+
return 2;
|
|
2093
|
+
}
|
|
1956
2094
|
if (kind === "plugin-repo") {
|
|
1957
2095
|
if (flags.official) {
|
|
1958
2096
|
console.error("--official \u53EA\u7528\u4E8E band new plugin\uFF1A\u72EC\u7ACB\u63D2\u4EF6\u4ED3\u5E93\u4E0D\u751F\u6210\u5B98\u65B9\u63D2\u4EF6");
|
|
@@ -1961,7 +2099,8 @@ async function main(argv) {
|
|
|
1961
2099
|
const r2 = newPluginRepo(flags.dir ?? ".", name, {
|
|
1962
2100
|
template,
|
|
1963
2101
|
...flags.stage ? { stage: flags.stage } : {},
|
|
1964
|
-
...flags.title ? { title: flags.title } : {}
|
|
2102
|
+
...flags.title ? { title: flags.title } : {},
|
|
2103
|
+
...flags.react ? { react: true } : {}
|
|
1965
2104
|
});
|
|
1966
2105
|
for (const f of r2.files) console.log(`\u2713 ${relative(flags.dir ?? ".", join7(r2.dir, f))}`);
|
|
1967
2106
|
for (const h of r2.hints) console.log(`\u4E0B\u4E00\u6B65\uFF1A${h}`);
|
|
@@ -1980,7 +2119,7 @@ async function main(argv) {
|
|
|
1980
2119
|
if (cmd === "dev") {
|
|
1981
2120
|
const { args, flags } = parseArgs(rest, ["port", "host"]);
|
|
1982
2121
|
const port = flags.port === void 0 ? void 0 : parsePort(flags.port);
|
|
1983
|
-
const { startDevServer } = await import("./dev-server-
|
|
2122
|
+
const { startDevServer } = await import("./dev-server-IBR3PKDE.js");
|
|
1984
2123
|
const server = await startDevServer(args[0] ?? ".", {
|
|
1985
2124
|
...port !== void 0 ? { port } : {},
|
|
1986
2125
|
...flags.host ? { host: flags.host } : {}
|