@appthen/vibe-workspace 0.1.0 → 0.1.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/PLUGIN_DEV.md +26 -0
- package/README.md +6 -0
- package/dist/{Workbench-Dhd6kXGh.js → Workbench-Bh2vD56R.js} +50 -14
- package/dist/{Workbench-Dhd6kXGh.js.map → Workbench-Bh2vD56R.js.map} +1 -1
- package/dist/{devWorkbench-BmYheR6S.js → devWorkbench-C-rC8sz8.js} +25 -4
- package/dist/devWorkbench-C-rC8sz8.js.map +1 -0
- package/dist/extension-cli/index.js +15 -11
- package/dist/extension-cli/index.js.map +1 -1
- package/dist/extension-dev/index.js +1 -1
- package/dist/extension-dev-workbench/index.js +12 -4
- package/dist/extension-dev-workbench/index.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/vibe-workspace/src/components/MonacoWrapper.d.ts +1 -1
- package/dist/vibe-workspace/src/extension-dev/types.d.ts +4 -0
- package/dist/vibe-workspace/src/extension-dev/workspace.d.ts +2 -0
- package/dist/vibe-workspace/src/services/themeService.d.ts +13 -0
- package/dist/vibe-workspace/src/workbench/types.d.ts +3 -0
- package/dist/workbench/index.js +1 -1
- package/package.json +1 -1
- package/dist/devWorkbench-BmYheR6S.js.map +0 -1
package/PLUGIN_DEV.md
CHANGED
|
@@ -24,6 +24,14 @@ pnpm dev
|
|
|
24
24
|
|
|
25
25
|
`pnpm install` 是首次准备依赖的步骤。依赖缓存准备好后,`dev`、`validate`、`test`、`build` 和 `pack` 不依赖 marketplace,可以离线完成。
|
|
26
26
|
|
|
27
|
+
如果同时修改 `@appthen/vibe-workspace` 本身,不要为了本地调试发布 npm。可以在 SDK 仓库运行 `pnpm run build:lib -- --watch`,然后从扩展工作区运行:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm dev -- --package-root /path/to/vibe-workspace
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`--package-root` 会让本地 Workbench、扩展构建和模板运行时使用指定目录的 `dist`。只有要交付给其他开发者时才发布 npm。
|
|
34
|
+
|
|
27
35
|
## 2. 工作区结构
|
|
28
36
|
|
|
29
37
|
```text
|
|
@@ -71,6 +79,7 @@ pnpm pack -- acme.example
|
|
|
71
79
|
"apiVersion": "1",
|
|
72
80
|
"main": "./src/index.tsx",
|
|
73
81
|
"sourceType": "umd",
|
|
82
|
+
"icon": "data:image/svg+xml,%3Csvg ...%3E%3C/svg%3E",
|
|
74
83
|
"runtime": {
|
|
75
84
|
"sidebarViewId": "sidebar.acme.example"
|
|
76
85
|
},
|
|
@@ -92,6 +101,23 @@ pnpm pack -- acme.example
|
|
|
92
101
|
- `runtime.sidebarViewId`:声明扩展侧边栏视图。
|
|
93
102
|
- `runtime.autoActivate`:只用于必须在 Workbench 启动时注册的扩展能力,普通扩展不要开启。
|
|
94
103
|
- `accessPolicy`:声明扩展自身的访问策略,会与租户和工作台策略合并。
|
|
104
|
+
- `icon`:侧边栏和移动端导航图标。v1 使用小型 `data:image/svg+xml` 或 HTTPS 图片 URL;暂不支持从扩展包引用相对路径静态资源。
|
|
105
|
+
|
|
106
|
+
图标建议使用不超过 32x32 的单色或双色 SVG data URL。需要多文件图片、字体或本地资源目录时,先上传到可信 CDN,再把 HTTPS URL 写入 Manifest;这样不会引入未定义的资源打包和 CDN 路径问题。
|
|
107
|
+
|
|
108
|
+
## 5.1 工作台主题
|
|
109
|
+
|
|
110
|
+
主题属于 Workbench 配置,不属于扩展激活副作用。离线工作区可以在 `themes/*.json` 定义主题,并在 `appthen-extension-workspace.json` 指定默认主题:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"devWorkbench": {
|
|
115
|
+
"theme": "acme.sales"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`pnpm dev` 会自动加载 `themes/` 下的 JSON。主题可通过 `extends` 继承 `vercel`、`dracula` 等内置主题;设置菜单中的主题替换会写入浏览器 localStorage,刷新后仍会保留。修改主题文件后重启 `pnpm dev` 以重新载入。
|
|
95
121
|
|
|
96
122
|
## 5. 编写扩展
|
|
97
123
|
|
package/README.md
CHANGED
|
@@ -30,6 +30,12 @@ appthen-extension publish [extensionId] --server <url> --tenant <tenantId>
|
|
|
30
30
|
appthen-extension install <package-file> --server <url> --tenant <tenantId>
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
开发 Workbench SDK 本身时,不需要发布 npm。先在 SDK 仓库执行 `pnpm run build:lib -- --watch`,再从扩展工作区指向本地 SDK:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm dev -- --package-root /path/to/vibe-workspace
|
|
37
|
+
```
|
|
38
|
+
|
|
33
39
|
`publish` uploads and updates the tenant extension record. It does not mount the extension into a Workbench unless `--install-tenant` is provided. Workbench mounting and permissions are configured separately.
|
|
34
40
|
|
|
35
41
|
## Stable Extension API
|
|
@@ -1159,21 +1159,26 @@ class ThemeService {
|
|
|
1159
1159
|
constructor() {
|
|
1160
1160
|
this.currentTheme = DraculaTheme;
|
|
1161
1161
|
this.listeners = [];
|
|
1162
|
+
this.customThemes = /* @__PURE__ */ new Map();
|
|
1162
1163
|
this.applyTheme(DraculaTheme);
|
|
1163
1164
|
}
|
|
1165
|
+
registerTheme(theme) {
|
|
1166
|
+
if (!(theme == null ? void 0 : theme.id) || !theme.label || !theme.colors || !theme.type) return false;
|
|
1167
|
+
this.customThemes.set(theme.id, theme);
|
|
1168
|
+
this.listeners.forEach((l) => l());
|
|
1169
|
+
return true;
|
|
1170
|
+
}
|
|
1171
|
+
registerThemes(themes) {
|
|
1172
|
+
let changed = false;
|
|
1173
|
+
themes.forEach((theme) => {
|
|
1174
|
+
if (this.registerThemeWithoutNotify(theme)) changed = true;
|
|
1175
|
+
});
|
|
1176
|
+
if (changed) this.listeners.forEach((l) => l());
|
|
1177
|
+
}
|
|
1164
1178
|
setTheme(themeId) {
|
|
1165
1179
|
console.log("[ThemeService] setTheme called with:", themeId);
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
} else if (themeId === "vercel") {
|
|
1169
|
-
this.applyTheme(VercelTheme);
|
|
1170
|
-
} else if (themeId === "appthen-light") {
|
|
1171
|
-
this.applyTheme(AppThenLightTheme);
|
|
1172
|
-
} else if (themeId === "vs-light") {
|
|
1173
|
-
this.applyTheme(LightTheme);
|
|
1174
|
-
} else {
|
|
1175
|
-
this.applyTheme(DarkTheme);
|
|
1176
|
-
}
|
|
1180
|
+
const theme = this.resolveTheme(themeId) || DarkTheme;
|
|
1181
|
+
this.applyTheme(theme);
|
|
1177
1182
|
}
|
|
1178
1183
|
setUserTheme(themeId) {
|
|
1179
1184
|
this.setTheme(themeId);
|
|
@@ -1193,7 +1198,30 @@ class ThemeService {
|
|
|
1193
1198
|
return this.currentTheme;
|
|
1194
1199
|
}
|
|
1195
1200
|
getAvailableThemes() {
|
|
1196
|
-
return [DraculaTheme, VercelTheme, AppThenLightTheme, DarkTheme, LightTheme];
|
|
1201
|
+
return [DraculaTheme, VercelTheme, AppThenLightTheme, DarkTheme, LightTheme, ...this.customThemes.values()].map((theme) => this.resolveTheme(theme.id) || theme);
|
|
1202
|
+
}
|
|
1203
|
+
registerThemeWithoutNotify(theme) {
|
|
1204
|
+
if (!(theme == null ? void 0 : theme.id) || !theme.label || !theme.colors || !theme.type) return false;
|
|
1205
|
+
const previous = this.customThemes.get(theme.id);
|
|
1206
|
+
this.customThemes.set(theme.id, theme);
|
|
1207
|
+
return JSON.stringify(previous) !== JSON.stringify(theme);
|
|
1208
|
+
}
|
|
1209
|
+
resolveTheme(themeId, seen = /* @__PURE__ */ new Set()) {
|
|
1210
|
+
var _a2, _b;
|
|
1211
|
+
const builtIn = [DraculaTheme, VercelTheme, AppThenLightTheme, DarkTheme, LightTheme].find((theme2) => theme2.id === themeId || themeId === "appthen" && theme2.id === "dracula" || themeId === "vs-light" && theme2.id === "light");
|
|
1212
|
+
const theme = builtIn || this.customThemes.get(themeId);
|
|
1213
|
+
if (!theme || seen.has(theme.id)) return theme;
|
|
1214
|
+
if (!theme.extends) return theme;
|
|
1215
|
+
seen.add(theme.id);
|
|
1216
|
+
const parent = this.resolveTheme(theme.extends, seen);
|
|
1217
|
+
if (!parent) return theme;
|
|
1218
|
+
return {
|
|
1219
|
+
...parent,
|
|
1220
|
+
...theme,
|
|
1221
|
+
colors: { ...parent.colors, ...theme.colors },
|
|
1222
|
+
portalColors: { ...parent.portalColors, ...theme.portalColors },
|
|
1223
|
+
monaco: { ...parent.monaco, ...theme.monaco, colors: { ...(_a2 = parent.monaco) == null ? void 0 : _a2.colors, ...(_b = theme.monaco) == null ? void 0 : _b.colors } }
|
|
1224
|
+
};
|
|
1197
1225
|
}
|
|
1198
1226
|
applyTheme(theme) {
|
|
1199
1227
|
this.currentTheme = theme;
|
|
@@ -136955,6 +136983,7 @@ function WorkbenchProvider({
|
|
|
136955
136983
|
var _a2, _b, _c, _d, _e2, _f, _g, _h;
|
|
136956
136984
|
const [state, dispatch2] = useReducer(workbenchReducer, initialState);
|
|
136957
136985
|
useEffect(() => {
|
|
136986
|
+
var _a3;
|
|
136958
136987
|
if (config) {
|
|
136959
136988
|
const resolvedConfig = config.scene || config.workbenchId !== "vibecoding" ? config : createVibeCodingWorkbenchConfig(config);
|
|
136960
136989
|
const resolvedExtensions = resolveRuntimeExtensions(resolvedConfig);
|
|
@@ -136968,6 +136997,9 @@ function WorkbenchProvider({
|
|
|
136968
136997
|
state.activeLeftExtensionId
|
|
136969
136998
|
)
|
|
136970
136999
|
});
|
|
137000
|
+
if ((_a3 = resolvedConfig.themeCatalog) == null ? void 0 : _a3.length) {
|
|
137001
|
+
themeService.registerThemes(resolvedConfig.themeCatalog);
|
|
137002
|
+
}
|
|
136971
137003
|
if (resolvedConfig.theme) {
|
|
136972
137004
|
const themeId = themeService.getPreferredThemeId() || resolvedConfig.theme;
|
|
136973
137005
|
console.log("[Workbench] Applying theme:", themeId);
|
|
@@ -137486,6 +137518,7 @@ function WorkbenchProvider({
|
|
|
137486
137518
|
const loadWorkbenchConfig = async () => {
|
|
137487
137519
|
console.log("[Workbench] Loading config for:", workbenchId);
|
|
137488
137520
|
const applyResolvedConfig = (resolvedConfig) => {
|
|
137521
|
+
var _a4;
|
|
137489
137522
|
if (activeWorkbenchConfigKeyRef.current !== configKey) return;
|
|
137490
137523
|
const resolvedExtensions = resolveRuntimeExtensions(resolvedConfig);
|
|
137491
137524
|
dispatch2({ type: "SET_WORKBENCH_CONFIG", payload: resolvedConfig });
|
|
@@ -137498,6 +137531,9 @@ function WorkbenchProvider({
|
|
|
137498
137531
|
state.activeLeftExtensionId
|
|
137499
137532
|
)
|
|
137500
137533
|
});
|
|
137534
|
+
if ((_a4 = resolvedConfig.themeCatalog) == null ? void 0 : _a4.length) {
|
|
137535
|
+
themeService.registerThemes(resolvedConfig.themeCatalog);
|
|
137536
|
+
}
|
|
137501
137537
|
if (resolvedConfig.theme) {
|
|
137502
137538
|
const themeId = themeService.getPreferredThemeId() || resolvedConfig.theme;
|
|
137503
137539
|
console.log("[Workbench] Applying theme:", themeId);
|
|
@@ -139503,7 +139539,7 @@ const WorkbenchSettingsMenu = ({
|
|
|
139503
139539
|
onClose
|
|
139504
139540
|
}) => {
|
|
139505
139541
|
const [currentTheme, setCurrentTheme] = useState(themeService.getCurrentTheme());
|
|
139506
|
-
const themes =
|
|
139542
|
+
const themes = themeService.getAvailableThemes();
|
|
139507
139543
|
useEffect(() => {
|
|
139508
139544
|
return themeService.onThemeChange(() => {
|
|
139509
139545
|
setCurrentTheme(themeService.getCurrentTheme());
|
|
@@ -140990,4 +141026,4 @@ export {
|
|
|
140990
141026
|
normalizeFileSrc as y,
|
|
140991
141027
|
previewService as z
|
|
140992
141028
|
};
|
|
140993
|
-
//# sourceMappingURL=Workbench-
|
|
141029
|
+
//# sourceMappingURL=Workbench-Bh2vD56R.js.map
|