@zhama/tego-plugin-sdk 1.36.2 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/agent/RULES.md +123 -0
  2. package/agent/guides/access.md +39 -0
  3. package/agent/guides/backend.md +76 -0
  4. package/agent/guides/claw.md +18 -0
  5. package/agent/guides/desktop-web.md +48 -0
  6. package/agent/guides/frontend.md +83 -0
  7. package/agent/guides/host-api-versions.md +34 -0
  8. package/agent/guides/i18n.md +17 -0
  9. package/agent/guides/manifest.md +26 -0
  10. package/agent/guides/migrations.md +17 -0
  11. package/agent/guides/storage.md +18 -0
  12. package/agent/guides/testing.md +17 -0
  13. package/agent/guides/ui.md +22 -0
  14. package/agent/reference/plugin-sdk-api.md +561 -0
  15. package/bin/tego-plugin-pack.mjs +1 -1
  16. package/bin/tego-plugin.mjs +4 -2
  17. package/dist/chunk-2NTAWYCG.js +1 -0
  18. package/dist/chunk-2P6UEAPV.cjs +1 -0
  19. package/dist/chunk-45Y4CR4R.cjs +1 -0
  20. package/dist/{chunk-PWSTCQRN.cjs → chunk-4LKRXDYY.cjs} +13 -12
  21. package/dist/{chunk-7XHF3YSK.js → chunk-56QOZQTY.js} +1 -1
  22. package/dist/{chunk-C2OCOPZQ.cjs → chunk-6HNG5OZI.cjs} +1 -1
  23. package/dist/{chunk-2ORO36BY.js → chunk-DEGQDJF6.js} +1 -1
  24. package/dist/chunk-EIVA5BR6.js +1 -0
  25. package/dist/{chunk-P2Q2AKWP.js → chunk-FCYAAOHC.js} +17 -16
  26. package/dist/chunk-HZ4YWRYX.cjs +5 -0
  27. package/dist/chunk-I5Z3ECC4.js +5 -0
  28. package/dist/chunk-INCA3GFW.js +1 -0
  29. package/dist/chunk-IVJECPGG.js +1 -0
  30. package/dist/{chunk-KMN5RHLX.cjs → chunk-MWMGJJ74.cjs} +1 -1
  31. package/dist/chunk-N4SXZZPY.cjs +1 -0
  32. package/dist/chunk-SKNPNPJP.cjs +1 -0
  33. package/dist/dev.cjs +88 -5
  34. package/dist/dev.d.cts +37 -1
  35. package/dist/dev.d.ts +37 -1
  36. package/dist/dev.js +91 -8
  37. package/dist/doctor.cjs +8 -0
  38. package/dist/doctor.d.cts +62 -0
  39. package/dist/doctor.d.ts +62 -0
  40. package/dist/doctor.js +8 -0
  41. package/dist/frontend.d.cts +33 -1
  42. package/dist/frontend.d.ts +33 -1
  43. package/dist/hono.cjs +1 -0
  44. package/dist/hono.d.cts +84 -0
  45. package/dist/hono.d.ts +84 -0
  46. package/dist/hono.js +1 -0
  47. package/dist/index.cjs +1 -1
  48. package/dist/index.d.cts +6 -1
  49. package/dist/index.d.ts +6 -1
  50. package/dist/index.js +1 -1
  51. package/dist/manifest.cjs +1 -1
  52. package/dist/manifest.d.cts +55 -2
  53. package/dist/manifest.d.ts +55 -2
  54. package/dist/manifest.js +1 -1
  55. package/dist/migrations-sync.cjs +1 -0
  56. package/dist/migrations-sync.d.cts +20 -0
  57. package/dist/migrations-sync.d.ts +20 -0
  58. package/dist/migrations-sync.js +1 -0
  59. package/dist/pack.cjs +1 -1
  60. package/dist/pack.d.cts +5 -0
  61. package/dist/pack.d.ts +5 -0
  62. package/dist/pack.js +1 -1
  63. package/dist/publish.cjs +1 -1
  64. package/dist/publish.js +1 -1
  65. package/dist/react.cjs +1 -0
  66. package/dist/react.d.cts +101 -0
  67. package/dist/react.d.ts +101 -0
  68. package/dist/react.js +1 -0
  69. package/dist/scaffold.cjs +671 -17
  70. package/dist/scaffold.d.cts +42 -18
  71. package/dist/scaffold.d.ts +42 -18
  72. package/dist/scaffold.js +673 -19
  73. package/dist/server-runtime.cjs +1 -1
  74. package/dist/server-runtime.d.cts +27 -2
  75. package/dist/server-runtime.d.ts +27 -2
  76. package/dist/server-runtime.js +1 -1
  77. package/dist/testing.cjs +6 -2
  78. package/dist/testing.d.cts +19 -1
  79. package/dist/testing.d.ts +19 -1
  80. package/dist/testing.js +6 -2
  81. package/dist/verify-FF2RD2MV.cjs +1 -0
  82. package/dist/verify-W7ZTUCO4.js +1 -0
  83. package/dist/vite.cjs +1 -1
  84. package/dist/vite.d.cts +27 -1
  85. package/dist/vite.d.ts +27 -1
  86. package/dist/vite.js +1 -1
  87. package/package.json +31 -3
  88. package/dist/chunk-3WA3M347.cjs +0 -1
  89. package/dist/chunk-5CU33JVY.js +0 -1
  90. package/dist/chunk-7K37PVGV.js +0 -5
  91. package/dist/chunk-BTHXQWHT.js +0 -1
  92. package/dist/chunk-ROFUQLOZ.cjs +0 -1
  93. package/dist/chunk-W7C357A6.cjs +0 -5
