@kanyun-ai-infra/band-cli 0.2.0 → 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/official/activity/package.json +1 -1
- package/bundled/official/approval/package.json +1 -1
- package/bundled/official/artifacts/package.json +1 -1
- package/bundled/official/chat/dist/index.js +1 -1
- package/bundled/official/chat/package.json +2 -2
- package/bundled/official/chunks/chunk-7XYETT7C.js +1 -0
- package/bundled/official/comment/package.json +1 -1
- package/bundled/official/header/package.json +1 -1
- package/bundled/official/home/dist/index.js +1 -1
- package/bundled/official/home/package.json +2 -2
- package/bundled/official/layouts/package.json +1 -1
- package/bundled/official/library/package.json +1 -1
- package/bundled/official/members/dist/index.js +1 -1
- package/bundled/official/members/package.json +2 -2
- package/bundled/official/memory/package.json +1 -1
- package/bundled/official/native/package.json +1 -1
- package/bundled/official/params-form/package.json +1 -1
- package/bundled/official/plugins/package.json +1 -1
- package/bundled/official/project/dist/index.js +1 -1
- package/bundled/official/project/package.json +2 -2
- package/bundled/official/queue/package.json +1 -1
- package/bundled/official/settings/dist/index.js +1 -1
- package/bundled/official/settings/package.json +2 -2
- package/bundled/official/shell/dist/index.js +1 -1
- package/bundled/official/shell/package.json +2 -2
- package/bundled/official/stages/package.json +1 -1
- package/bundled/official/threads/dist/index.js +1 -1
- package/bundled/official/threads/package.json +2 -2
- package/bundled/official/turn-bar/package.json +1 -1
- package/bundled/official/turn-trace/package.json +1 -1
- package/bundled/official/version-switch/dist/index.js +1 -1
- package/bundled/official/version-switch/package.json +1 -1
- package/bundled/official/viewer-entity/package.json +1 -1
- package/bundled/official/viewer-external/package.json +1 -1
- package/bundled/official/viewer-image/package.json +1 -1
- package/bundled/official/viewer-media/package.json +1 -1
- package/bundled/official/viewer-storyboard/package.json +1 -1
- package/bundled/official/viewer-text/package.json +1 -1
- package/bundled/official/viewer-tool/package.json +1 -1
- package/bundled/official/viewer-web/package.json +1 -1
- package/bundled/official/viewer-web-app/package.json +1 -1
- package/bundled/official/workshops/dist/index.js +2 -2
- package/bundled/official/workshops/package.json +2 -2
- package/bundled/tokens/components.css +1 -1
- package/dev-host/app.tsx +23 -7
- package/dev-host/host.css +7 -0
- package/dist/bin.js +1 -1
- package/dist/{chunk-Q2XJXNVH.js → chunk-FGPWXAOA.js} +151 -19
- package/dist/{dev-server-Q7NTJ3QD.js → dev-server-IBR3PKDE.js} +14 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/package.json +5 -4
- package/src/inspector-default.ts +9 -0
- package/bundled/official/chunks/chunk-DIL5YSVK.js +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanyun-ai-infra/band-workshops",
|
|
3
|
-
"version": "0.2.
|
|
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": "^2.
|
|
10
|
+
"@kanyun-ai-infra/band-plugin-sdk": "^2.1.0",
|
|
11
11
|
"react": "^19.0.0",
|
|
12
12
|
"react-dom": "^19.0.0",
|
|
13
13
|
"@kanyun-ai-infra/band-shell": "*"
|
|
@@ -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
|
@@ -35,6 +35,7 @@ import * as dev from "virtual:band-dev";
|
|
|
35
35
|
import { useEffect, useRef, useState } from "react";
|
|
36
36
|
import { createRoot } from "react-dom/client";
|
|
37
37
|
import { devManagers } from "../src/dev-managers.ts";
|
|
38
|
+
import { inspectorOpenByDefault } from "../src/inspector-default.ts";
|
|
38
39
|
import { DEV_HOST_PLUGIN } from "../src/inspector-plugins.ts";
|
|
39
40
|
import { loadPlugins } from "../src/load-plugins.ts";
|
|
40
41
|
import { Inspector } from "./Inspector.tsx";
|
|
@@ -316,6 +317,10 @@ function focusOf(s: Selection | null): string | undefined {
|
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
function App() {
|
|
320
|
+
// 夹具栏占 300px:视口不到 1600 默认收起,免得挤坏项目页右栏;收起时仍挂着,事件与诊断照常记
|
|
321
|
+
const [inspectorOpen, setInspectorOpen] = useState(() =>
|
|
322
|
+
inspectorOpenByDefault(window.innerWidth),
|
|
323
|
+
);
|
|
319
324
|
return (
|
|
320
325
|
<div className="dev-page">
|
|
321
326
|
<header className="dev-bar">
|
|
@@ -345,16 +350,27 @@ function App() {
|
|
|
345
350
|
) : (
|
|
346
351
|
<span className="chip plain">{member.displayName}</span>
|
|
347
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>
|
|
348
362
|
</header>
|
|
349
363
|
<div className="dev-body">
|
|
350
364
|
<ProjectPage />
|
|
351
|
-
<
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
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>
|
|
358
374
|
</div>
|
|
359
375
|
</div>
|
|
360
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
|
@@ -646,7 +646,7 @@ import { parse } from "yaml";
|
|
|
646
646
|
// package.json
|
|
647
647
|
var package_default = {
|
|
648
648
|
name: "@kanyun-ai-infra/band-cli",
|
|
649
|
-
version: "0.2.
|
|
649
|
+
version: "0.2.1",
|
|
650
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",
|
|
651
651
|
license: "UNLICENSED",
|
|
652
652
|
type: "module",
|
|
@@ -742,11 +742,13 @@ function newPluginRepo(parentDir, packageName, opts) {
|
|
|
742
742
|
const title = opts.title ?? name;
|
|
743
743
|
const dir = join2(resolve2(parentDir), name);
|
|
744
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";
|
|
745
747
|
const rendered = renderPluginTemplate(opts.template, {
|
|
746
748
|
title,
|
|
747
749
|
...opts.stage ? { stage: opts.stage } : {},
|
|
748
750
|
id: name,
|
|
749
|
-
entry:
|
|
751
|
+
entry: `./${entryFile}`
|
|
750
752
|
});
|
|
751
753
|
const workshop = fixtureWorkshop(packageName, opts.template, name, opts.stage);
|
|
752
754
|
try {
|
|
@@ -757,14 +759,16 @@ function newPluginRepo(parentDir, packageName, opts) {
|
|
|
757
759
|
);
|
|
758
760
|
}
|
|
759
761
|
const files = {
|
|
760
|
-
"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)}
|
|
761
765
|
`,
|
|
762
766
|
"plugin.yaml": rendered.manifest,
|
|
763
|
-
|
|
767
|
+
[entryFile]: react ? reactSource(opts.template, title, opts.stage, name) : rendered.code,
|
|
764
768
|
"dev/workshop.yaml": workshop,
|
|
765
769
|
"dev/fixture.ts": fixtureSource(opts.template, opts.stage),
|
|
766
770
|
".gitlab-ci.yml": CI(packageName),
|
|
767
|
-
"README.md": readme(packageName, title, opts.template, name, parsed.scope),
|
|
771
|
+
"README.md": readme(packageName, title, opts.template, name, parsed.scope, react),
|
|
768
772
|
".gitignore": "node_modules/\ndist/\n"
|
|
769
773
|
};
|
|
770
774
|
for (const [f, body] of Object.entries(files)) {
|
|
@@ -778,7 +782,8 @@ function newPluginRepo(parentDir, packageName, opts) {
|
|
|
778
782
|
hints: [
|
|
779
783
|
`cd ${dir} && npm install\uFF1A\u88C5\u4E0A band \u547D\u4EE4\u884C\u4E0E\u63D2\u4EF6 SDK\uFF08devDependencies\uFF09`,
|
|
780
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",
|
|
781
|
-
"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",
|
|
782
787
|
placementHint(opts.template, packageName, name, opts.stage),
|
|
783
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"
|
|
784
789
|
]
|
|
@@ -791,7 +796,7 @@ function placementHint(template, packageName, name, stage) {
|
|
|
791
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`;
|
|
792
797
|
}
|
|
793
798
|
var PROJECT2 = "@kanyun-ai-infra/band-project";
|
|
794
|
-
function packageJson(packageName, title) {
|
|
799
|
+
function packageJson(packageName, title, react) {
|
|
795
800
|
return {
|
|
796
801
|
name: packageName,
|
|
797
802
|
version: "0.1.0",
|
|
@@ -799,7 +804,7 @@ function packageJson(packageName, title) {
|
|
|
799
804
|
license: "UNLICENSED",
|
|
800
805
|
type: "module",
|
|
801
806
|
files: ["src", "plugin.yaml", "README.md"],
|
|
802
|
-
scripts: { dev: "band dev .", check: "band check ." },
|
|
807
|
+
scripts: { dev: "band dev .", check: "band check .", typecheck: "tsc --noEmit" },
|
|
803
808
|
peerDependencies: {
|
|
804
809
|
react: "^19.0.0",
|
|
805
810
|
"react-dom": "^19.0.0",
|
|
@@ -809,10 +814,36 @@ function packageJson(packageName, title) {
|
|
|
809
814
|
peerDependenciesMeta: { [PROJECT2]: { optional: true } },
|
|
810
815
|
devDependencies: {
|
|
811
816
|
"@kanyun-ai-infra/band-cli": `^${CLI_VERSION}`,
|
|
812
|
-
"@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
|
+
} : {}
|
|
813
827
|
}
|
|
814
828
|
};
|
|
815
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
|
+
}
|
|
816
847
|
function fixtureWorkshop(packageName, template, name, stage) {
|
|
817
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
|
|
818
849
|
# \u672C\u4ED3\u5E93\u7684\u63D2\u4EF6\u7531\u547D\u4EE4\u76F4\u63A5\u88C5\u4E0A\uFF0C\u4E0D\u7528\u5199\u8FDB views.plugins\u3002
|
|
@@ -856,6 +887,85 @@ views:
|
|
|
856
887
|
`;
|
|
857
888
|
}
|
|
858
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
|
+
}
|
|
859
969
|
function fixtureSource(template, stage) {
|
|
860
970
|
const stages = template === "stage-view" ? ` stages: [{ stage: ${q2(stage ?? "")}, status: "ready" }],
|
|
861
971
|
` : "";
|
|
@@ -916,7 +1026,8 @@ band-check:
|
|
|
916
1026
|
- npx band check .
|
|
917
1027
|
`;
|
|
918
1028
|
}
|
|
919
|
-
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";
|
|
920
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";
|
|
921
1032
|
return `# ${packageName}
|
|
922
1033
|
|
|
@@ -928,7 +1039,8 @@ ${title}\uFF1A\u4E00\u4E2A\u72EC\u7ACB\u7684 Band \u63D2\u4EF6\uFF08\u4E0D\u5C5E
|
|
|
928
1039
|
|---|---|
|
|
929
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 |
|
|
930
1041
|
| \`plugin.yaml\` | \u89C6\u56FE\u9762\u6E05\u5355\uFF1A\u5F80\u54EA\u4E9B\u63D2\u69FD\u8D21\u732E |
|
|
931
|
-
| \`
|
|
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 |
|
|
932
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 |
|
|
933
1045
|
| \`dev/fixture.ts\` | \u5939\u5177\uFF1A\u793A\u4F8B\u4EA7\u7269\u3001\u7248\u672C\u4E0E\u6587\u4EF6 |
|
|
934
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 |
|
|
@@ -940,7 +1052,8 @@ ${title}\uFF1A\u4E00\u4E2A\u72EC\u7ACB\u7684 Band \u63D2\u4EF6\uFF08\u4E0D\u5C5E
|
|
|
940
1052
|
\`\`\`bash
|
|
941
1053
|
npm install # \u88C5\u4E0A devDependencies \u91CC\u7684 band \u547D\u4EE4\u884C\u4E0E\u63D2\u4EF6 SDK
|
|
942
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
|
|
943
|
-
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
|
|
944
1057
|
\`\`\`
|
|
945
1058
|
|
|
946
1059
|
## \u53D1\u5E03\uFF08\u8FDB\u884C\u4E2D\uFF09
|
|
@@ -1070,9 +1183,19 @@ var PUBLISH_LABELS = {
|
|
|
1070
1183
|
404: "\u5DE5\u574A\u4E0D\u5B58\u5728\uFF0C\u8BF7\u68C0\u67E5 --workshop id",
|
|
1071
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"
|
|
1072
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
|
+
}
|
|
1073
1194
|
async function connectBand(urlOption, failureLabels = PUBLISH_LABELS, needScope = "workshops:publish") {
|
|
1074
1195
|
let url = urlOption ?? process.env.BAND_URL;
|
|
1075
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");
|
|
1076
1199
|
if (!token) {
|
|
1077
1200
|
let saved;
|
|
1078
1201
|
try {
|
|
@@ -1094,11 +1217,11 @@ async function connectBand(urlOption, failureLabels = PUBLISH_LABELS, needScope
|
|
|
1094
1217
|
}
|
|
1095
1218
|
if (requestedOrigin && requestedOrigin !== savedOrigin)
|
|
1096
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");
|
|
1097
|
-
url
|
|
1220
|
+
if (!url) url = saved.url;
|
|
1098
1221
|
token = saved.token;
|
|
1099
1222
|
}
|
|
1100
|
-
if (!url
|
|
1101
|
-
|
|
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");
|
|
1102
1225
|
let base;
|
|
1103
1226
|
try {
|
|
1104
1227
|
base = new URL(url);
|
|
@@ -1820,7 +1943,7 @@ var USAGE_BASE = `\u7528\u6CD5\uFF1A
|
|
|
1820
1943
|
band preview [\u5206\u652F\u6216\u63D0\u4EA4] [--url <Band \u670D\u52A1\u5730\u5740>] --workshop <id> [--project <\u9879\u76EE id>]
|
|
1821
1944
|
band dev [\u5DE5\u574A\u4ED3\u5E93\u76EE\u5F55 | \u72EC\u7ACB\u63D2\u4EF6\u4ED3\u5E93\u76EE\u5F55] [--port 5310] [--host 127.0.0.1]
|
|
1822
1945
|
band new plugin <\u540D> --template panel|viewer|stage-view [--stage <\u9636\u6BB5>] [--title <\u6807\u9898>] [--dir <\u5DE5\u574A\u4ED3\u5E93\u76EE\u5F55>]
|
|
1823
|
-
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>]
|
|
1824
1947
|
band new workshop <\u76EE\u5F55> [--example video]
|
|
1825
1948
|
band new skill [--dir <\u4ED3\u5E93\u76EE\u5F55>]
|
|
1826
1949
|
band --version`;
|
|
@@ -1949,7 +2072,11 @@ async function main(argv) {
|
|
|
1949
2072
|
return 0;
|
|
1950
2073
|
}
|
|
1951
2074
|
if (cmd === "new") {
|
|
1952
|
-
const { args, flags } = parseArgs(
|
|
2075
|
+
const { args, flags } = parseArgs(
|
|
2076
|
+
rest,
|
|
2077
|
+
["template", "stage", "title", "dir"],
|
|
2078
|
+
["official", "react"]
|
|
2079
|
+
);
|
|
1953
2080
|
const [kind, name] = args;
|
|
1954
2081
|
if (kind !== "plugin" && kind !== "plugin-repo" || !name) {
|
|
1955
2082
|
console.error(usage());
|
|
@@ -1960,6 +2087,10 @@ async function main(argv) {
|
|
|
1960
2087
|
console.error(`--template \u53EA\u80FD\u662F ${PLUGIN_TEMPLATES.join(" | ")}`);
|
|
1961
2088
|
return 2;
|
|
1962
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
|
+
}
|
|
1963
2094
|
if (kind === "plugin-repo") {
|
|
1964
2095
|
if (flags.official) {
|
|
1965
2096
|
console.error("--official \u53EA\u7528\u4E8E band new plugin\uFF1A\u72EC\u7ACB\u63D2\u4EF6\u4ED3\u5E93\u4E0D\u751F\u6210\u5B98\u65B9\u63D2\u4EF6");
|
|
@@ -1968,7 +2099,8 @@ async function main(argv) {
|
|
|
1968
2099
|
const r2 = newPluginRepo(flags.dir ?? ".", name, {
|
|
1969
2100
|
template,
|
|
1970
2101
|
...flags.stage ? { stage: flags.stage } : {},
|
|
1971
|
-
...flags.title ? { title: flags.title } : {}
|
|
2102
|
+
...flags.title ? { title: flags.title } : {},
|
|
2103
|
+
...flags.react ? { react: true } : {}
|
|
1972
2104
|
});
|
|
1973
2105
|
for (const f of r2.files) console.log(`\u2713 ${relative(flags.dir ?? ".", join7(r2.dir, f))}`);
|
|
1974
2106
|
for (const h of r2.hints) console.log(`\u4E0B\u4E00\u6B65\uFF1A${h}`);
|
|
@@ -1987,7 +2119,7 @@ async function main(argv) {
|
|
|
1987
2119
|
if (cmd === "dev") {
|
|
1988
2120
|
const { args, flags } = parseArgs(rest, ["port", "host"]);
|
|
1989
2121
|
const port = flags.port === void 0 ? void 0 : parsePort(flags.port);
|
|
1990
|
-
const { startDevServer } = await import("./dev-server-
|
|
2122
|
+
const { startDevServer } = await import("./dev-server-IBR3PKDE.js");
|
|
1991
2123
|
const server = await startDevServer(args[0] ?? ".", {
|
|
1992
2124
|
...port !== void 0 ? { port } : {},
|
|
1993
2125
|
...flags.host ? { host: flags.host } : {}
|
|
@@ -194,9 +194,21 @@ function heartbeatPlugin(ms) {
|
|
|
194
194
|
function bandDevPlugin(root, initial) {
|
|
195
195
|
let ws = initial;
|
|
196
196
|
let server;
|
|
197
|
+
const seenPackageJsons = /* @__PURE__ */ new Set();
|
|
198
|
+
const pluginPackageJsons = () => {
|
|
199
|
+
for (const p of ws.plugins) seenPackageJsons.add(join(dirname(p.manifestPath), "package.json"));
|
|
200
|
+
for (const path of seenPackageJsons)
|
|
201
|
+
if (!existsSync(path)) {
|
|
202
|
+
seenPackageJsons.delete(path);
|
|
203
|
+
server?.watcher.unwatch(path);
|
|
204
|
+
}
|
|
205
|
+
return [...seenPackageJsons];
|
|
206
|
+
};
|
|
207
|
+
const isViewPackageJson = (file) => /[\\/]band[\\/]views[\\/][^\\/]+[\\/]package\.json$/.test(file);
|
|
197
208
|
const yamls = () => [
|
|
198
209
|
ws.workshopPath,
|
|
199
210
|
...ws.plugins.map((p) => p.manifestPath),
|
|
211
|
+
...pluginPackageJsons(),
|
|
200
212
|
...ws.paramsPaths
|
|
201
213
|
];
|
|
202
214
|
return {
|
|
@@ -215,7 +227,8 @@ function bandDevPlugin(root, initial) {
|
|
|
215
227
|
s.watcher.add(yamls());
|
|
216
228
|
s.watcher.on("all", (_event, file) => {
|
|
217
229
|
if (!file.startsWith(root)) return;
|
|
218
|
-
if (!file.endsWith(".yaml") && !ws.paramsPaths.includes(file))
|
|
230
|
+
if (!file.endsWith(".yaml") && !ws.paramsPaths.includes(file) && !pluginPackageJsons().includes(file) && !isViewPackageJson(file))
|
|
231
|
+
return;
|
|
219
232
|
const mod = s.moduleGraph.getModuleById(RESOLVED);
|
|
220
233
|
if (mod) s.moduleGraph.invalidateModule(mod);
|
|
221
234
|
s.ws.send({ type: "full-reload" });
|
package/dist/index.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ interface NewPluginRepoOptions {
|
|
|
33
33
|
stage?: string;
|
|
34
34
|
/** 界面上的标题,缺省用插件名。 */
|
|
35
35
|
title?: string;
|
|
36
|
+
/** 用 React 写:入口是 `src/index.tsx`,package.json 带 React 与 `band-plugin-react` 的开发依赖,tsconfig 开 JSX。 */
|
|
37
|
+
react?: boolean;
|
|
36
38
|
}
|
|
37
39
|
interface NewPluginRepoResult {
|
|
38
40
|
/** 仓库目录(`<父目录>/<名>`)。 */
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanyun-ai-infra/band-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "band 命令行:新建、本地调试、校验与发布 Band 工坊和插件",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"dist",
|
|
36
36
|
"dev-host",
|
|
37
37
|
"src/dev-managers.ts",
|
|
38
|
+
"src/inspector-default.ts",
|
|
38
39
|
"src/inspector-plugins.ts",
|
|
39
40
|
"src/load-plugins.ts",
|
|
40
41
|
"bundled"
|
|
@@ -43,9 +44,9 @@
|
|
|
43
44
|
"node": ">=22.19"
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
46
|
-
"@kanyun-ai-infra/band-contracts": "^0.1.
|
|
47
|
-
"@kanyun-ai-infra/band-plugin-react": "^0.2.
|
|
48
|
-
"@kanyun-ai-infra/band-plugin-sdk": "^2.
|
|
47
|
+
"@kanyun-ai-infra/band-contracts": "^0.1.4",
|
|
48
|
+
"@kanyun-ai-infra/band-plugin-react": "^0.2.1",
|
|
49
|
+
"@kanyun-ai-infra/band-plugin-sdk": "^2.1.0",
|
|
49
50
|
"es-module-lexer": "^2.3.2",
|
|
50
51
|
"react": "^19.3.1",
|
|
51
52
|
"react-dom": "^19.3.1",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `band dev` 右边「夹具」栏默认展开的最小视口宽度(像素):不到这个宽度项目页的右栏会被夹具栏挤得显示不全,
|
|
3
|
+
* 默认收起,作者点「夹具」按钮展开。quickstart 写的「不到 1600 像素右栏显示不全」是同一个数。
|
|
4
|
+
*/
|
|
5
|
+
export const INSPECTOR_OPEN_MIN_WIDTH = 1600;
|
|
6
|
+
|
|
7
|
+
export function inspectorOpenByDefault(viewportWidth: number): boolean {
|
|
8
|
+
return viewportWidth >= INSPECTOR_OPEN_MIN_WIDTH;
|
|
9
|
+
}
|