@zhama/tego-plugin-sdk 1.40.0 → 1.40.2

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.
@@ -79,29 +79,29 @@ export default definePluginFrontend({
79
79
 
80
80
  ### 宿主上下文
81
81
 
82
- | 成员 | 参数或返回值 | 用途与约束 |
83
- | -------------------------------------- | -------------------------------------------- | --------------------------------------------------------------- |
84
- | `ctx.pluginId`、`ctx.basePath` | 字符串 | 当前插件 ID、宿主内页面前缀 |
85
- | `ctx.user` | `userId`、`tenantId`、`roles`、`displayName` | 当前用户;业务权限使用 access SDK,不根据宿主角色名自行判断 |
86
- | `ctx.activeAvatar?` | `{ id, name }` | 当前选中的数字员工;用于界面上下文,不能作为机器身份或授权证明 |
87
- | `ctx.delegation?` | `current`、`subscribe`、`open` | 宿主统一的工作授权状态与授权对话框;见下文「工作授权」 |
88
- | `ctx.config` | `Record<string, unknown>` | 仅前端配置,已应用默认值;不包含后端和 Claw 配置或秘密 |
89
- | `ctx.api.request(path, init?)` | `Promise<Response>` | 自动附加认证,路径相对当前插件后端命名空间 |
90
- | `ctx.api.json<T>(path, init?)` | `Promise<T>` | JSON 请求;非 2xx 会抛错 |
91
- | `ctx.route.current()` | `{ path, search }` | 当前插件内路径及带 `?` 的查询串 |
92
- | `ctx.route.subscribe(listener)` | 取消订阅函数 | 监听宿主导航;可接入 `useSyncExternalStore` |
93
- | `ctx.navigate(to)` | 宿主路径 | 在宿主内导航,支持绝对宿主路径 |
94
- | `ctx.can(navKey)` | `boolean` | 是否为 manifest 声明的导航 key;不替代资源授权 |
95
- | `ctx.publicPagesUrl` | 以 `/` 结尾的绝对地址 | 构建公开页面链接或二维码;未声明公开前端时访问返回 404 |
96
- | `ctx.hostUrl(path)` | 绝对地址 | 将宿主签发的上传/下载路径转换为浏览器可访问地址 |
97
- | `ctx.layout.collapseSidebar()` | 恢复函数 | 收起宿主导航侧栏;页面结束使用时调用返回函数 |
98
- | `ctx.events.subscribe(listener)` | 取消订阅函数 | 接收 `{ name, payload, timestamp }`,名称已去掉插件命名空间前缀 |
99
- | `ctx.events.connected()` | `boolean` | 查询事件连接状态 |
100
- | `ctx.events.subscribeStatus(listener)` | 取消订阅函数 | 监听事件连接状态变化 |
101
- | `ctx.platform?` | `'web' \| 'desktop'` | 1.37;运行的壳。代码应在两端都正确,不要据此分叉业务逻辑 |
102
- | `ctx.openExternal?(url)` | `Promise<void>` | 1.37;在系统浏览器(桌面端)或新标签页(web)打开外部链接 |
103
- | `ctx.download?({ path \| blob, fileName })` | `Promise<void>` | 1.37;保存宿主路径或页面生成的文件;桌面端弹出原生保存对话框 |
104
- | `ctx.copyText?(text)` | `Promise<boolean>` | 1.37;复制到剪贴板,壳拒绝时返回 `false` |
82
+ | 成员 | 参数或返回值 | 用途与约束 |
83
+ | ------------------------------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------- |
84
+ | `ctx.pluginId`、`ctx.basePath` | 字符串 | 当前插件 ID、宿主内页面前缀 |
85
+ | `ctx.user` | `userId`、`tenantId`、`roles`、`displayName` | 当前用户;业务权限使用 access SDK,不根据宿主角色名自行判断 |
86
+ | `ctx.activeAvatar?` | `{ id, name }` | 当前选中的数字员工;用于界面上下文,不能作为机器身份或授权证明 |
87
+ | `ctx.delegation?` | `current`、`subscribe`、`open` | 宿主统一的工作授权状态与授权对话框;见下文「工作授权」 |
88
+ | `ctx.config` | `Record<string, unknown>` | 仅前端配置,已应用默认值;不包含后端和 Claw 配置或秘密 |
89
+ | `ctx.api.request(path, init?)` | `Promise<Response>` | 自动附加认证,路径相对当前插件后端命名空间 |
90
+ | `ctx.api.json<T>(path, init?)` | `Promise<T>` | JSON 请求;非 2xx 会抛错 |
91
+ | `ctx.route.current()` | `{ path, search }` | 当前插件内路径及带 `?` 的查询串 |
92
+ | `ctx.route.subscribe(listener)` | 取消订阅函数 | 监听宿主导航;可接入 `useSyncExternalStore` |
93
+ | `ctx.navigate(to)` | 宿主路径 | 在宿主内导航,支持绝对宿主路径 |
94
+ | `ctx.can(navKey)` | `boolean` | 是否为 manifest 声明的导航 key;不替代资源授权 |
95
+ | `ctx.publicPagesUrl` | 以 `/` 结尾的绝对地址 | 构建公开页面链接或二维码;未声明公开前端时访问返回 404 |
96
+ | `ctx.hostUrl(path)` | 绝对地址 | 将宿主签发的上传/下载路径转换为浏览器可访问地址 |
97
+ | `ctx.layout.collapseSidebar()` | 恢复函数 | 收起宿主导航侧栏;页面结束使用时调用返回函数。导航已是固定图标栏,宿主按空操作处理 |
98
+ | `ctx.events.subscribe(listener)` | 取消订阅函数 | 接收 `{ name, payload, timestamp }`,名称已去掉插件命名空间前缀 |
99
+ | `ctx.events.connected()` | `boolean` | 查询事件连接状态 |
100
+ | `ctx.events.subscribeStatus(listener)` | 取消订阅函数 | 监听事件连接状态变化 |
101
+ | `ctx.platform?` | `'web' \| 'desktop'` | 1.37;运行的壳。代码应在两端都正确,不要据此分叉业务逻辑 |
102
+ | `ctx.openExternal?(url)` | `Promise<void>` | 1.37;在系统浏览器(桌面端)或新标签页(web)打开外部链接 |
103
+ | `ctx.download?({ path \| blob, fileName })` | `Promise<void>` | 1.37;保存宿主路径或页面生成的文件;桌面端弹出原生保存对话框 |
104
+ | `ctx.copyText?(text)` | `Promise<boolean>` | 1.37;复制到剪贴板,壳拒绝时返回 `false` |
105
105
 
106
106
  web 与桌面端(Tauri)的差异:桌面端 CSP 不允许 `eval`/`new Function`/`blob:` 脚本,`location.origin` 是 `tauri://localhost`,`ctx.api` 经 Rust 代理整包缓冲(上限 100 MB),`window.open` 与 `<a download>` 不可靠;web 端 CSP 只允许连接平台。外链、下载、复制请用上面 1.37 的能力,详见 SDK 的 `agent/guides/desktop-web.md`。
107
107
 
@@ -306,11 +306,11 @@ await ctx.office?.open({
306
306
 
307
307
  ### 来源与工作委托
308
308
 
309
- | API | 输入 | 返回值与约束 |
310
- | -------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------- |
311
- | `host.sources?.read(id, actor)` | `actor: { userId, avatarId, metadataOnly? }` | `{ source: unknown }`;宿主复核来源归属、源数据是否存在、捕获授权 |
309
+ | API | 输入 | 返回值与约束 |
310
+ | ---------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
311
+ | `host.sources?.read(id, actor)` | `actor: { userId, avatarId, metadataOnly? }` | `{ source: unknown }`;宿主复核来源归属、源数据是否存在、捕获授权 |
312
312
  | `host.sources?.latestUserMessage(input)` | `{ topicId, userId, avatarId }`,需在 manifest 声明 `messages.latest_user` | `{ message: { id, topicId, origin, content, createdAt } \| null }`;只返回此人在该话题的最新一条。`origin` 由宿主写入,只有 `typed`、`voice` 是本人原话,其他值或 `null` 都不是;超过 200 字时 `content` 为空 |
313
- | `host.delegations?.list(userId)` | 用户 ID | `{ delegations: [{ avatarId, enabled, actions }] }`;当前安装的工作委托,用于转交工作前复核 |
313
+ | `host.delegations?.list(userId)` | 用户 ID | `{ delegations: [{ avatarId, enabled, actions }] }`;当前安装的工作委托,用于转交工作前复核 |
314
314
 
315
315
  `sources.read` 读取平台已授权捕获的来源,不是任意会话查询接口。`delegations.list` 只查询,不能创建或扩张委托;来源捕获、会话绑定和委托管理的其他平台 REST 接口不在 `PluginHostApi` 方法列表中。
316
316
 
@@ -524,28 +524,28 @@ Python FastAPI 的路由以 `dependencies=[policy.permission(...)]` 等方式挂
524
524
 
525
525
  以下是常用能力的版本节点。新插件采用权限目录时直接声明 `^1.22.0`;兼容旧宿主时,声明所需最低版本并检测可选成员。
526
526
 
527
- | Host API | 常用新增能力 |
528
- | -------- | -------------------------------------------------- |
529
- | 1.1.0 | ChatSurface、话题创建 metadata |
530
- | 1.2.0 | 前端路由 store、用户显示名 |
531
- | 1.3.0 | 前端插件事件流 |
532
- | 1.4.0 | 插件配置 |
533
- | 1.5.0 | directory |
534
- | 1.6.0 | knowledge 引用核验 |
535
- | 1.7.0 | 权威来源段落引用 |
536
- | 1.9.0 | 通用 AI 表单填写 |
537
- | 1.10.0 | Python 后端、出站声明、公开路由/页面、插件知识集合 |
538
- | 1.12.0 | 大对象上传路径、文件头读取、浏览器 hostUrl |
539
- | 1.14.0 | 前端侧栏收起请求 |
540
- | 1.15.0 | 受管下载 |
541
- | 1.17.0 | 直接注册普通用户 |
542
- | 1.18.0 | 普通账号密码重置 |
543
- | 1.19.0 | 存储复制与流式传输 |
544
- | 1.20.0 | Mermaid 与 HTML 图表渲染 |
545
- | 1.21.0 | 前端 Office 产物打开 |
546
- | 1.22.0 | 插件权限目录、access SDK、后端 tenantId |
547
- | 1.26.0 | `proactive.emit` 事件触发任务 |
548
- | 1.27.0 | AI 草稿可配置执行预算 `timeoutMs` |
527
+ | Host API | 常用新增能力 |
528
+ | -------- | ------------------------------------------------------------------------------- |
529
+ | 1.1.0 | ChatSurface、话题创建 metadata |
530
+ | 1.2.0 | 前端路由 store、用户显示名 |
531
+ | 1.3.0 | 前端插件事件流 |
532
+ | 1.4.0 | 插件配置 |
533
+ | 1.5.0 | directory |
534
+ | 1.6.0 | knowledge 引用核验 |
535
+ | 1.7.0 | 权威来源段落引用 |
536
+ | 1.9.0 | 通用 AI 表单填写 |
537
+ | 1.10.0 | Python 后端、出站声明、公开路由/页面、插件知识集合 |
538
+ | 1.12.0 | 大对象上传路径、文件头读取、浏览器 hostUrl |
539
+ | 1.14.0 | 前端侧栏收起请求 |
540
+ | 1.15.0 | 受管下载 |
541
+ | 1.17.0 | 直接注册普通用户 |
542
+ | 1.18.0 | 普通账号密码重置 |
543
+ | 1.19.0 | 存储复制与流式传输 |
544
+ | 1.20.0 | Mermaid 与 HTML 图表渲染 |
545
+ | 1.21.0 | 前端 Office 产物打开 |
546
+ | 1.22.0 | 插件权限目录、access SDK、后端 tenantId |
547
+ | 1.26.0 | `proactive.emit` 事件触发任务 |
548
+ | 1.27.0 | AI 草稿可配置执行预算 `timeoutMs` |
549
549
  | 1.37.0 | 前端 `platform`、`openExternal`、`download`、`copyText`(web 与桌面端行为一致) |
550
550
 
551
551
  ## 能力边界与相关文档
@@ -231,7 +231,12 @@ interface PluginHostContext {
231
231
  };
232
232
  /** Shell layout requests are scoped to this frontend mount. */
233
233
  layout: {
234
- /** Collapse the host navigation sidebar. Call the returned function when the page is done. */
234
+ /**
235
+ * Ask the host navigation to yield width. Call the returned function when
236
+ * the page is done. Since the navigation became a fixed icon rail there is
237
+ * nothing left to fold, so the host treats it as a no-op; keep calling it,
238
+ * the contract is unchanged.
239
+ */
235
240
  collapseSidebar(): () => void;
236
241
  };
237
242
  /** Selected avatar, isolated run without chat delivery or tools. Drafts require normal API validation before saving. */
@@ -231,7 +231,12 @@ interface PluginHostContext {
231
231
  };
232
232
  /** Shell layout requests are scoped to this frontend mount. */
233
233
  layout: {
234
- /** Collapse the host navigation sidebar. Call the returned function when the page is done. */
234
+ /**
235
+ * Ask the host navigation to yield width. Call the returned function when
236
+ * the page is done. Since the navigation became a fixed icon rail there is
237
+ * nothing left to fold, so the host treats it as a no-op; keep calling it,
238
+ * the contract is unchanged.
239
+ */
235
240
  collapseSidebar(): () => void;
236
241
  };
237
242
  /** Selected avatar, isolated run without chat delivery or tools. Drafts require normal API validation before saving. */
package/dist/publish.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var $=Object.defineProperty;var s=(e,a)=>$(e,"name",{value:a,configurable:!0});var chunkQQOUNXLC_cjs=require("./chunk-QQOUNXLC.cjs");require("./chunk-6EKQMOYT.cjs"),require("./chunk-H6GXDFLP.cjs"),require("./chunk-45Y4CR4R.cjs");var chunk2P6UEAPV_cjs=require("./chunk-2P6UEAPV.cjs");require("./chunk-N4SXZZPY.cjs"),require("./chunk-IOZFHJ4F.cjs"),require("./chunk-AJY7ZHXK.cjs"),require("./chunk-OP64Y4IN.cjs");var promises=require("fs/promises"),path=require("path"),API_PREFIX="/api/v1/tego-os";async function publishPlugin(e){const a=e.log===null?()=>{}:e.log??(t=>console.log(t)),n=await chunkQQOUNXLC_cjs.packPlugin({root:e.root,log:a});return publishPackedPlugin(n,e)}s(publishPlugin,"publishPlugin");async function publishPackedPlugin(e,a){const n=a.log===null?()=>{}:a.log??(p=>console.log(p)),t=a.fetchImpl??fetch,r=createCaller(a.server,a.token,t),u=await promises.readFile(e.file),o=path.basename(e.file);n("\u203A presigning upload");const l=await r("POST","/admin/runtime-plugins/presign-stream",{filename:o,mimeType:"application/zip",size:u.byteLength});n(`\u203A uploading ${o} (${u.byteLength} bytes)`),await putArchive(a.server,l.uploadUrl,u,t),n("\u203A inspecting package");const c=await r("POST","/admin/runtime-plugins/inspect",{uploadToken:l.uploadToken});n(` ${c.pluginId}@${c.semanticVersion} \u2014 ${describeParts(c)}${c.isUpgrade?" (upgrade)":""}${c.requiresConfig?", needs config":""}`),n("\u203A finalizing release");const g=await r("POST","/admin/runtime-plugins/upload",{uploadToken:l.uploadToken,...a.meta});let i=g.release;n(` release ${i.id} (${i.status})`),(a.approve??!0)&&(n("\u203A approving release"),i=await r("POST",`/admin/runtime-plugins/releases/${encodeURIComponent(i.id)}/approve`,{}),n(` release ${i.id} (${i.status})`));let d=null;if(a.install??!0){const p=chunk2P6UEAPV_cjs.resolvePluginScope(e.manifest),f=p==="avatar"?{releaseId:i.id,avatarIds:a.avatarIds??[]}:{releaseId:i.id};n(`\u203A installing for tenant (${p}-scoped)`),d=await r("POST","/admin/runtime-plugins/installs",f),reportInstall(d,n)}return{packed:e,preview:c,catalog:g.catalog,release:i,install:d}}s(publishPackedPlugin,"publishPackedPlugin");function describeParts(e){const a=[];return e.parts.frontend&&a.push(`frontend (${e.parts.frontend.locales.length} locales)`),e.parts.backend&&a.push(`backend (${e.parts.backend.migrationCount} migrations)`),e.parts.claw&&a.push("claw"),a.join(", ")||"no parts"}s(describeParts,"describeParts");function reportInstall(e,a){const n=e.avatars;if(!n||n.attempted===0){a(` installed ${e.pluginId}@${e.version}`);return}const t=n.attempted-n.failures.length;a(` installed ${e.pluginId}@${e.version} \u2014 ${t}/${n.attempted} avatars`);for(const r of n.failures)a(` \u2717 ${r.avatarId}: ${r.message}`)}s(reportInstall,"reportInstall");function createCaller(e,a,n){const t=e.replace(/\/+$/,"");return s(async function(u,o,l){const c=await n(`${t}${API_PREFIX}${o}`,{method:u,headers:{authorization:`Bearer ${a}`,...l===void 0?{}:{"content-type":"application/json"}},...l===void 0?{}:{body:JSON.stringify(l)}});return unwrap(c,`${u} ${o}`)},"call")}s(createCaller,"createCaller");async function putArchive(e,a,n,t){const r=e.replace(/\/+$/,""),u=await t(`${r}${a}`,{method:"PUT",headers:{"content-type":"application/zip"},body:n});await unwrap(u,"PUT upload")}s(putArchive,"putArchive");async function unwrap(e,a){let n;try{n=await e.json()}catch{n=null}if(!e.ok||!n?.success){const t=n?.error?.message??`HTTP ${e.status}`;throw new Error(`${a} failed: ${t}`)}return n.data}s(unwrap,"unwrap"),exports.publishPackedPlugin=publishPackedPlugin,exports.publishPlugin=publishPlugin;
1
+ "use strict";var $=Object.defineProperty;var i=(e,n)=>$(e,"name",{value:n,configurable:!0});var chunkQQOUNXLC_cjs=require("./chunk-QQOUNXLC.cjs");require("./chunk-6EKQMOYT.cjs"),require("./chunk-H6GXDFLP.cjs"),require("./chunk-45Y4CR4R.cjs");var chunk2P6UEAPV_cjs=require("./chunk-2P6UEAPV.cjs");require("./chunk-N4SXZZPY.cjs"),require("./chunk-IOZFHJ4F.cjs"),require("./chunk-AJY7ZHXK.cjs"),require("./chunk-OP64Y4IN.cjs");var promises=require("fs/promises"),path=require("path"),API_PREFIX="/api/v1/tego-os";async function publishPlugin(e){const n=e.log===null?()=>{}:e.log??(r=>console.log(r)),a=await chunkQQOUNXLC_cjs.packPlugin({root:e.root,log:n});return publishPackedPlugin(a,e)}i(publishPlugin,"publishPlugin");async function publishPackedPlugin(e,n){const a=n.log===null?()=>{}:n.log??(p=>console.log(p)),r=n.fetchImpl??fetch,t=createCaller(n.server,n.token,r),s=await promises.readFile(e.file),o=path.basename(e.file);a("\u203A presigning upload");const c=await t("POST","/admin/runtime-plugins/presign-stream",{filename:o,mimeType:"application/zip",size:s.byteLength});a(`\u203A uploading ${o} (${s.byteLength} bytes)`),await putArchive(n.server,c.uploadUrl,s,r),a("\u203A inspecting package");const u=await t("POST","/admin/runtime-plugins/inspect",{uploadToken:c.uploadToken});a(` ${u.pluginId}@${u.semanticVersion} \u2014 ${describeParts(u)}${u.isUpgrade?" (upgrade)":""}${u.requiresConfig?", needs config":""}`),a("\u203A finalizing release");const g=await t("POST","/admin/runtime-plugins/upload",{uploadToken:c.uploadToken,...n.meta});let l=g.release;a(` release ${l.id} (${l.status})`),(n.approve??!0)&&(a("\u203A approving release"),l=await t("POST",`/admin/runtime-plugins/releases/${encodeURIComponent(l.id)}/approve`,{}),a(` release ${l.id} (${l.status})`));let d=null;if(n.install??!0){const p=chunk2P6UEAPV_cjs.resolvePluginScope(e.manifest),f=p==="avatar"?{releaseId:l.id,avatarIds:n.avatarIds??await currentAvatarIds(t,e.manifest.id,a)}:{releaseId:l.id};a(`\u203A installing for tenant (${p}-scoped)`),d=await t("POST","/admin/runtime-plugins/installs",f),reportInstall(d,a)}return{packed:e,preview:u,catalog:g.catalog,release:l,install:d}}i(publishPackedPlugin,"publishPackedPlugin");async function currentAvatarIds(e,n,a){const t=(await e("GET","/admin/runtime-plugins/installs")).find(s=>s.pluginId===n);return t?(a(` keeping the ${t.avatarIds.length} avatars it is installed on`),t.avatarIds):(a(" first install: no avatars selected (pass --avatar to choose)"),[])}i(currentAvatarIds,"currentAvatarIds");function describeParts(e){const n=[];return e.parts.frontend&&n.push(`frontend (${e.parts.frontend.locales.length} locales)`),e.parts.backend&&n.push(`backend (${e.parts.backend.migrationCount} migrations)`),e.parts.claw&&n.push("claw"),n.join(", ")||"no parts"}i(describeParts,"describeParts");function reportInstall(e,n){const a=e.avatars;if(!a||a.attempted===0){n(` installed ${e.pluginId}@${e.version}`);return}const r=a.attempted-a.failures.length;n(` installed ${e.pluginId}@${e.version} \u2014 ${r}/${a.attempted} avatars`);for(const t of a.failures)n(` \u2717 ${t.avatarId}: ${t.message}`)}i(reportInstall,"reportInstall");function createCaller(e,n,a){const r=e.replace(/\/+$/,"");return i(async function(s,o,c){const u=await a(`${r}${API_PREFIX}${o}`,{method:s,headers:{authorization:`Bearer ${n}`,...c===void 0?{}:{"content-type":"application/json"}},...c===void 0?{}:{body:JSON.stringify(c)}});return unwrap(u,`${s} ${o}`)},"call")}i(createCaller,"createCaller");async function putArchive(e,n,a,r){const t=e.replace(/\/+$/,""),s=await r(`${t}${n}`,{method:"PUT",headers:{"content-type":"application/zip"},body:a});await unwrap(s,"PUT upload")}i(putArchive,"putArchive");async function unwrap(e,n){let a;try{a=await e.json()}catch{a=null}if(!e.ok||!a?.success){const r=a?.error?.message??`HTTP ${e.status}`;throw new Error(`${n} failed: ${r}`)}return a.data}i(unwrap,"unwrap"),exports.publishPackedPlugin=publishPackedPlugin,exports.publishPlugin=publishPlugin;
@@ -9,9 +9,12 @@ interface PublishPluginOptions {
9
9
  /** Admin bearer token. The publish endpoints all sit behind `adminMiddleware`. */
10
10
  token: string;
11
11
  /**
12
- * Avatars to install onto, for an avatar-scoped plugin. An empty array
13
- * installs it for nobody, which is the server's own contract, not a no-op —
14
- * it still creates the tenant install. Ignored for a tenant-scoped plugin.
12
+ * Avatars to install onto, for an avatar-scoped plugin: the complete set, so
13
+ * any avatar left out is uninstalled. An empty array installs it for nobody,
14
+ * which is the server's own contract, not a no-op — it still creates the
15
+ * tenant install. Omitted, an upgrade keeps the avatars the plugin is
16
+ * installed on now and a first install selects none. Ignored for a
17
+ * tenant-scoped plugin.
15
18
  */
16
19
  avatarIds?: string[];
17
20
  /** Catalog metadata to stamp on the release. */
package/dist/publish.d.ts CHANGED
@@ -9,9 +9,12 @@ interface PublishPluginOptions {
9
9
  /** Admin bearer token. The publish endpoints all sit behind `adminMiddleware`. */
10
10
  token: string;
11
11
  /**
12
- * Avatars to install onto, for an avatar-scoped plugin. An empty array
13
- * installs it for nobody, which is the server's own contract, not a no-op —
14
- * it still creates the tenant install. Ignored for a tenant-scoped plugin.
12
+ * Avatars to install onto, for an avatar-scoped plugin: the complete set, so
13
+ * any avatar left out is uninstalled. An empty array installs it for nobody,
14
+ * which is the server's own contract, not a no-op — it still creates the
15
+ * tenant install. Omitted, an upgrade keeps the avatars the plugin is
16
+ * installed on now and a first install selects none. Ignored for a
17
+ * tenant-scoped plugin.
15
18
  */
16
19
  avatarIds?: string[];
17
20
  /** Catalog metadata to stamp on the release. */
package/dist/publish.js CHANGED
@@ -1 +1 @@
1
- var h=Object.defineProperty;var o=(e,a)=>h(e,"name",{value:a,configurable:!0});import{packPlugin as v}from"./chunk-UZBWS5AR.js";import"./chunk-44LPR67H.js";import"./chunk-2KXEYXM2.js";import"./chunk-2NTAWYCG.js";import{resolvePluginScope as P}from"./chunk-IVJECPGG.js";import"./chunk-INCA3GFW.js";import"./chunk-XOXUS4VI.js";import"./chunk-VMCGDDGP.js";import"./chunk-SNUCO2MK.js";import{readFile as w}from"fs/promises";import{basename as y}from"path";var I="/api/v1/tego-os";async function T(e){const a=e.log===null?()=>{}:e.log??(n=>console.log(n)),t=await v({root:e.root,log:a});return m(t,e)}o(T,"publishPlugin");async function m(e,a){const t=a.log===null?()=>{}:a.log??(p=>console.log(p)),n=a.fetchImpl??fetch,r=A(a.server,a.token,n),s=await w(e.file),c=y(e.file);t("\u203A presigning upload");const u=await r("POST","/admin/runtime-plugins/presign-stream",{filename:c,mimeType:"application/zip",size:s.byteLength});t(`\u203A uploading ${c} (${s.byteLength} bytes)`),await S(a.server,u.uploadUrl,s,n),t("\u203A inspecting package");const l=await r("POST","/admin/runtime-plugins/inspect",{uploadToken:u.uploadToken});t(` ${l.pluginId}@${l.semanticVersion} \u2014 ${b(l)}${l.isUpgrade?" (upgrade)":""}${l.requiresConfig?", needs config":""}`),t("\u203A finalizing release");const g=await r("POST","/admin/runtime-plugins/upload",{uploadToken:u.uploadToken,...a.meta});let i=g.release;t(` release ${i.id} (${i.status})`),(a.approve??!0)&&(t("\u203A approving release"),i=await r("POST",`/admin/runtime-plugins/releases/${encodeURIComponent(i.id)}/approve`,{}),t(` release ${i.id} (${i.status})`));let d=null;if(a.install??!0){const p=P(e.manifest),$=p==="avatar"?{releaseId:i.id,avatarIds:a.avatarIds??[]}:{releaseId:i.id};t(`\u203A installing for tenant (${p}-scoped)`),d=await r("POST","/admin/runtime-plugins/installs",$),k(d,t)}return{packed:e,preview:l,catalog:g.catalog,release:i,install:d}}o(m,"publishPackedPlugin");function b(e){const a=[];return e.parts.frontend&&a.push(`frontend (${e.parts.frontend.locales.length} locales)`),e.parts.backend&&a.push(`backend (${e.parts.backend.migrationCount} migrations)`),e.parts.claw&&a.push("claw"),a.join(", ")||"no parts"}o(b,"describeParts");function k(e,a){const t=e.avatars;if(!t||t.attempted===0){a(` installed ${e.pluginId}@${e.version}`);return}const n=t.attempted-t.failures.length;a(` installed ${e.pluginId}@${e.version} \u2014 ${n}/${t.attempted} avatars`);for(const r of t.failures)a(` \u2717 ${r.avatarId}: ${r.message}`)}o(k,"reportInstall");function A(e,a,t){const n=e.replace(/\/+$/,"");return o(async function(s,c,u){const l=await t(`${n}${I}${c}`,{method:s,headers:{authorization:`Bearer ${a}`,...u===void 0?{}:{"content-type":"application/json"}},...u===void 0?{}:{body:JSON.stringify(u)}});return f(l,`${s} ${c}`)},"call")}o(A,"createCaller");async function S(e,a,t,n){const r=e.replace(/\/+$/,""),s=await n(`${r}${a}`,{method:"PUT",headers:{"content-type":"application/zip"},body:t});await f(s,"PUT upload")}o(S,"putArchive");async function f(e,a){let t;try{t=await e.json()}catch{t=null}if(!e.ok||!t?.success){const n=t?.error?.message??`HTTP ${e.status}`;throw new Error(`${a} failed: ${n}`)}return t.data}o(f,"unwrap");export{m as publishPackedPlugin,T as publishPlugin};
1
+ var v=Object.defineProperty;var s=(a,e)=>v(a,"name",{value:e,configurable:!0});import{packPlugin as h}from"./chunk-UZBWS5AR.js";import"./chunk-44LPR67H.js";import"./chunk-2KXEYXM2.js";import"./chunk-2NTAWYCG.js";import{resolvePluginScope as I}from"./chunk-IVJECPGG.js";import"./chunk-INCA3GFW.js";import"./chunk-XOXUS4VI.js";import"./chunk-VMCGDDGP.js";import"./chunk-SNUCO2MK.js";import{readFile as w}from"fs/promises";import{basename as P}from"path";var y="/api/v1/tego-os";async function T(a){const e=a.log===null?()=>{}:a.log??(i=>console.log(i)),t=await h({root:a.root,log:e});return f(t,a)}s(T,"publishPlugin");async function f(a,e){const t=e.log===null?()=>{}:e.log??(p=>console.log(p)),i=e.fetchImpl??fetch,n=S(e.server,e.token,i),r=await w(a.file),c=P(a.file);t("\u203A presigning upload");const u=await n("POST","/admin/runtime-plugins/presign-stream",{filename:c,mimeType:"application/zip",size:r.byteLength});t(`\u203A uploading ${c} (${r.byteLength} bytes)`),await z(e.server,u.uploadUrl,r,i),t("\u203A inspecting package");const l=await n("POST","/admin/runtime-plugins/inspect",{uploadToken:u.uploadToken});t(` ${l.pluginId}@${l.semanticVersion} \u2014 ${k(l)}${l.isUpgrade?" (upgrade)":""}${l.requiresConfig?", needs config":""}`),t("\u203A finalizing release");const g=await n("POST","/admin/runtime-plugins/upload",{uploadToken:u.uploadToken,...e.meta});let o=g.release;t(` release ${o.id} (${o.status})`),(e.approve??!0)&&(t("\u203A approving release"),o=await n("POST",`/admin/runtime-plugins/releases/${encodeURIComponent(o.id)}/approve`,{}),t(` release ${o.id} (${o.status})`));let d=null;if(e.install??!0){const p=I(a.manifest),$=p==="avatar"?{releaseId:o.id,avatarIds:e.avatarIds??await b(n,a.manifest.id,t)}:{releaseId:o.id};t(`\u203A installing for tenant (${p}-scoped)`),d=await n("POST","/admin/runtime-plugins/installs",$),A(d,t)}return{packed:a,preview:l,catalog:g.catalog,release:o,install:d}}s(f,"publishPackedPlugin");async function b(a,e,t){const n=(await a("GET","/admin/runtime-plugins/installs")).find(r=>r.pluginId===e);return n?(t(` keeping the ${n.avatarIds.length} avatars it is installed on`),n.avatarIds):(t(" first install: no avatars selected (pass --avatar to choose)"),[])}s(b,"currentAvatarIds");function k(a){const e=[];return a.parts.frontend&&e.push(`frontend (${a.parts.frontend.locales.length} locales)`),a.parts.backend&&e.push(`backend (${a.parts.backend.migrationCount} migrations)`),a.parts.claw&&e.push("claw"),e.join(", ")||"no parts"}s(k,"describeParts");function A(a,e){const t=a.avatars;if(!t||t.attempted===0){e(` installed ${a.pluginId}@${a.version}`);return}const i=t.attempted-t.failures.length;e(` installed ${a.pluginId}@${a.version} \u2014 ${i}/${t.attempted} avatars`);for(const n of t.failures)e(` \u2717 ${n.avatarId}: ${n.message}`)}s(A,"reportInstall");function S(a,e,t){const i=a.replace(/\/+$/,"");return s(async function(r,c,u){const l=await t(`${i}${y}${c}`,{method:r,headers:{authorization:`Bearer ${e}`,...u===void 0?{}:{"content-type":"application/json"}},...u===void 0?{}:{body:JSON.stringify(u)}});return m(l,`${r} ${c}`)},"call")}s(S,"createCaller");async function z(a,e,t,i){const n=a.replace(/\/+$/,""),r=await i(`${n}${e}`,{method:"PUT",headers:{"content-type":"application/zip"},body:t});await m(r,"PUT upload")}s(z,"putArchive");async function m(a,e){let t;try{t=await a.json()}catch{t=null}if(!a.ok||!t?.success){const i=t?.error?.message??`HTTP ${a.status}`;throw new Error(`${e} failed: ${i}`)}return t.data}s(m,"unwrap");export{f as publishPackedPlugin,T as publishPlugin};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhama/tego-plugin-sdk",
3
- "version": "1.40.0",
3
+ "version": "1.40.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",