package/dist/hono.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var u=Object.defineProperty;var n=(s,e)=>u(s,"name",{value:e,configurable:!0});var HttpError=class extends Error{static{n(this,"HttpError")}constructor(s,e,t,r){super(t),this.status=s,this.code=e,this.detail=r,this.name="HttpError"}status;code;detail},badRequest=n((s,e,t)=>new HttpError(400,s,e,t),"badRequest"),forbidden=n((s,e)=>new HttpError(403,s,e),"forbidden"),notFound=n(s=>new HttpError(404,"not_found",`${s} was not found or is not visible to you.`),"notFound"),conflict=n((s,e,t)=>new HttpError(409,s,e,t),"conflict");function firstIssue(s,e){const t=s.issues[0],r=t?.path.map(String).join(".")??"",o=r.length>0?r:e;return{path:o,message:`${o}: ${t?.message??"invalid"}`}}n(firstIssue,"firstIssue");async function readBody(s,e){let t;try{t=await s.req.json()}catch{throw badRequest("invalid_json","The request body is not valid JSON.")}const r=e.safeParse(t);if(r.success)return r.data;const{path:o,message:a}=firstIssue(r.error,"body");throw badRequest("invalid_body",a,{path:o})}n(readBody,"readBody");function readQuery(s,e){const t=e.safeParse(s.req.query());if(t.success)return t.data;const{path:r,message:o}=firstIssue(t.error,"query");throw badRequest("invalid_query",o,{path:r})}n(readQuery,"readQuery");var jsonNotFound=n(s=>s.json({error:{code:"no_route",message:`No such route: ${s.req.method} ${new URL(s.req.url).pathname}`}},404),"jsonNotFound");function accessError(s){if(s instanceof Error&&!(s.name!=="AccessDeniedError"&&s.name!=="AccessAdminError"))return s}n(accessError,"accessError");function pluginErrorHandler(s={}){return(e,t)=>{const r=accessError(e);if(r)return r.name==="AccessAdminError"?t.json({error:{code:r.code??"forbidden",message:r.message}},r.status):r.status===404?t.json({error:{code:"not_found",message:"Not found"}},404):t.json({error:{code:"permission_required",message:r.message,permission:r.decision?.permission,reason:r.decision?.reason}},403);if(e instanceof HttpError)return t.json({error:{code:e.code,message:e.message,...e.detail?{detail:e.detail}:{}}},e.status);if(e.status===429&&e.message.startsWith("Tego host API ")){const i=e.retryAfter;return typeof i=="string"&&t.header("Retry-After",i),t.json({error:{code:"rate_limited",message:"Too many requests; try again shortly."}},429)}const a=t.env;return(s.log?.(t)??a?.host?.log)?.error("request failed",{method:t.req.method,path:new URL(t.req.url).pathname,error:e instanceof Error?e.message:String(e)}),t.json({error:{code:"internal",message:s.message??"The request could not be completed."}},500)}}n(pluginErrorHandler,"pluginErrorHandler");function changedEventsMiddleware(s={}){return async(e,t)=>{await t();const r=e.req.method;if(r==="GET"||r==="HEAD"||r==="OPTIONS"||e.res.status>=400)return;const o=new URL(e.req.url).pathname;if(s.skip?.(o))return;const a=e.env,d=a?.host;if(d)try{await d.events.publish(s.topic??"changed",{method:r,path:o,byAgent:!!a?.ctx?.avatarId})}catch(i){d.log.warn("change notice not published",{error:i instanceof Error?i.message:String(i)})}}}n(changedEventsMiddleware,"changedEventsMiddleware"),exports.HttpError=HttpError,exports.badRequest=badRequest,exports.changedEventsMiddleware=changedEventsMiddleware,exports.conflict=conflict,exports.forbidden=forbidden,exports.jsonNotFound=jsonNotFound,exports.notFound=notFound,exports.pluginErrorHandler=pluginErrorHandler,exports.readBody=readBody,exports.readQuery=readQuery;
@@ -0,0 +1,84 @@
1
+ import { MiddlewareHandler, NotFoundHandler, Context, ErrorHandler } from 'hono';
2
+ import { PluginHostApi } from './server.cjs';
3
+ import 'zod';
4
+ import './frontend.cjs';
5
+
6
+ /**
7
+ * Hono helpers for a plugin backend: refusals with a code the frontend can
8
+ * translate, validated bodies, and one error handler that turns everything
9
+ * else into JSON without leaking SQL or stack traces.
10
+ *
11
+ * `hono` stays the plugin's own dependency; schemas are duck-typed
12
+ * (`safeParse`) so any zod version works.
13
+ */
14
+
15
+ type HttpErrorStatus = 400 | 401 | 403 | 404 | 409 | 413 | 422 | 429;
16
+ /** A refusal the caller can act on: a status, a stable code, a sentence. */
17
+ declare class HttpError extends Error {
18
+ readonly status: HttpErrorStatus;
19
+ readonly code: string;
20
+ readonly detail?: Record<string, unknown> | undefined;
21
+ constructor(status: HttpErrorStatus, code: string, message: string, detail?: Record<string, unknown> | undefined);
22
+ }
23
+ declare const badRequest: (code: string, message: string, detail?: Record<string, unknown>) => HttpError;
24
+ declare const forbidden: (code: string, message: string) => HttpError;
25
+ declare const notFound: (what: string) => HttpError;
26
+ declare const conflict: (code: string, message: string, detail?: Record<string, unknown>) => HttpError;
27
+ /** Anything with zod's `safeParse` shape. */
28
+ interface ParseSchema<T> {
29
+ safeParse(input: unknown): {
30
+ success: true;
31
+ data: T;
32
+ } | {
33
+ success: false;
34
+ error: {
35
+ issues: {
36
+ path: PropertyKey[];
37
+ message: string;
38
+ }[];
39
+ };
40
+ };
41
+ }
42
+ /**
43
+ * The JSON body, validated, or a 400 naming the field. A truncated body would
44
+ * otherwise be a SyntaxError and a 500 — "the service broke" when the request did.
45
+ */
46
+ declare function readBody<T>(c: Pick<Context, 'req'> | {
47
+ req: {
48
+ json(): Promise<unknown>;
49
+ };
50
+ }, schema: ParseSchema<T>): Promise<T>;
51
+ /** The query string, validated, or a 400 naming the parameter. */
52
+ declare function readQuery<T>(c: {
53
+ req: {
54
+ query(): Record<string, string>;
55
+ };
56
+ }, schema: ParseSchema<T>): T;
57
+ /** `{ error: { code: 'no_route', … } }` instead of Hono's plain-text 404. */
58
+ declare const jsonNotFound: NotFoundHandler;
59
+ /**
60
+ * `app.onError(pluginErrorHandler())`:
61
+ *
62
+ * - access refusals → 403 `permission_required` (or the concealing 404), admin
63
+ * refusals with their code;
64
+ * - `HttpError` → its status, code, message and detail;
65
+ * - the host API's 429 → 429 `rate_limited` with its `Retry-After`;
66
+ * - anything else → logged through `host.log.error` (from `c.env.host`, or
67
+ * `options.log`) and a generic 500 that names nothing internal.
68
+ */
69
+ declare function pluginErrorHandler(options?: {
70
+ /** The sentence users see for an unexpected failure. */
71
+ message?: string;
72
+ log?: (c: Context) => Pick<PluginHostApi['log'], 'error'> | undefined;
73
+ }): ErrorHandler;
74
+ /**
75
+ * Publishes `changed` (`{ method, path, byAgent }`, no record data — the stream
76
+ * is tenant-wide) after every successful write, so open pages refresh. Failures
77
+ * to publish are logged, never surfaced to the caller.
78
+ */
79
+ declare function changedEventsMiddleware(options?: {
80
+ topic?: string;
81
+ skip?: (path: string) => boolean;
82
+ }): MiddlewareHandler;
83
+
84
+ export { HttpError, type HttpErrorStatus, type ParseSchema, badRequest, changedEventsMiddleware, conflict, forbidden, jsonNotFound, notFound, pluginErrorHandler, readBody, readQuery };
package/dist/hono.d.ts ADDED
@@ -0,0 +1,84 @@
1
+ import { MiddlewareHandler, NotFoundHandler, Context, ErrorHandler } from 'hono';
2
+ import { PluginHostApi } from './server.js';
3
+ import 'zod';
4
+ import './frontend.js';
5
+
6
+ /**
7
+ * Hono helpers for a plugin backend: refusals with a code the frontend can
8
+ * translate, validated bodies, and one error handler that turns everything
9
+ * else into JSON without leaking SQL or stack traces.
10
+ *
11
+ * `hono` stays the plugin's own dependency; schemas are duck-typed
12
+ * (`safeParse`) so any zod version works.
13
+ */
14
+
15
+ type HttpErrorStatus = 400 | 401 | 403 | 404 | 409 | 413 | 422 | 429;
16
+ /** A refusal the caller can act on: a status, a stable code, a sentence. */
17
+ declare class HttpError extends Error {
18
+ readonly status: HttpErrorStatus;
19
+ readonly code: string;
20
+ readonly detail?: Record<string, unknown> | undefined;
21
+ constructor(status: HttpErrorStatus, code: string, message: string, detail?: Record<string, unknown> | undefined);
22
+ }
23
+ declare const badRequest: (code: string, message: string, detail?: Record<string, unknown>) => HttpError;
24
+ declare const forbidden: (code: string, message: string) => HttpError;
25
+ declare const notFound: (what: string) => HttpError;
26
+ declare const conflict: (code: string, message: string, detail?: Record<string, unknown>) => HttpError;
27
+ /** Anything with zod's `safeParse` shape. */
28
+ interface ParseSchema<T> {
29
+ safeParse(input: unknown): {
30
+ success: true;
31
+ data: T;
32
+ } | {
33
+ success: false;
34
+ error: {
35
+ issues: {
36
+ path: PropertyKey[];
37
+ message: string;
38
+ }[];
39
+ };
40
+ };
41
+ }
42
+ /**
43
+ * The JSON body, validated, or a 400 naming the field. A truncated body would
44
+ * otherwise be a SyntaxError and a 500 — "the service broke" when the request did.
45
+ */
46
+ declare function readBody<T>(c: Pick<Context, 'req'> | {
47
+ req: {
48
+ json(): Promise<unknown>;
49
+ };
50
+ }, schema: ParseSchema<T>): Promise<T>;
51
+ /** The query string, validated, or a 400 naming the parameter. */
52
+ declare function readQuery<T>(c: {
53
+ req: {
54
+ query(): Record<string, string>;
55
+ };
56
+ }, schema: ParseSchema<T>): T;
57
+ /** `{ error: { code: 'no_route', … } }` instead of Hono's plain-text 404. */
58
+ declare const jsonNotFound: NotFoundHandler;
59
+ /**
60
+ * `app.onError(pluginErrorHandler())`:
61
+ *
62
+ * - access refusals → 403 `permission_required` (or the concealing 404), admin
63
+ * refusals with their code;
64
+ * - `HttpError` → its status, code, message and detail;
65
+ * - the host API's 429 → 429 `rate_limited` with its `Retry-After`;
66
+ * - anything else → logged through `host.log.error` (from `c.env.host`, or
67
+ * `options.log`) and a generic 500 that names nothing internal.
68
+ */
69
+ declare function pluginErrorHandler(options?: {
70
+ /** The sentence users see for an unexpected failure. */
71
+ message?: string;
72
+ log?: (c: Context) => Pick<PluginHostApi['log'], 'error'> | undefined;
73
+ }): ErrorHandler;
74
+ /**
75
+ * Publishes `changed` (`{ method, path, byAgent }`, no record data — the stream
76
+ * is tenant-wide) after every successful write, so open pages refresh. Failures
77
+ * to publish are logged, never surfaced to the caller.
78
+ */
79
+ declare function changedEventsMiddleware(options?: {
80
+ topic?: string;
81
+ skip?: (path: string) => boolean;
82
+ }): MiddlewareHandler;
83
+
84
+ export { HttpError, type HttpErrorStatus, type ParseSchema, badRequest, changedEventsMiddleware, conflict, forbidden, jsonNotFound, notFound, pluginErrorHandler, readBody, readQuery };
package/dist/hono.js ADDED
@@ -0,0 +1 @@
1
+ var m=Object.defineProperty;var n=(s,e)=>m(s,"name",{value:e,configurable:!0});var d=class extends Error{static{n(this,"HttpError")}constructor(s,e,t,r){super(t),this.status=s,this.code=e,this.detail=r,this.name="HttpError"}status;code;detail},c=n((s,e,t)=>new d(400,s,e,t),"badRequest"),f=n((s,e)=>new d(403,s,e),"forbidden"),g=n(s=>new d(404,"not_found",`${s} was not found or is not visible to you.`),"notFound"),l=n((s,e,t)=>new d(409,s,e,t),"conflict");function h(s,e){const t=s.issues[0],r=t?.path.map(String).join(".")??"",o=r.length>0?r:e;return{path:o,message:`${o}: ${t?.message??"invalid"}`}}n(h,"firstIssue");async function p(s,e){let t;try{t=await s.req.json()}catch{throw c("invalid_json","The request body is not valid JSON.")}const r=e.safeParse(t);if(r.success)return r.data;const{path:o,message:a}=h(r.error,"body");throw c("invalid_body",a,{path:o})}n(p,"readBody");function v(s,e){const t=e.safeParse(s.req.query());if(t.success)return t.data;const{path:r,message:o}=h(t.error,"query");throw c("invalid_query",o,{path:r})}n(v,"readQuery");var y=n(s=>s.json({error:{code:"no_route",message:`No such route: ${s.req.method} ${new URL(s.req.url).pathname}`}},404),"jsonNotFound");function q(s){if(s instanceof Error&&!(s.name!=="AccessDeniedError"&&s.name!=="AccessAdminError"))return s}n(q,"accessError");function w(s={}){return(e,t)=>{const r=q(e);if(r)return r.name==="AccessAdminError"?t.json({error:{code:r.code??"forbidden",message:r.message}},r.status):r.status===404?t.json({error:{code:"not_found",message:"Not found"}},404):t.json({error:{code:"permission_required",message:r.message,permission:r.decision?.permission,reason:r.decision?.reason}},403);if(e instanceof d)return t.json({error:{code:e.code,message:e.message,...e.detail?{detail:e.detail}:{}}},e.status);if(e.status===429&&e.message.startsWith("Tego host API ")){const i=e.retryAfter;return typeof i=="string"&&t.header("Retry-After",i),t.json({error:{code:"rate_limited",message:"Too many requests; try again shortly."}},429)}const a=t.env;return(s.log?.(t)??a?.host?.log)?.error("request failed",{method:t.req.method,path:new URL(t.req.url).pathname,error:e instanceof Error?e.message:String(e)}),t.json({error:{code:"internal",message:s.message??"The request could not be completed."}},500)}}n(w,"pluginErrorHandler");function E(s={}){return async(e,t)=>{await t();const r=e.req.method;if(r==="GET"||r==="HEAD"||r==="OPTIONS"||e.res.status>=400)return;const o=new URL(e.req.url).pathname;if(s.skip?.(o))return;const a=e.env,u=a?.host;if(u)try{await u.events.publish(s.topic??"changed",{method:r,path:o,byAgent:!!a?.ctx?.avatarId})}catch(i){u.log.warn("change notice not published",{error:i instanceof Error?i.message:String(i)})}}}n(E,"changedEventsMiddleware");export{d as HttpError,c as badRequest,E as changedEventsMiddleware,l as conflict,f as forbidden,y as jsonNotFound,g as notFound,w as pluginErrorHandler,p as readBody,v as readQuery};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var a=Object.defineProperty;var e=(t,n)=>a(t,"name",{value:n,configurable:!0});var chunkKMN5RHLX_cjs=require("./chunk-KMN5RHLX.cjs"),chunkROFUQLOZ_cjs=require("./chunk-ROFUQLOZ.cjs"),chunkC2OCOPZQ_cjs=require("./chunk-C2OCOPZQ.cjs");function readClawTools(t){if(!t)return[];const n=t.contracts;if(typeof n!="object"||n===null)return[];const u=n.tools;return Array.isArray(u)?u.filter(i=>typeof i=="string"):[]}e(readClawTools,"readClawTools");function auditDeclarationGaps(t,n){const u=Object.keys(t.audit?.tools??{}),i=new Set(n);return{undeclared:n.filter(o=>!t.audit?.tools?.[o]),unknown:u.filter(o=>!i.has(o))}}e(auditDeclarationGaps,"auditDeclarationGaps");function buildInstallDisclosure(t,n=null,u=null){const i=(t.parts.frontend?.nav??[]).map(r=>({key:r.key,labelKey:r.labelKey,permission:chunkROFUQLOZ_cjs.pluginMenuPermission(t.id,r.key),path:chunkROFUQLOZ_cjs.pluginNavPath(t.id,r.path)})),o=chunkROFUQLOZ_cjs.resolvePluginParts(t).backend,s=readClawTools(n);return{requiredPermissions:[...new Set(t.permissions?.required??[])].sort(),egress:o?.egress??[],publicRoutes:(o?.publicRoutes??[]).map(chunkROFUQLOZ_cjs.formatPublicRoute).sort(),...o?{backendRuntime:o.runtime}:{},scope:chunkROFUQLOZ_cjs.resolvePluginScope(t),parts:chunkROFUQLOZ_cjs.declaredPartNames(t),declares:chunkROFUQLOZ_cjs.resolvePluginDeclares(t),nav:i,clawTools:s,auditUndeclaredTools:auditDeclarationGaps(t,s).undeclared,config:{frontend:chunkKMN5RHLX_cjs.summarizeConfigDeclaration(t.parts.frontend?.config),backend:chunkKMN5RHLX_cjs.summarizeConfigDeclaration(t.parts.backend?.config),claw:chunkKMN5RHLX_cjs.summarizeClawConfig(n)},...u?{access:{permissions:Object.values(u.permissions).filter(r=>!r.reserved).length,roles:Object.keys(u.roles).length}}:{}}}e(buildInstallDisclosure,"buildInstallDisclosure");function requiresBackendConfig(t){return t.config.backend.required.length>0}e(requiresBackendConfig,"requiresBackendConfig");function diffInstallDisclosure(t,n){const u=[];for(const r of n.requiredPermissions??[])t?.requiredPermissions?.includes(r)||u.push({kind:"permission",value:r});for(const r of n.egress??[])!t?.egress?.includes(r)&&!t?.egress?.includes("*")&&u.push({kind:"egress",value:r});for(const r of n.publicRoutes??[])t?.publicRoutes?.includes(r)||u.push({kind:"publicRoute",value:r});const i=new Set(t?.parts??[]);for(const r of n.parts)i.has(r)||u.push({kind:"part",value:r});for(const r of["database","storage","events"])n.declares[r]&&(t?.declares[r]||u.push({kind:"declares",value:r}));const o=new Set((t?.nav??[]).map(r=>r.key));for(const r of n.nav)o.has(r.key)||u.push({kind:"nav",value:r.key});const s=new Set(t?.clawTools??[]);for(const r of n.clawTools)s.has(r)||u.push({kind:"clawTool",value:r});for(const r of["frontend","backend","claw"]){const l=new Set(t?.config[r]?.required??[]);for(const c of n.config[r].required)l.has(c)||u.push({kind:"configRequired",value:`${r}.${c}`})}return u}e(diffInstallDisclosure,"diffInstallDisclosure"),Object.defineProperty(exports,"EMPTY_CONFIG_SECTION_SUMMARY",{enumerable:!0,get:e(function(){return chunkKMN5RHLX_cjs.EMPTY_CONFIG_SECTION_SUMMARY},"get")}),Object.defineProperty(exports,"PLUGIN_CONFIG_SECRET_SENTINEL",{enumerable:!0,get:e(function(){return chunkKMN5RHLX_cjs.PLUGIN_CONFIG_SECRET_SENTINEL},"get")}),Object.defineProperty(exports,"PLUGIN_CONFIG_SECTIONS",{enumerable:!0,get:e(function(){return chunkKMN5RHLX_cjs.PLUGIN_CONFIG_SECTIONS},"get")}),Object.defineProperty(exports,"applyConfigDefaults",{enumerable:!0,get:e(function(){return chunkKMN5RHLX_cjs.applyConfigDefaults},"get")}),Object.defineProperty(exports,"configFieldLabel",{enumerable:!0,get:e(function(){return chunkKMN5RHLX_cjs.configFieldLabel},"get")}),Object.defineProperty(exports,"redactSecrets",{enumerable:!0,get:e(function(){return chunkKMN5RHLX_cjs.redactSecrets},"get")}),Object.defineProperty(exports,"restoreSecrets",{enumerable:!0,get:e(function(){return chunkKMN5RHLX_cjs.restoreSecrets},"get")}),Object.defineProperty(exports,"summarizeClawConfig",{enumerable:!0,get:e(function(){return chunkKMN5RHLX_cjs.summarizeClawConfig},"get")}),Object.defineProperty(exports,"summarizeConfigDeclaration",{enumerable:!0,get:e(function(){return chunkKMN5RHLX_cjs.summarizeConfigDeclaration},"get")}),Object.defineProperty(exports,"CLAW_MANIFEST_FILENAME",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.CLAW_MANIFEST_FILENAME},"get")}),Object.defineProperty(exports,"MAX_PLUGIN_MENU_PERMISSION_LENGTH",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.MAX_PLUGIN_MENU_PERMISSION_LENGTH},"get")}),Object.defineProperty(exports,"PLUGIN_AVATAR_PUBLIC_API_PATH",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_AVATAR_PUBLIC_API_PATH},"get")}),Object.defineProperty(exports,"PLUGIN_AVATAR_PUBLIC_PAGES_PATH",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_AVATAR_PUBLIC_PAGES_PATH},"get")}),Object.defineProperty(exports,"PLUGIN_BACKEND_PLATFORMS",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_BACKEND_PLATFORMS},"get")}),Object.defineProperty(exports,"PLUGIN_BACKEND_RUNTIMES",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_BACKEND_RUNTIMES},"get")}),Object.defineProperty(exports,"PLUGIN_MANIFEST_FILENAME",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_MANIFEST_FILENAME},"get")}),Object.defineProperty(exports,"PLUGIN_NAV_ICONS",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_NAV_ICONS},"get")}),Object.defineProperty(exports,"PLUGIN_NAV_ICON_FALLBACK",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_NAV_ICON_FALLBACK},"get")}),Object.defineProperty(exports,"PLUGIN_PART_DEFAULTS",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_PART_DEFAULTS},"get")}),Object.defineProperty(exports,"PLUGIN_PART_NAMES",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_PART_NAMES},"get")}),Object.defineProperty(exports,"PLUGIN_PUBLIC_API_PATH",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_PUBLIC_API_PATH},"get")}),Object.defineProperty(exports,"PLUGIN_PUBLIC_PAGES_PATH",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_PUBLIC_PAGES_PATH},"get")}),Object.defineProperty(exports,"PLUGIN_PUBLIC_ROUTE_METHODS",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_PUBLIC_ROUTE_METHODS},"get")}),Object.defineProperty(exports,"PLUGIN_SUPPORTED_LOCALES",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.PLUGIN_SUPPORTED_LOCALES},"get")}),Object.defineProperty(exports,"declaredPartNames",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.declaredPartNames},"get")}),Object.defineProperty(exports,"formatPublicRoute",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.formatPublicRoute},"get")}),Object.defineProperty(exports,"localizedTextToString",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.localizedTextToString},"get")}),Object.defineProperty(exports,"matchPublicRoute",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.matchPublicRoute},"get")}),Object.defineProperty(exports,"pluginApiPath",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.pluginApiPath},"get")}),Object.defineProperty(exports,"pluginBasePath",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.pluginBasePath},"get")}),Object.defineProperty(exports,"pluginI18nKey",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.pluginI18nKey},"get")}),Object.defineProperty(exports,"pluginI18nNamespace",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.pluginI18nNamespace},"get")}),Object.defineProperty(exports,"pluginMenuKey",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.pluginMenuKey},"get")}),Object.defineProperty(exports,"pluginMenuPermission",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.pluginMenuPermission},"get")}),Object.defineProperty(exports,"pluginNavPath",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.pluginNavPath},"get")}),Object.defineProperty(exports,"publicApiBaseFromPagePath",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.publicApiBaseFromPagePath},"get")}),Object.defineProperty(exports,"resolvePluginDeclares",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.resolvePluginDeclares},"get")}),Object.defineProperty(exports,"resolvePluginParts",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.resolvePluginParts},"get")}),Object.defineProperty(exports,"resolvePluginScope",{enumerable:!0,get:e(function(){return chunkROFUQLOZ_cjs.resolvePluginScope},"get")}),Object.defineProperty(exports,"HOST_API_VERSION",{enumerable:!0,get:e(function(){return chunkC2OCOPZQ_cjs.HOST_API_VERSION},"get")}),Object.defineProperty(exports,"SHARED_MODULE_IDS",{enumerable:!0,get:e(function(){return chunkC2OCOPZQ_cjs.SHARED_MODULE_IDS},"get")}),Object.defineProperty(exports,"hostApiRangeMinimum",{enumerable:!0,get:e(function(){return chunkC2OCOPZQ_cjs.hostApiRangeMinimum},"get")}),Object.defineProperty(exports,"isValidHostApiRange",{enumerable:!0,get:e(function(){return chunkC2OCOPZQ_cjs.isValidHostApiRange},"get")}),Object.defineProperty(exports,"satisfiesHostApiRange",{enumerable:!0,get:e(function(){return chunkC2OCOPZQ_cjs.satisfiesHostApiRange},"get")}),exports.auditDeclarationGaps=auditDeclarationGaps,exports.buildInstallDisclosure=buildInstallDisclosure,exports.diffInstallDisclosure=diffInstallDisclosure,exports.requiresBackendConfig=requiresBackendConfig;
1
+ "use strict";var a=Object.defineProperty;var e=(t,n)=>a(t,"name",{value:n,configurable:!0});var chunkMWMGJJ74_cjs=require("./chunk-MWMGJJ74.cjs"),chunk2P6UEAPV_cjs=require("./chunk-2P6UEAPV.cjs"),chunkN4SXZZPY_cjs=require("./chunk-N4SXZZPY.cjs"),chunk6HNG5OZI_cjs=require("./chunk-6HNG5OZI.cjs");function readClawTools(t){if(!t)return[];const n=t.contracts;if(typeof n!="object"||n===null)return[];const u=n.tools;return Array.isArray(u)?u.filter(i=>typeof i=="string"):[]}e(readClawTools,"readClawTools");function auditDeclarationGaps(t,n){const u=Object.keys(t.audit?.tools??{}),i=new Set(n);return{undeclared:n.filter(o=>!t.audit?.tools?.[o]),unknown:u.filter(o=>!i.has(o))}}e(auditDeclarationGaps,"auditDeclarationGaps");function buildInstallDisclosure(t,n=null,u=null){const i=(t.parts.frontend?.nav??[]).map(r=>({key:r.key,labelKey:r.labelKey,permission:chunkN4SXZZPY_cjs.pluginMenuPermission(t.id,r.key),path:chunkN4SXZZPY_cjs.pluginNavPath(t.id,r.path)})),o=chunk2P6UEAPV_cjs.resolvePluginParts(t).backend,s=readClawTools(n);return{requiredPermissions:[...new Set(t.permissions?.required??[])].sort(),egress:o?.egress??[],publicRoutes:(o?.publicRoutes??[]).map(chunk2P6UEAPV_cjs.formatPublicRoute).sort(),...o?{backendRuntime:o.runtime}:{},scope:chunk2P6UEAPV_cjs.resolvePluginScope(t),parts:chunk2P6UEAPV_cjs.declaredPartNames(t),declares:chunk2P6UEAPV_cjs.resolvePluginDeclares(t),nav:i,clawTools:s,auditUndeclaredTools:auditDeclarationGaps(t,s).undeclared,config:{frontend:chunkMWMGJJ74_cjs.summarizeConfigDeclaration(t.parts.frontend?.config),backend:chunkMWMGJJ74_cjs.summarizeConfigDeclaration(t.parts.backend?.config),claw:chunkMWMGJJ74_cjs.summarizeClawConfig(n)},...u?{access:{permissions:Object.values(u.permissions).filter(r=>!r.reserved).length,roles:Object.keys(u.roles).length}}:{}}}e(buildInstallDisclosure,"buildInstallDisclosure");function requiresBackendConfig(t){return t.config.backend.required.length>0}e(requiresBackendConfig,"requiresBackendConfig");function diffInstallDisclosure(t,n){const u=[];for(const r of n.requiredPermissions??[])t?.requiredPermissions?.includes(r)||u.push({kind:"permission",value:r});for(const r of n.egress??[])!t?.egress?.includes(r)&&!t?.egress?.includes("*")&&u.push({kind:"egress",value:r});for(const r of n.publicRoutes??[])t?.publicRoutes?.includes(r)||u.push({kind:"publicRoute",value:r});const i=new Set(t?.parts??[]);for(const r of n.parts)i.has(r)||u.push({kind:"part",value:r});for(const r of["database","storage","events"])n.declares[r]&&(t?.declares[r]||u.push({kind:"declares",value:r}));const o=new Set((t?.nav??[]).map(r=>r.key));for(const r of n.nav)o.has(r.key)||u.push({kind:"nav",value:r.key});const s=new Set(t?.clawTools??[]);for(const r of n.clawTools)s.has(r)||u.push({kind:"clawTool",value:r});for(const r of["frontend","backend","claw"]){const l=new Set(t?.config[r]?.required??[]);for(const c of n.config[r].required)l.has(c)||u.push({kind:"configRequired",value:`${r}.${c}`})}return u}e(diffInstallDisclosure,"diffInstallDisclosure"),Object.defineProperty(exports,"EMPTY_CONFIG_SECTION_SUMMARY",{enumerable:!0,get:e(function(){return chunkMWMGJJ74_cjs.EMPTY_CONFIG_SECTION_SUMMARY},"get")}),Object.defineProperty(exports,"PLUGIN_CONFIG_SECRET_SENTINEL",{enumerable:!0,get:e(function(){return chunkMWMGJJ74_cjs.PLUGIN_CONFIG_SECRET_SENTINEL},"get")}),Object.defineProperty(exports,"PLUGIN_CONFIG_SECTIONS",{enumerable:!0,get:e(function(){return chunkMWMGJJ74_cjs.PLUGIN_CONFIG_SECTIONS},"get")}),Object.defineProperty(exports,"applyConfigDefaults",{enumerable:!0,get:e(function(){return chunkMWMGJJ74_cjs.applyConfigDefaults},"get")}),Object.defineProperty(exports,"configFieldLabel",{enumerable:!0,get:e(function(){return chunkMWMGJJ74_cjs.configFieldLabel},"get")}),Object.defineProperty(exports,"redactSecrets",{enumerable:!0,get:e(function(){return chunkMWMGJJ74_cjs.redactSecrets},"get")}),Object.defineProperty(exports,"restoreSecrets",{enumerable:!0,get:e(function(){return chunkMWMGJJ74_cjs.restoreSecrets},"get")}),Object.defineProperty(exports,"summarizeClawConfig",{enumerable:!0,get:e(function(){return chunkMWMGJJ74_cjs.summarizeClawConfig},"get")}),Object.defineProperty(exports,"summarizeConfigDeclaration",{enumerable:!0,get:e(function(){return chunkMWMGJJ74_cjs.summarizeConfigDeclaration},"get")}),Object.defineProperty(exports,"CLAW_MANIFEST_FILENAME",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.CLAW_MANIFEST_FILENAME},"get")}),Object.defineProperty(exports,"PLUGIN_AVATAR_PUBLIC_API_PATH",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_AVATAR_PUBLIC_API_PATH},"get")}),Object.defineProperty(exports,"PLUGIN_AVATAR_PUBLIC_PAGES_PATH",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_AVATAR_PUBLIC_PAGES_PATH},"get")}),Object.defineProperty(exports,"PLUGIN_BACKEND_PLATFORMS",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_BACKEND_PLATFORMS},"get")}),Object.defineProperty(exports,"PLUGIN_BACKEND_RUNTIMES",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_BACKEND_RUNTIMES},"get")}),Object.defineProperty(exports,"PLUGIN_MANIFEST_FILENAME",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_MANIFEST_FILENAME},"get")}),Object.defineProperty(exports,"PLUGIN_NAV_ICONS",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_NAV_ICONS},"get")}),Object.defineProperty(exports,"PLUGIN_NAV_ICON_FALLBACK",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_NAV_ICON_FALLBACK},"get")}),Object.defineProperty(exports,"PLUGIN_PART_DEFAULTS",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_PART_DEFAULTS},"get")}),Object.defineProperty(exports,"PLUGIN_PART_NAMES",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_PART_NAMES},"get")}),Object.defineProperty(exports,"PLUGIN_PUBLIC_API_PATH",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_PUBLIC_API_PATH},"get")}),Object.defineProperty(exports,"PLUGIN_PUBLIC_PAGES_PATH",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_PUBLIC_PAGES_PATH},"get")}),Object.defineProperty(exports,"PLUGIN_PUBLIC_ROUTE_METHODS",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.PLUGIN_PUBLIC_ROUTE_METHODS},"get")}),Object.defineProperty(exports,"declaredPartNames",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.declaredPartNames},"get")}),Object.defineProperty(exports,"formatPublicRoute",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.formatPublicRoute},"get")}),Object.defineProperty(exports,"matchPublicRoute",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.matchPublicRoute},"get")}),Object.defineProperty(exports,"publicApiBaseFromPagePath",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.publicApiBaseFromPagePath},"get")}),Object.defineProperty(exports,"resolvePluginDeclares",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.resolvePluginDeclares},"get")}),Object.defineProperty(exports,"resolvePluginParts",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.resolvePluginParts},"get")}),Object.defineProperty(exports,"resolvePluginScope",{enumerable:!0,get:e(function(){return chunk2P6UEAPV_cjs.resolvePluginScope},"get")}),Object.defineProperty(exports,"MAX_PLUGIN_MENU_PERMISSION_LENGTH",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.MAX_PLUGIN_MENU_PERMISSION_LENGTH},"get")}),Object.defineProperty(exports,"PLUGIN_SUPPORTED_LOCALES",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.PLUGIN_SUPPORTED_LOCALES},"get")}),Object.defineProperty(exports,"localizedTextToString",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.localizedTextToString},"get")}),Object.defineProperty(exports,"pluginApiPath",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.pluginApiPath},"get")}),Object.defineProperty(exports,"pluginBasePath",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.pluginBasePath},"get")}),Object.defineProperty(exports,"pluginI18nKey",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.pluginI18nKey},"get")}),Object.defineProperty(exports,"pluginI18nNamespace",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.pluginI18nNamespace},"get")}),Object.defineProperty(exports,"pluginMenuKey",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.pluginMenuKey},"get")}),Object.defineProperty(exports,"pluginMenuPermission",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.pluginMenuPermission},"get")}),Object.defineProperty(exports,"pluginNavPath",{enumerable:!0,get:e(function(){return chunkN4SXZZPY_cjs.pluginNavPath},"get")}),Object.defineProperty(exports,"HOST_API_VERSION",{enumerable:!0,get:e(function(){return chunk6HNG5OZI_cjs.HOST_API_VERSION},"get")}),Object.defineProperty(exports,"SHARED_MODULE_IDS",{enumerable:!0,get:e(function(){return chunk6HNG5OZI_cjs.SHARED_MODULE_IDS},"get")}),Object.defineProperty(exports,"hostApiRangeMinimum",{enumerable:!0,get:e(function(){return chunk6HNG5OZI_cjs.hostApiRangeMinimum},"get")}),Object.defineProperty(exports,"isValidHostApiRange",{enumerable:!0,get:e(function(){return chunk6HNG5OZI_cjs.isValidHostApiRange},"get")}),Object.defineProperty(exports,"satisfiesHostApiRange",{enumerable:!0,get:e(function(){return chunk6HNG5OZI_cjs.satisfiesHostApiRange},"get")}),exports.auditDeclarationGaps=auditDeclarationGaps,exports.buildInstallDisclosure=buildInstallDisclosure,exports.diffInstallDisclosure=diffInstallDisclosure,exports.requiresBackendConfig=requiresBackendConfig;
package/dist/index.d.cts CHANGED
@@ -272,12 +272,17 @@ declare function diffInstallDisclosure(accepted: PluginInstallDisclosure | null,
272
272
  * identity revision fencing and durable document moves by externalId. Managed
273
273
  * collection reads use existing ACLs; policyScope is deprecated.
274
274
  *
275
+ * 1.37.0 adds the shell-neutral capabilities a page needs to behave the same
276
+ * in the web app and the desktop app: `PluginHostContext.platform`,
277
+ * `openExternal`, `download` and `copyText`. `window.open`, `<a download>`
278
+ * and `navigator.clipboard` are unreliable inside the desktop webview.
279
+ *
275
280
  * This numbers the *host API surface*, not the `@tego/plugin-sdk` npm package
276
281
  * — the two move on their own clocks. A manifest declares compatibility
277
282
  * against this constant through `hostApiRange`; the SDK's own package version
278
283
  * is a build-time dependency and never reaches a manifest.
279
284
  */
280
- declare const HOST_API_VERSION = "1.36.0";
285
+ declare const HOST_API_VERSION = "1.37.0";
281
286
  /**
282
287
  * Module specifiers the shell provides to plugin frontends.
283
288
  *
package/dist/index.d.ts CHANGED
@@ -272,12 +272,17 @@ declare function diffInstallDisclosure(accepted: PluginInstallDisclosure | null,
272
272
  * identity revision fencing and durable document moves by externalId. Managed
273
273
  * collection reads use existing ACLs; policyScope is deprecated.
274
274
  *
275
+ * 1.37.0 adds the shell-neutral capabilities a page needs to behave the same
276
+ * in the web app and the desktop app: `PluginHostContext.platform`,
277
+ * `openExternal`, `download` and `copyText`. `window.open`, `<a download>`
278
+ * and `navigator.clipboard` are unreliable inside the desktop webview.
279
+ *
275
280
  * This numbers the *host API surface*, not the `@tego/plugin-sdk` npm package
276
281
  * — the two move on their own clocks. A manifest declares compatibility
277
282
  * against this constant through `hostApiRange`; the SDK's own package version
278
283
  * is a build-time dependency and never reaches a manifest.
279
284
  */
280
- declare const HOST_API_VERSION = "1.36.0";
285
+ declare const HOST_API_VERSION = "1.37.0";
281
286
  /**
282
287
  * Module specifiers the shell provides to plugin frontends.
283
288
  *
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var d=Object.defineProperty;var l=(o,s)=>d(o,"name",{value:s,configurable:!0});import{summarizeClawConfig as f,summarizeConfigDeclaration as a}from"./chunk-2ORO36BY.js";export{EMPTY_CONFIG_SECTION_SUMMARY,PLUGIN_CONFIG_SECRET_SENTINEL,PLUGIN_CONFIG_SECTIONS,applyConfigDefaults,configFieldLabel,redactSecrets,restoreSecrets,summarizeClawConfig,summarizeConfigDeclaration}from"./chunk-2ORO36BY.js";import{pluginNavPath as p,pluginMenuPermission as _,resolvePluginParts as I,resolvePluginDeclares as N,declaredPartNames as A,resolvePluginScope as g,formatPublicRoute as S}from"./chunk-BTHXQWHT.js";export{CLAW_MANIFEST_FILENAME,MAX_PLUGIN_MENU_PERMISSION_LENGTH,PLUGIN_AVATAR_PUBLIC_API_PATH,PLUGIN_AVATAR_PUBLIC_PAGES_PATH,PLUGIN_BACKEND_PLATFORMS,PLUGIN_BACKEND_RUNTIMES,PLUGIN_MANIFEST_FILENAME,PLUGIN_NAV_ICONS,PLUGIN_NAV_ICON_FALLBACK,PLUGIN_PART_DEFAULTS,PLUGIN_PART_NAMES,PLUGIN_PUBLIC_API_PATH,PLUGIN_PUBLIC_PAGES_PATH,PLUGIN_PUBLIC_ROUTE_METHODS,PLUGIN_SUPPORTED_LOCALES,declaredPartNames,formatPublicRoute,localizedTextToString,matchPublicRoute,pluginApiPath,pluginBasePath,pluginI18nKey,pluginI18nNamespace,pluginMenuKey,pluginMenuPermission,pluginNavPath,publicApiBaseFromPagePath,resolvePluginDeclares,resolvePluginParts,resolvePluginScope}from"./chunk-BTHXQWHT.js";export{HOST_API_VERSION,SHARED_MODULE_IDS,hostApiRangeMinimum,isValidHostApiRange,satisfiesHostApiRange}from"./chunk-7XHF3YSK.js";function L(o){if(!o)return[];const s=o.contracts;if(typeof s!="object"||s===null)return[];const n=s.tools;return Array.isArray(n)?n.filter(i=>typeof i=="string"):[]}l(L,"readClawTools");function c(o,s){const n=Object.keys(o.audit?.tools??{}),i=new Set(s);return{undeclared:s.filter(r=>!o.audit?.tools?.[r]),unknown:n.filter(r=>!i.has(r))}}l(c,"auditDeclarationGaps");function T(o,s=null,n=null){const i=(o.parts.frontend?.nav??[]).map(e=>({key:e.key,labelKey:e.labelKey,permission:_(o.id,e.key),path:p(o.id,e.path)})),r=I(o).backend,t=L(s);return{requiredPermissions:[...new Set(o.permissions?.required??[])].sort(),egress:r?.egress??[],publicRoutes:(r?.publicRoutes??[]).map(S).sort(),...r?{backendRuntime:r.runtime}:{},scope:g(o),parts:A(o),declares:N(o),nav:i,clawTools:t,auditUndeclaredTools:c(o,t).undeclared,config:{frontend:a(o.parts.frontend?.config),backend:a(o.parts.backend?.config),claw:f(s)},...n?{access:{permissions:Object.values(n.permissions).filter(e=>!e.reserved).length,roles:Object.keys(n.roles).length}}:{}}}l(T,"buildInstallDisclosure");function E(o){return o.config.backend.required.length>0}l(E,"requiresBackendConfig");function m(o,s){const n=[];for(const e of s.requiredPermissions??[])o?.requiredPermissions?.includes(e)||n.push({kind:"permission",value:e});for(const e of s.egress??[])!o?.egress?.includes(e)&&!o?.egress?.includes("*")&&n.push({kind:"egress",value:e});for(const e of s.publicRoutes??[])o?.publicRoutes?.includes(e)||n.push({kind:"publicRoute",value:e});const i=new Set(o?.parts??[]);for(const e of s.parts)i.has(e)||n.push({kind:"part",value:e});for(const e of["database","storage","events"])s.declares[e]&&(o?.declares[e]||n.push({kind:"declares",value:e}));const r=new Set((o?.nav??[]).map(e=>e.key));for(const e of s.nav)r.has(e.key)||n.push({kind:"nav",value:e.key});const t=new Set(o?.clawTools??[]);for(const e of s.clawTools)t.has(e)||n.push({kind:"clawTool",value:e});for(const e of["frontend","backend","claw"]){const P=new Set(o?.config[e]?.required??[]);for(const u of s.config[e].required)P.has(u)||n.push({kind:"configRequired",value:`${e}.${u}`})}return n}l(m,"diffInstallDisclosure");export{c as auditDeclarationGaps,T as buildInstallDisclosure,m as diffInstallDisclosure,E as requiresBackendConfig};
1
+ var d=Object.defineProperty;var l=(o,s)=>d(o,"name",{value:s,configurable:!0});import{summarizeClawConfig as f,summarizeConfigDeclaration as a}from"./chunk-DEGQDJF6.js";export{EMPTY_CONFIG_SECTION_SUMMARY,PLUGIN_CONFIG_SECRET_SENTINEL,PLUGIN_CONFIG_SECTIONS,applyConfigDefaults,configFieldLabel,redactSecrets,restoreSecrets,summarizeClawConfig,summarizeConfigDeclaration}from"./chunk-DEGQDJF6.js";import{resolvePluginParts as p,resolvePluginDeclares as _,declaredPartNames as I,resolvePluginScope as N,formatPublicRoute as A}from"./chunk-IVJECPGG.js";export{CLAW_MANIFEST_FILENAME,PLUGIN_AVATAR_PUBLIC_API_PATH,PLUGIN_AVATAR_PUBLIC_PAGES_PATH,PLUGIN_BACKEND_PLATFORMS,PLUGIN_BACKEND_RUNTIMES,PLUGIN_MANIFEST_FILENAME,PLUGIN_NAV_ICONS,PLUGIN_NAV_ICON_FALLBACK,PLUGIN_PART_DEFAULTS,PLUGIN_PART_NAMES,PLUGIN_PUBLIC_API_PATH,PLUGIN_PUBLIC_PAGES_PATH,PLUGIN_PUBLIC_ROUTE_METHODS,declaredPartNames,formatPublicRoute,matchPublicRoute,publicApiBaseFromPagePath,resolvePluginDeclares,resolvePluginParts,resolvePluginScope}from"./chunk-IVJECPGG.js";import{pluginNavPath as g,pluginMenuPermission as S}from"./chunk-INCA3GFW.js";export{MAX_PLUGIN_MENU_PERMISSION_LENGTH,PLUGIN_SUPPORTED_LOCALES,localizedTextToString,pluginApiPath,pluginBasePath,pluginI18nKey,pluginI18nNamespace,pluginMenuKey,pluginMenuPermission,pluginNavPath}from"./chunk-INCA3GFW.js";export{HOST_API_VERSION,SHARED_MODULE_IDS,hostApiRangeMinimum,isValidHostApiRange,satisfiesHostApiRange}from"./chunk-56QOZQTY.js";function L(o){if(!o)return[];const s=o.contracts;if(typeof s!="object"||s===null)return[];const n=s.tools;return Array.isArray(n)?n.filter(i=>typeof i=="string"):[]}l(L,"readClawTools");function c(o,s){const n=Object.keys(o.audit?.tools??{}),i=new Set(s);return{undeclared:s.filter(r=>!o.audit?.tools?.[r]),unknown:n.filter(r=>!i.has(r))}}l(c,"auditDeclarationGaps");function m(o,s=null,n=null){const i=(o.parts.frontend?.nav??[]).map(e=>({key:e.key,labelKey:e.labelKey,permission:S(o.id,e.key),path:g(o.id,e.path)})),r=p(o).backend,t=L(s);return{requiredPermissions:[...new Set(o.permissions?.required??[])].sort(),egress:r?.egress??[],publicRoutes:(r?.publicRoutes??[]).map(A).sort(),...r?{backendRuntime:r.runtime}:{},scope:N(o),parts:I(o),declares:_(o),nav:i,clawTools:t,auditUndeclaredTools:c(o,t).undeclared,config:{frontend:a(o.parts.frontend?.config),backend:a(o.parts.backend?.config),claw:f(s)},...n?{access:{permissions:Object.values(n.permissions).filter(e=>!e.reserved).length,roles:Object.keys(n.roles).length}}:{}}}l(m,"buildInstallDisclosure");function T(o){return o.config.backend.required.length>0}l(T,"requiresBackendConfig");function E(o,s){const n=[];for(const e of s.requiredPermissions??[])o?.requiredPermissions?.includes(e)||n.push({kind:"permission",value:e});for(const e of s.egress??[])!o?.egress?.includes(e)&&!o?.egress?.includes("*")&&n.push({kind:"egress",value:e});for(const e of s.publicRoutes??[])o?.publicRoutes?.includes(e)||n.push({kind:"publicRoute",value:e});const i=new Set(o?.parts??[]);for(const e of s.parts)i.has(e)||n.push({kind:"part",value:e});for(const e of["database","storage","events"])s.declares[e]&&(o?.declares[e]||n.push({kind:"declares",value:e}));const r=new Set((o?.nav??[]).map(e=>e.key));for(const e of s.nav)r.has(e.key)||n.push({kind:"nav",value:e.key});const t=new Set(o?.clawTools??[]);for(const e of s.clawTools)t.has(e)||n.push({kind:"clawTool",value:e});for(const e of["frontend","backend","claw"]){const P=new Set(o?.config[e]?.required??[]);for(const u of s.config[e].required)P.has(u)||n.push({kind:"configRequired",value:`${e}.${u}`})}return n}l(E,"diffInstallDisclosure");export{c as auditDeclarationGaps,m as buildInstallDisclosure,E as diffInstallDisclosure,T as requiresBackendConfig};
package/dist/manifest.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var n=Object.defineProperty;var e=(r,t)=>n(r,"name",{value:t,configurable:!0});var chunk3WA3M347_cjs=require("./chunk-3WA3M347.cjs");require("./chunk-ROFUQLOZ.cjs"),require("./chunk-C2OCOPZQ.cjs"),require("./chunk-AJY7ZHXK.cjs"),require("./chunk-OP64Y4IN.cjs"),Object.defineProperty(exports,"PYTHON_LOCK_FILENAME",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.PYTHON_LOCK_FILENAME},"get")}),Object.defineProperty(exports,"PYTHON_RUNNER_VERSION",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.PYTHON_RUNNER_VERSION},"get")}),Object.defineProperty(exports,"PYTHON_WHEELS_DIR",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.PYTHON_WHEELS_DIR},"get")}),Object.defineProperty(exports,"checkPluginAccessCatalog",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.checkPluginAccessCatalog},"get")}),Object.defineProperty(exports,"checkPythonVendoring",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.checkPythonVendoring},"get")}),Object.defineProperty(exports,"normalizePackageName",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.normalizePackageName},"get")}),Object.defineProperty(exports,"parseRequirementsLock",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.parseRequirementsLock},"get")}),Object.defineProperty(exports,"parseTegoPluginManifest",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.parseTegoPluginManifest},"get")}),Object.defineProperty(exports,"parseWheelFilename",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.parseWheelFilename},"get")}),Object.defineProperty(exports,"tegoPluginManifestSchema",{enumerable:!0,get:e(function(){return chunk3WA3M347_cjs.tegoPluginManifestSchema},"get")});
1
+ "use strict";var n=Object.defineProperty;var e=(r,t)=>n(r,"name",{value:t,configurable:!0});var chunkSKNPNPJP_cjs=require("./chunk-SKNPNPJP.cjs"),chunk45Y4CR4R_cjs=require("./chunk-45Y4CR4R.cjs");require("./chunk-2P6UEAPV.cjs"),require("./chunk-N4SXZZPY.cjs"),require("./chunk-6HNG5OZI.cjs"),require("./chunk-AJY7ZHXK.cjs"),require("./chunk-OP64Y4IN.cjs"),Object.defineProperty(exports,"PYTHON_LOCK_FILENAME",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.PYTHON_LOCK_FILENAME},"get")}),Object.defineProperty(exports,"PYTHON_RUNNER_VERSION",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.PYTHON_RUNNER_VERSION},"get")}),Object.defineProperty(exports,"PYTHON_WHEELS_DIR",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.PYTHON_WHEELS_DIR},"get")}),Object.defineProperty(exports,"checkPluginAccessCatalog",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.checkPluginAccessCatalog},"get")}),Object.defineProperty(exports,"checkPythonVendoring",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.checkPythonVendoring},"get")}),Object.defineProperty(exports,"normalizePackageName",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.normalizePackageName},"get")}),Object.defineProperty(exports,"parseRequirementsLock",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.parseRequirementsLock},"get")}),Object.defineProperty(exports,"parseTegoPluginManifest",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.parseTegoPluginManifest},"get")}),Object.defineProperty(exports,"parseWheelFilename",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.parseWheelFilename},"get")}),Object.defineProperty(exports,"tegoPluginManifestSchema",{enumerable:!0,get:e(function(){return chunkSKNPNPJP_cjs.tegoPluginManifestSchema},"get")}),Object.defineProperty(exports,"LOCALE_FILENAME_PATTERN",{enumerable:!0,get:e(function(){return chunk45Y4CR4R_cjs.LOCALE_FILENAME_PATTERN},"get")}),Object.defineProperty(exports,"MIGRATION_FILENAME_PATTERN",{enumerable:!0,get:e(function(){return chunk45Y4CR4R_cjs.MIGRATION_FILENAME_PATTERN},"get")}),Object.defineProperty(exports,"flattenLocaleKeys",{enumerable:!0,get:e(function(){return chunk45Y4CR4R_cjs.flattenLocaleKeys},"get")}),Object.defineProperty(exports,"verifyFrontendLocales",{enumerable:!0,get:e(function(){return chunk45Y4CR4R_cjs.verifyFrontendLocales},"get")}),Object.defineProperty(exports,"verifyMigrationNames",{enumerable:!0,get:e(function(){return chunk45Y4CR4R_cjs.verifyMigrationNames},"get")});
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { T as TegoPluginManifest, y as PluginBackendPlatform } from './manifest-types-CUTNfJTa.cjs';
2
+ import { T as TegoPluginManifest, P as PluginNavEntry, y as PluginBackendPlatform } from './manifest-types-CUTNfJTa.cjs';
3
3
  import { A as AccessCatalog } from './catalog-CSSbrfEf.cjs';
4
4
 
5
5
  /**
@@ -22,6 +22,59 @@ type PluginAccessCatalogResult = {
22
22
  */
23
23
  declare function checkPluginAccessCatalog(manifest: Pick<TegoPluginManifest, 'access' | 'parts'>, raw: unknown): PluginAccessCatalogResult;
24
24
 
25
+ /** `zh-CN.json`, `en.json` — the locale file shape the host's loader expects. */
26
+ declare const LOCALE_FILENAME_PATTERN: RegExp;
27
+ /**
28
+ * `0001_initial.sql`. The numeric prefix is what makes the apply order
29
+ * deterministic; without it two migrations could be applied in either order,
30
+ * which is only discovered when a column is missing in production.
31
+ */
32
+ declare const MIGRATION_FILENAME_PATTERN: RegExp;
33
+ /** Read access to a plugin package or source tree, paths relative to its root with `/`. */
34
+ interface PluginTreeReader {
35
+ /** Names of the files directly in `dir` (not nested deeper); empty when it does not exist. */
36
+ list(dir: string): Promise<string[]>;
37
+ /** The file as UTF-8, or `null` when absent. */
38
+ readText(path: string): Promise<string | null>;
39
+ }
40
+ /** Every leaf path of a nested translation object, in `a.b.c` form. */
41
+ declare function flattenLocaleKeys(value: unknown, prefix?: string, into?: Set<string>): Set<string>;
42
+ interface LocaleVerification {
43
+ /** Locale tags found (`zh-CN`, `en`, …), in directory order. */
44
+ locales: string[];
45
+ /** Parsed bundles by tag, for checks that need the values. */
46
+ bundles: Map<string, unknown>;
47
+ errors: string[];
48
+ }
49
+ /**
50
+ * Every locale bundle exists, parses, and carries the same keys.
51
+ *
52
+ * Three separate failures, all of which used to reach a user as a sidebar row
53
+ * showing `crm.nav.deals`:
54
+ *
55
+ * - a missing language, where the platform is translated and this plugin is
56
+ * not. Falling back would hide it permanently, so it is refused where the
57
+ * author can act
58
+ * - a key present in one bundle and absent in another, which is what a
59
+ * half-finished translation pass leaves behind
60
+ * - a nav entry pointing at a key nobody wrote
61
+ *
62
+ * Keys are compared against `zh-CN`, the platform's own default, rather than
63
+ * against a union of all files — a union would let a typo in one file demand
64
+ * the same typo in the other nine.
65
+ */
66
+ declare function verifyFrontendLocales(reader: PluginTreeReader, frontend: {
67
+ i18nDirPath: string;
68
+ nav: PluginNavEntry[];
69
+ }): Promise<LocaleVerification>;
70
+ interface MigrationVerification {
71
+ /** Valid migration file names, sorted (= apply order). */
72
+ migrations: string[];
73
+ errors: string[];
74
+ }
75
+ /** Migration files are `<ordinal>_<description>.sql` with unique ordinals. */
76
+ declare function verifyMigrationNames(reader: PluginTreeReader, migrationsDirPath: string): Promise<MigrationVerification>;
77
+
25
78
  /**
26
79
  * Whether a python backend's vendored wheels will install in the runner.
27
80
  *
@@ -2821,4 +2874,4 @@ interface PluginManifestParseResult {
2821
2874
  */
2822
2875
  declare function parseTegoPluginManifest(value: unknown): PluginManifestParseResult;
2823
2876
 
2824
- export { type LockedRequirement, PYTHON_LOCK_FILENAME, PYTHON_RUNNER_VERSION, PYTHON_WHEELS_DIR, type ParsedTegoPluginManifest, type ParsedWheelFilename, type PluginAccessCatalogResult, type PluginManifestParseResult, type VendoredWheel, checkPluginAccessCatalog, checkPythonVendoring, normalizePackageName, parseRequirementsLock, parseTegoPluginManifest, parseWheelFilename, tegoPluginManifestSchema };
2877
+ export { LOCALE_FILENAME_PATTERN, type LocaleVerification, type LockedRequirement, MIGRATION_FILENAME_PATTERN, type MigrationVerification, PYTHON_LOCK_FILENAME, PYTHON_RUNNER_VERSION, PYTHON_WHEELS_DIR, type ParsedTegoPluginManifest, type ParsedWheelFilename, type PluginAccessCatalogResult, type PluginManifestParseResult, type PluginTreeReader, type VendoredWheel, checkPluginAccessCatalog, checkPythonVendoring, flattenLocaleKeys, normalizePackageName, parseRequirementsLock, parseTegoPluginManifest, parseWheelFilename, tegoPluginManifestSchema, verifyFrontendLocales, verifyMigrationNames };
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { T as TegoPluginManifest, y as PluginBackendPlatform } from './manifest-types-CUTNfJTa.js';
2
+ import { T as TegoPluginManifest, P as PluginNavEntry, y as PluginBackendPlatform } from './manifest-types-CUTNfJTa.js';
3
3
  import { A as AccessCatalog } from './catalog-CSSbrfEf.js';
4
4
 
5
5
  /**
@@ -22,6 +22,59 @@ type PluginAccessCatalogResult = {
22
22
  */
23
23
  declare function checkPluginAccessCatalog(manifest: Pick<TegoPluginManifest, 'access' | 'parts'>, raw: unknown): PluginAccessCatalogResult;
24
24
 
25
+ /** `zh-CN.json`, `en.json` — the locale file shape the host's loader expects. */
26
+ declare const LOCALE_FILENAME_PATTERN: RegExp;
27
+ /**
28
+ * `0001_initial.sql`. The numeric prefix is what makes the apply order
29
+ * deterministic; without it two migrations could be applied in either order,
30
+ * which is only discovered when a column is missing in production.
31
+ */
32
+ declare const MIGRATION_FILENAME_PATTERN: RegExp;
33
+ /** Read access to a plugin package or source tree, paths relative to its root with `/`. */
34
+ interface PluginTreeReader {
35
+ /** Names of the files directly in `dir` (not nested deeper); empty when it does not exist. */
36
+ list(dir: string): Promise<string[]>;
37
+ /** The file as UTF-8, or `null` when absent. */
38
+ readText(path: string): Promise<string | null>;
39
+ }
40
+ /** Every leaf path of a nested translation object, in `a.b.c` form. */
41
+ declare function flattenLocaleKeys(value: unknown, prefix?: string, into?: Set<string>): Set<string>;
42
+ interface LocaleVerification {
43
+ /** Locale tags found (`zh-CN`, `en`, …), in directory order. */
44
+ locales: string[];
45
+ /** Parsed bundles by tag, for checks that need the values. */
46
+ bundles: Map<string, unknown>;
47
+ errors: string[];
48
+ }
49
+ /**
50
+ * Every locale bundle exists, parses, and carries the same keys.
51
+ *
52
+ * Three separate failures, all of which used to reach a user as a sidebar row
53
+ * showing `crm.nav.deals`:
54
+ *
55
+ * - a missing language, where the platform is translated and this plugin is
56
+ * not. Falling back would hide it permanently, so it is refused where the
57
+ * author can act
58
+ * - a key present in one bundle and absent in another, which is what a
59
+ * half-finished translation pass leaves behind
60
+ * - a nav entry pointing at a key nobody wrote
61
+ *
62
+ * Keys are compared against `zh-CN`, the platform's own default, rather than
63
+ * against a union of all files — a union would let a typo in one file demand
64
+ * the same typo in the other nine.
65
+ */
66
+ declare function verifyFrontendLocales(reader: PluginTreeReader, frontend: {
67
+ i18nDirPath: string;
68
+ nav: PluginNavEntry[];
69
+ }): Promise<LocaleVerification>;
70
+ interface MigrationVerification {
71
+ /** Valid migration file names, sorted (= apply order). */
72
+ migrations: string[];
73
+ errors: string[];
74
+ }
75
+ /** Migration files are `<ordinal>_<description>.sql` with unique ordinals. */
76
+ declare function verifyMigrationNames(reader: PluginTreeReader, migrationsDirPath: string): Promise<MigrationVerification>;
77
+
25
78
  /**
26
79
  * Whether a python backend's vendored wheels will install in the runner.
27
80
  *
@@ -2821,4 +2874,4 @@ interface PluginManifestParseResult {
2821
2874
  */
2822
2875
  declare function parseTegoPluginManifest(value: unknown): PluginManifestParseResult;
2823
2876
 
2824
- export { type LockedRequirement, PYTHON_LOCK_FILENAME, PYTHON_RUNNER_VERSION, PYTHON_WHEELS_DIR, type ParsedTegoPluginManifest, type ParsedWheelFilename, type PluginAccessCatalogResult, type PluginManifestParseResult, type VendoredWheel, checkPluginAccessCatalog, checkPythonVendoring, normalizePackageName, parseRequirementsLock, parseTegoPluginManifest, parseWheelFilename, tegoPluginManifestSchema };
2877
+ export { LOCALE_FILENAME_PATTERN, type LocaleVerification, type LockedRequirement, MIGRATION_FILENAME_PATTERN, type MigrationVerification, PYTHON_LOCK_FILENAME, PYTHON_RUNNER_VERSION, PYTHON_WHEELS_DIR, type ParsedTegoPluginManifest, type ParsedWheelFilename, type PluginAccessCatalogResult, type PluginManifestParseResult, type PluginTreeReader, type VendoredWheel, checkPluginAccessCatalog, checkPythonVendoring, flattenLocaleKeys, normalizePackageName, parseRequirementsLock, parseTegoPluginManifest, parseWheelFilename, tegoPluginManifestSchema, verifyFrontendLocales, verifyMigrationNames };
package/dist/manifest.js CHANGED
@@ -1 +1 @@
1
- export{PYTHON_LOCK_FILENAME,PYTHON_RUNNER_VERSION,PYTHON_WHEELS_DIR,checkPluginAccessCatalog,checkPythonVendoring,normalizePackageName,parseRequirementsLock,parseTegoPluginManifest,parseWheelFilename,tegoPluginManifestSchema}from"./chunk-5CU33JVY.js";import"./chunk-BTHXQWHT.js";import"./chunk-7XHF3YSK.js";import"./chunk-VMCGDDGP.js";import"./chunk-SNUCO2MK.js";
1
+ export{PYTHON_LOCK_FILENAME,PYTHON_RUNNER_VERSION,PYTHON_WHEELS_DIR,checkPluginAccessCatalog,checkPythonVendoring,normalizePackageName,parseRequirementsLock,parseTegoPluginManifest,parseWheelFilename,tegoPluginManifestSchema}from"./chunk-EIVA5BR6.js";export{LOCALE_FILENAME_PATTERN,MIGRATION_FILENAME_PATTERN,flattenLocaleKeys,verifyFrontendLocales,verifyMigrationNames}from"./chunk-2NTAWYCG.js";import"./chunk-IVJECPGG.js";import"./chunk-INCA3GFW.js";import"./chunk-56QOZQTY.js";import"./chunk-VMCGDDGP.js";import"./chunk-SNUCO2MK.js";
@@ -0,0 +1 @@
1
+ "use strict";var f=Object.defineProperty;var o=(e,t)=>f(e,"name",{value:t,configurable:!0});var promises=require("fs/promises"),path=require("path");function parseName(e){const t=/^(\d{4,})_(.+)\.sql$/.exec(e);return t?{ordinal:Number(t[1]),tag:t[2]}:null}o(parseName,"parseName");async function sqlFiles(e){return(await promises.readdir(e).catch(()=>[])).filter(n=>n.endsWith(".sql")).sort()}o(sqlFiles,"sqlFiles");function normalizeGeneratedSql(e){return e.replaceAll('"public".',"")}o(normalizeGeneratedSql,"normalizeGeneratedSql");async function syncMigrations(e){const t=e.generatedDir??"backend/.drizzle",n=e.migrationsDir??"backend/migrations",g=await sqlFiles(path.join(e.root,t)),m=await sqlFiles(path.join(e.root,n)),l=new Map;let s=0;for(const r of m){const a=parseName(r);a&&(l.set(a.tag,r),s=Math.max(s,a.ordinal))}const i={copied:[],problems:[]};for(const r of g){const a=parseName(r);if(!a){i.problems.push(`${t}/${r}: not named <ordinal>_<tag>.sql`);continue}const u=normalizeGeneratedSql(await promises.readFile(path.join(e.root,t,r),"utf8")),d=l.get(a.tag);if(d){await promises.readFile(path.join(e.root,n,d),"utf8")!==u&&i.problems.push(`${n}/${d} differs from the regenerated ${r}. An applied migration is frozen \u2014 add a new one instead of editing it.`);continue}s+=1;const c=`${String(s).padStart(4,"0")}_${a.tag}.sql`;if(e.check){i.problems.push(`${n}/${c} is missing; run \`tego-plugin migrations sync\`.`);continue}await promises.writeFile(path.join(e.root,n,c),u,"utf8"),l.set(a.tag,c),i.copied.push({from:`${t}/${r}`,to:`${n}/${c}`})}return i}o(syncMigrations,"syncMigrations"),exports.normalizeGeneratedSql=normalizeGeneratedSql,exports.syncMigrations=syncMigrations;
@@ -0,0 +1,20 @@
1
+ interface MigrationSyncOptions {
2
+ root: string;
3
+ /** drizzle-kit's `out`. Default `backend/.drizzle`. */
4
+ generatedDir?: string;
5
+ /** The manifest's migrations dir. Default `backend/migrations`. */
6
+ migrationsDir?: string;
7
+ /** Verify only (for `build` / CI): report what is missing or edited. */
8
+ check?: boolean;
9
+ }
10
+ interface MigrationSyncResult {
11
+ copied: {
12
+ from: string;
13
+ to: string;
14
+ }[];
15
+ problems: string[];
16
+ }
17
+ declare function normalizeGeneratedSql(sql: string): string;
18
+ declare function syncMigrations(options: MigrationSyncOptions): Promise<MigrationSyncResult>;
19
+
20
+ export { type MigrationSyncOptions, type MigrationSyncResult, normalizeGeneratedSql, syncMigrations };
@@ -0,0 +1,20 @@
1
+ interface MigrationSyncOptions {
2
+ root: string;
3
+ /** drizzle-kit's `out`. Default `backend/.drizzle`. */
4
+ generatedDir?: string;
5
+ /** The manifest's migrations dir. Default `backend/migrations`. */
6
+ migrationsDir?: string;
7
+ /** Verify only (for `build` / CI): report what is missing or edited. */
8
+ check?: boolean;
9
+ }
10
+ interface MigrationSyncResult {
11
+ copied: {
12
+ from: string;
13
+ to: string;
14
+ }[];
15
+ problems: string[];
16
+ }
17
+ declare function normalizeGeneratedSql(sql: string): string;
18
+ declare function syncMigrations(options: MigrationSyncOptions): Promise<MigrationSyncResult>;
19
+
20
+ export { type MigrationSyncOptions, type MigrationSyncResult, normalizeGeneratedSql, syncMigrations };
@@ -0,0 +1 @@
1
+ var w=Object.defineProperty;var o=(t,e)=>w(t,"name",{value:e,configurable:!0});import{readFile as m,writeFile as y,readdir as q}from"fs/promises";import{join as s}from"path";function f(t){const e=/^(\d{4,})_(.+)\.sql$/.exec(t);return e?{ordinal:Number(e[1]),tag:e[2]}:null}o(f,"parseName");async function p(t){return(await q(t).catch(()=>[])).filter(n=>n.endsWith(".sql")).sort()}o(p,"sqlFiles");function $(t){return t.replaceAll('"public".',"")}o($,"normalizeGeneratedSql");async function x(t){const e=t.generatedDir??"backend/.drizzle",n=t.migrationsDir??"backend/migrations",h=await p(s(t.root,e)),b=await p(s(t.root,n)),l=new Map;let c=0;for(const r of b){const a=f(r);a&&(l.set(a.tag,r),c=Math.max(c,a.ordinal))}const i={copied:[],problems:[]};for(const r of h){const a=f(r);if(!a){i.problems.push(`${e}/${r}: not named <ordinal>_<tag>.sql`);continue}const g=$(await m(s(t.root,e,r),"utf8")),u=l.get(a.tag);if(u){await m(s(t.root,n,u),"utf8")!==g&&i.problems.push(`${n}/${u} differs from the regenerated ${r}. An applied migration is frozen \u2014 add a new one instead of editing it.`);continue}c+=1;const d=`${String(c).padStart(4,"0")}_${a.tag}.sql`;if(t.check){i.problems.push(`${n}/${d} is missing; run \`tego-plugin migrations sync\`.`);continue}await y(s(t.root,n,d),g,"utf8"),l.set(a.tag,d),i.copied.push({from:`${e}/${r}`,to:`${n}/${d}`})}return i}o(x,"syncMigrations");export{$ as normalizeGeneratedSql,x as syncMigrations};
package/dist/pack.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var t=Object.defineProperty;var e=(r,n)=>t(r,"name",{value:n,configurable:!0});var chunkPWSTCQRN_cjs=require("./chunk-PWSTCQRN.cjs");require("./chunk-W7C357A6.cjs"),require("./chunk-3WA3M347.cjs"),require("./chunk-ROFUQLOZ.cjs"),require("./chunk-C2OCOPZQ.cjs"),require("./chunk-AJY7ZHXK.cjs"),require("./chunk-OP64Y4IN.cjs"),Object.defineProperty(exports,"buildAgentTemplate",{enumerable:!0,get:e(function(){return chunkPWSTCQRN_cjs.buildAgentTemplate},"get")}),Object.defineProperty(exports,"buildPluginBackend",{enumerable:!0,get:e(function(){return chunkPWSTCQRN_cjs.buildPluginBackend},"get")}),Object.defineProperty(exports,"buildPluginTemplates",{enumerable:!0,get:e(function(){return chunkPWSTCQRN_cjs.buildPluginTemplates},"get")}),Object.defineProperty(exports,"lockPlugin",{enumerable:!0,get:e(function(){return chunkPWSTCQRN_cjs.lockPlugin},"get")}),Object.defineProperty(exports,"packPlugin",{enumerable:!0,get:e(function(){return chunkPWSTCQRN_cjs.packPlugin},"get")}),Object.defineProperty(exports,"readManifest",{enumerable:!0,get:e(function(){return chunkPWSTCQRN_cjs.readManifest},"get")}),Object.defineProperty(exports,"watchPluginFrontend",{enumerable:!0,get:e(function(){return chunkPWSTCQRN_cjs.watchPluginFrontend},"get")});
1
+ "use strict";var u=Object.defineProperty;var e=(r,n)=>u(r,"name",{value:n,configurable:!0});var chunk4LKRXDYY_cjs=require("./chunk-4LKRXDYY.cjs");require("./chunk-HZ4YWRYX.cjs"),require("./chunk-SKNPNPJP.cjs"),require("./chunk-45Y4CR4R.cjs"),require("./chunk-2P6UEAPV.cjs"),require("./chunk-N4SXZZPY.cjs"),require("./chunk-6HNG5OZI.cjs"),require("./chunk-AJY7ZHXK.cjs"),require("./chunk-OP64Y4IN.cjs"),Object.defineProperty(exports,"buildAgentTemplate",{enumerable:!0,get:e(function(){return chunk4LKRXDYY_cjs.buildAgentTemplate},"get")}),Object.defineProperty(exports,"buildPluginBackend",{enumerable:!0,get:e(function(){return chunk4LKRXDYY_cjs.buildPluginBackend},"get")}),Object.defineProperty(exports,"buildPluginTemplates",{enumerable:!0,get:e(function(){return chunk4LKRXDYY_cjs.buildPluginTemplates},"get")}),Object.defineProperty(exports,"lockPlugin",{enumerable:!0,get:e(function(){return chunk4LKRXDYY_cjs.lockPlugin},"get")}),Object.defineProperty(exports,"packPlugin",{enumerable:!0,get:e(function(){return chunk4LKRXDYY_cjs.packPlugin},"get")}),Object.defineProperty(exports,"readManifest",{enumerable:!0,get:e(function(){return chunk4LKRXDYY_cjs.readManifest},"get")}),Object.defineProperty(exports,"watchPluginFrontend",{enumerable:!0,get:e(function(){return chunk4LKRXDYY_cjs.watchPluginFrontend},"get")});
package/dist/pack.d.cts CHANGED
@@ -85,6 +85,11 @@ interface PackPluginOptions {
85
85
  };
86
86
  /** Where to report progress. Defaults to `console.log`. Pass `null` to mute. */
87
87
  log?: ((message: string) => void) | null;
88
+ /**
89
+ * Run `tego-plugin doctor` first (default). Packing stops on the problems
90
+ * upload would refuse anyway; the rest are summarized, not fatal.
91
+ */
92
+ doctor?: boolean;
88
93
  }
89
94
  interface PackedPlugin {
90
95
  /** Absolute path of the archive. */
package/dist/pack.d.ts CHANGED
@@ -85,6 +85,11 @@ interface PackPluginOptions {
85
85
  };
86
86
  /** Where to report progress. Defaults to `console.log`. Pass `null` to mute. */
87
87
  log?: ((message: string) => void) | null;
88
+ /**
89
+ * Run `tego-plugin doctor` first (default). Packing stops on the problems
90
+ * upload would refuse anyway; the rest are summarized, not fatal.
91
+ */
92
+ doctor?: boolean;
88
93
  }
89
94
  interface PackedPlugin {
90
95
  /** Absolute path of the archive. */
package/dist/pack.js CHANGED
@@ -1 +1 @@
1
- export{buildAgentTemplate,buildPluginBackend,buildPluginTemplates,lockPlugin,packPlugin,readManifest,watchPluginFrontend}from"./chunk-P2Q2AKWP.js";import"./chunk-7K37PVGV.js";import"./chunk-5CU33JVY.js";import"./chunk-BTHXQWHT.js";import"./chunk-7XHF3YSK.js";import"./chunk-VMCGDDGP.js";import"./chunk-SNUCO2MK.js";
1
+ export{buildAgentTemplate,buildPluginBackend,buildPluginTemplates,lockPlugin,packPlugin,readManifest,watchPluginFrontend}from"./chunk-FCYAAOHC.js";import"./chunk-I5Z3ECC4.js";import"./chunk-EIVA5BR6.js";import"./chunk-2NTAWYCG.js";import"./chunk-IVJECPGG.js";import"./chunk-INCA3GFW.js";import"./chunk-56QOZQTY.js";import"./chunk-VMCGDDGP.js";import"./chunk-SNUCO2MK.js";
package/dist/publish.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var $=Object.defineProperty;var s=(e,a)=>$(e,"name",{value:a,configurable:!0});var chunkPWSTCQRN_cjs=require("./chunk-PWSTCQRN.cjs");require("./chunk-W7C357A6.cjs"),require("./chunk-3WA3M347.cjs");var chunkROFUQLOZ_cjs=require("./chunk-ROFUQLOZ.cjs");require("./chunk-C2OCOPZQ.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 chunkPWSTCQRN_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 c=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,c.uploadUrl,u,t),n("\u203A inspecting package");const l=await r("POST","/admin/runtime-plugins/inspect",{uploadToken:c.uploadToken});n(` ${l.pluginId}@${l.semanticVersion} \u2014 ${describeParts(l)}${l.isUpgrade?" (upgrade)":""}${l.requiresConfig?", needs config":""}`),n("\u203A finalizing release");const g=await r("POST","/admin/runtime-plugins/upload",{uploadToken:c.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=chunkROFUQLOZ_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:l,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,c){const l=await n(`${t}${API_PREFIX}${o}`,{method:u,headers:{authorization:`Bearer ${a}`,...c===void 0?{}:{"content-type":"application/json"}},...c===void 0?{}:{body:JSON.stringify(c)}});return unwrap(l,`${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 s=(e,a)=>$(e,"name",{value:a,configurable:!0});var chunk4LKRXDYY_cjs=require("./chunk-4LKRXDYY.cjs");require("./chunk-HZ4YWRYX.cjs"),require("./chunk-SKNPNPJP.cjs"),require("./chunk-45Y4CR4R.cjs");var chunk2P6UEAPV_cjs=require("./chunk-2P6UEAPV.cjs");require("./chunk-N4SXZZPY.cjs"),require("./chunk-6HNG5OZI.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 chunk4LKRXDYY_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;
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-P2Q2AKWP.js";import"./chunk-7K37PVGV.js";import"./chunk-5CU33JVY.js";import{resolvePluginScope as P}from"./chunk-BTHXQWHT.js";import"./chunk-7XHF3YSK.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 f(t,e)}o(T,"publishPlugin");async function f(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(f,"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 m(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 m(s,"PUT upload")}o(S,"putArchive");async function m(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(m,"unwrap");export{f as publishPackedPlugin,T as publishPlugin};
1
+ var h=Object.defineProperty;var o=(e,a)=>h(e,"name",{value:a,configurable:!0});import{packPlugin as v}from"./chunk-FCYAAOHC.js";import"./chunk-I5Z3ECC4.js";import"./chunk-EIVA5BR6.js";import"./chunk-2NTAWYCG.js";import{resolvePluginScope as P}from"./chunk-IVJECPGG.js";import"./chunk-INCA3GFW.js";import"./chunk-56QOZQTY.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};