@ubiquity-os/plugin-sdk 1.0.11 → 1.1.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.
package/dist/index.d.mts CHANGED
@@ -3,51 +3,57 @@ import { EmitterWebhookEventName, EmitterWebhookEvent } from '@octokit/webhooks'
3
3
  import { TAnySchema } from '@sinclair/typebox';
4
4
  import { Logs, LogLevel, LogReturn } from '@ubiquity-os/ubiquity-os-logger';
5
5
  import { Hono } from 'hono';
6
- import * as _octokit_core_dist_types_types from '@octokit/core/dist-types/types';
7
- import * as _octokit_plugin_paginate_graphql from '@octokit/plugin-paginate-graphql';
8
- import * as _octokit_plugin_rest_endpoint_methods from '@octokit/plugin-rest-endpoint-methods';
9
- import * as _octokit_plugin_paginate_rest from '@octokit/plugin-paginate-rest';
10
- import * as _octokit_request_error from '@octokit/request-error';
11
- import { Octokit } from '@octokit/core';
6
+ import { customOctokit } from './octokit.mjs';
12
7
  import { Manifest } from './manifest.mjs';
8
+ import '@octokit/core/dist-types/types';
9
+ import '@octokit/plugin-paginate-graphql';
10
+ import '@octokit/plugin-rest-endpoint-methods';
11
+ import '@octokit/plugin-paginate-rest';
12
+ import '@octokit/request-error';
13
+ import '@octokit/core';
13
14
 
14
- declare const customOctokit: typeof Octokit & _octokit_core_dist_types_types.Constructor<{
15
- retry: {
16
- retryRequest: (error: _octokit_request_error.RequestError, retries: number, retryAfter: number) => _octokit_request_error.RequestError;
17
- };
18
- } & {
19
- paginate: _octokit_plugin_paginate_rest.PaginateInterface;
20
- } & _octokit_plugin_rest_endpoint_methods.Api & _octokit_plugin_paginate_graphql.paginateGraphQLInterface>;
21
-
22
- interface Context<TConfig = unknown, TEnv = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName> {
15
+ interface Context<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName> {
23
16
  eventName: TSupportedEvents;
24
17
  payload: {
25
18
  [K in TSupportedEvents]: K extends EmitterWebhookEventName ? EmitterWebhookEvent<K> : never;
26
19
  }[TSupportedEvents]["payload"];
20
+ command: TCommand | null;
27
21
  octokit: InstanceType<typeof customOctokit>;
28
22
  config: TConfig;
29
23
  env: TEnv;
30
24
  logger: Logs;
31
25
  }
32
26
 
27
+ type Return = Record<string, unknown> | undefined | void;
28
+ type HandlerReturn = Promise<Return> | Return;
29
+
33
30
  interface Options$1 {
34
31
  kernelPublicKey?: string;
35
32
  logLevel?: LogLevel;
36
33
  postCommentOnError?: boolean;
37
34
  settingsSchema?: TAnySchema;
38
35
  envSchema?: TAnySchema;
36
+ commandSchema?: TAnySchema;
37
+ /**
38
+ * @deprecated This disables signature verification - only for local development
39
+ */
39
40
  bypassSignatureVerification?: boolean;
40
41
  }
41
- declare function createPlugin<TConfig = unknown, TEnv = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TSupportedEvents>) => Promise<Record<string, unknown> | undefined>, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
42
+ declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
42
43
 
43
44
  interface Options {
44
45
  logLevel?: LogLevel;
45
46
  postCommentOnError?: boolean;
46
47
  settingsSchema?: TAnySchema;
47
48
  envSchema?: TAnySchema;
49
+ commandSchema?: TAnySchema;
48
50
  kernelPublicKey?: string;
51
+ /**
52
+ * @deprecated This disables signature verification - only for local development
53
+ */
54
+ bypassSignatureVerification?: boolean;
49
55
  }
50
- declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TSupportedEvents>) => Promise<Record<string, unknown> | undefined>, options?: Options): Promise<void>;
56
+ declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options): Promise<void>;
51
57
 
52
58
  /**
53
59
  * Posts a comment on a GitHub issue if the issue exists in the context payload, embedding structured metadata to it.
package/dist/index.d.ts CHANGED
@@ -3,51 +3,57 @@ import { EmitterWebhookEventName, EmitterWebhookEvent } from '@octokit/webhooks'
3
3
  import { TAnySchema } from '@sinclair/typebox';
4
4
  import { Logs, LogLevel, LogReturn } from '@ubiquity-os/ubiquity-os-logger';
5
5
  import { Hono } from 'hono';
6
- import * as _octokit_core_dist_types_types from '@octokit/core/dist-types/types';
7
- import * as _octokit_plugin_paginate_graphql from '@octokit/plugin-paginate-graphql';
8
- import * as _octokit_plugin_rest_endpoint_methods from '@octokit/plugin-rest-endpoint-methods';
9
- import * as _octokit_plugin_paginate_rest from '@octokit/plugin-paginate-rest';
10
- import * as _octokit_request_error from '@octokit/request-error';
11
- import { Octokit } from '@octokit/core';
6
+ import { customOctokit } from './octokit.js';
12
7
  import { Manifest } from './manifest.js';
8
+ import '@octokit/core/dist-types/types';
9
+ import '@octokit/plugin-paginate-graphql';
10
+ import '@octokit/plugin-rest-endpoint-methods';
11
+ import '@octokit/plugin-paginate-rest';
12
+ import '@octokit/request-error';
13
+ import '@octokit/core';
13
14
 
14
- declare const customOctokit: typeof Octokit & _octokit_core_dist_types_types.Constructor<{
15
- retry: {
16
- retryRequest: (error: _octokit_request_error.RequestError, retries: number, retryAfter: number) => _octokit_request_error.RequestError;
17
- };
18
- } & {
19
- paginate: _octokit_plugin_paginate_rest.PaginateInterface;
20
- } & _octokit_plugin_rest_endpoint_methods.Api & _octokit_plugin_paginate_graphql.paginateGraphQLInterface>;
21
-
22
- interface Context<TConfig = unknown, TEnv = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName> {
15
+ interface Context<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName> {
23
16
  eventName: TSupportedEvents;
24
17
  payload: {
25
18
  [K in TSupportedEvents]: K extends EmitterWebhookEventName ? EmitterWebhookEvent<K> : never;
26
19
  }[TSupportedEvents]["payload"];
20
+ command: TCommand | null;
27
21
  octokit: InstanceType<typeof customOctokit>;
28
22
  config: TConfig;
29
23
  env: TEnv;
30
24
  logger: Logs;
31
25
  }
32
26
 
27
+ type Return = Record<string, unknown> | undefined | void;
28
+ type HandlerReturn = Promise<Return> | Return;
29
+
33
30
  interface Options$1 {
34
31
  kernelPublicKey?: string;
35
32
  logLevel?: LogLevel;
36
33
  postCommentOnError?: boolean;
37
34
  settingsSchema?: TAnySchema;
38
35
  envSchema?: TAnySchema;
36
+ commandSchema?: TAnySchema;
37
+ /**
38
+ * @deprecated This disables signature verification - only for local development
39
+ */
39
40
  bypassSignatureVerification?: boolean;
40
41
  }
41
- declare function createPlugin<TConfig = unknown, TEnv = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TSupportedEvents>) => Promise<Record<string, unknown> | undefined>, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
42
+ declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
42
43
 
43
44
  interface Options {
44
45
  logLevel?: LogLevel;
45
46
  postCommentOnError?: boolean;
46
47
  settingsSchema?: TAnySchema;
47
48
  envSchema?: TAnySchema;
49
+ commandSchema?: TAnySchema;
48
50
  kernelPublicKey?: string;
51
+ /**
52
+ * @deprecated This disables signature verification - only for local development
53
+ */
54
+ bypassSignatureVerification?: boolean;
49
55
  }
50
- declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TSupportedEvents>) => Promise<Record<string, unknown> | undefined>, options?: Options): Promise<void>;
56
+ declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options): Promise<void>;
51
57
 
52
58
  /**
53
59
  * Posts a comment on a GitHub issue if the issue exists in the context payload, embedding structured metadata to it.
package/dist/index.js CHANGED
@@ -133,7 +133,8 @@ async function verifySignature(publicKeyPem, inputs, signature) {
133
133
  eventPayload: inputs.eventPayload,
134
134
  settings: inputs.settings,
135
135
  authToken: inputs.authToken,
136
- ref: inputs.ref
136
+ ref: inputs.ref,
137
+ command: inputs.command
137
138
  };
138
139
  const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").trim();
139
140
  const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
@@ -161,16 +162,11 @@ var inputSchema = import_typebox.Type.Object({
161
162
  stateId: import_typebox.Type.String(),
162
163
  eventName: import_typebox.Type.String(),
163
164
  eventPayload: import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any()),
165
+ command: import_typebox.Type.Union([import_typebox.Type.Null(), import_typebox.Type.Object({ name: import_typebox.Type.String(), parameters: import_typebox.Type.Unknown() })]),
164
166
  authToken: import_typebox.Type.String(),
165
167
  settings: import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any()),
166
168
  ref: import_typebox.Type.String(),
167
- signature: import_typebox.Type.String(),
168
- bypassSignatureVerification: import_typebox.Type.Optional(
169
- import_typebox.Type.Boolean({
170
- default: false,
171
- description: "Bypass signature verification (caution: only use this if you know what you're doing)"
172
- })
173
- )
169
+ signature: import_typebox.Type.String()
174
170
  });
175
171
  function createPlugin(handler, manifest, options) {
176
172
  const pluginOptions = {
@@ -178,7 +174,9 @@ function createPlugin(handler, manifest, options) {
178
174
  logLevel: options?.logLevel ?? import_ubiquity_os_logger.LOG_LEVEL.INFO,
179
175
  postCommentOnError: options?.postCommentOnError ?? true,
180
176
  settingsSchema: options?.settingsSchema,
181
- envSchema: options?.envSchema
177
+ envSchema: options?.envSchema,
178
+ commandSchema: options?.commandSchema,
179
+ bypassSignatureVerification: options?.bypassSignatureVerification || false
182
180
  };
183
181
  const app = new import_hono.Hono();
184
182
  app.get("/manifest.json", (ctx) => {
@@ -191,12 +189,12 @@ function createPlugin(handler, manifest, options) {
191
189
  const body = await ctx.req.json();
192
190
  const inputSchemaErrors = [...import_value.Value.Errors(inputSchema, body)];
193
191
  if (inputSchemaErrors.length) {
194
- console.dir(inputSchemaErrors, { depth: null });
192
+ console.log(inputSchemaErrors, { depth: null });
195
193
  throw new import_http_exception.HTTPException(400, { message: "Invalid body" });
196
194
  }
197
195
  const inputs = import_value.Value.Decode(inputSchema, body);
198
196
  const signature = inputs.signature;
199
- if (!options?.bypassSignatureVerification && !await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
197
+ if (!pluginOptions.bypassSignatureVerification && !await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
200
198
  throw new import_http_exception.HTTPException(400, { message: "Invalid signature" });
201
199
  }
202
200
  let config2;
@@ -204,7 +202,7 @@ function createPlugin(handler, manifest, options) {
204
202
  try {
205
203
  config2 = import_value.Value.Decode(pluginOptions.settingsSchema, import_value.Value.Default(pluginOptions.settingsSchema, inputs.settings));
206
204
  } catch (e) {
207
- console.dir(...import_value.Value.Errors(pluginOptions.settingsSchema, inputs.settings), { depth: null });
205
+ console.log(...import_value.Value.Errors(pluginOptions.settingsSchema, inputs.settings), { depth: null });
208
206
  throw e;
209
207
  }
210
208
  } else {
@@ -216,15 +214,27 @@ function createPlugin(handler, manifest, options) {
216
214
  try {
217
215
  env = import_value.Value.Decode(pluginOptions.envSchema, import_value.Value.Default(pluginOptions.envSchema, honoEnvironment));
218
216
  } catch (e) {
219
- console.dir(...import_value.Value.Errors(pluginOptions.envSchema, honoEnvironment), { depth: null });
217
+ console.log(...import_value.Value.Errors(pluginOptions.envSchema, honoEnvironment), { depth: null });
220
218
  throw e;
221
219
  }
222
220
  } else {
223
221
  env = ctx.env;
224
222
  }
223
+ let command = null;
224
+ if (inputs.command && pluginOptions.commandSchema) {
225
+ try {
226
+ command = import_value.Value.Decode(pluginOptions.commandSchema, import_value.Value.Default(pluginOptions.commandSchema, inputs.command));
227
+ } catch (e) {
228
+ console.log(...import_value.Value.Errors(pluginOptions.commandSchema, inputs.command), { depth: null });
229
+ throw e;
230
+ }
231
+ } else if (inputs.command) {
232
+ command = inputs.command;
233
+ }
225
234
  const context2 = {
226
235
  eventName: inputs.eventName,
227
236
  payload: inputs.eventPayload,
237
+ command,
228
238
  octokit: new customOctokit({ auth: inputs.authToken }),
229
239
  config: config2,
230
240
  env,
@@ -232,7 +242,7 @@ function createPlugin(handler, manifest, options) {
232
242
  };
233
243
  try {
234
244
  const result = await handler(context2);
235
- return ctx.json({ stateId: inputs.stateId, output: result });
245
+ return ctx.json({ stateId: inputs.stateId, output: result ?? {} });
236
246
  } catch (error) {
237
247
  console.error(error);
238
248
  let loggerError;
@@ -255,19 +265,36 @@ function createPlugin(handler, manifest, options) {
255
265
  // src/actions.ts
256
266
  var core = __toESM(require("@actions/core"));
257
267
  var github = __toESM(require("@actions/github"));
258
- var import_typebox2 = require("@sinclair/typebox");
259
- var import_value2 = require("@sinclair/typebox/value");
268
+ var import_typebox4 = require("@sinclair/typebox");
269
+ var import_value3 = require("@sinclair/typebox/value");
260
270
  var import_ubiquity_os_logger2 = require("@ubiquity-os/ubiquity-os-logger");
261
271
  var import_dotenv = require("dotenv");
272
+
273
+ // src/types/util.ts
274
+ var import_typebox2 = require("@sinclair/typebox");
275
+ var import_value2 = require("@sinclair/typebox/value");
276
+ function jsonType(type) {
277
+ return import_typebox2.Type.Transform(import_typebox2.Type.String()).Decode((value) => {
278
+ const parsed = JSON.parse(value);
279
+ return import_value2.Value.Decode(type, import_value2.Value.Default(type, parsed));
280
+ }).Encode((value) => JSON.stringify(value));
281
+ }
282
+
283
+ // src/types/command.ts
284
+ var import_typebox3 = require("@sinclair/typebox");
285
+ var commandCallSchema = import_typebox3.Type.Union([import_typebox3.Type.Null(), import_typebox3.Type.Object({ name: import_typebox3.Type.String(), parameters: import_typebox3.Type.Unknown() })]);
286
+
287
+ // src/actions.ts
262
288
  (0, import_dotenv.config)();
263
- var inputSchema2 = import_typebox2.Type.Object({
264
- stateId: import_typebox2.Type.String(),
265
- eventName: import_typebox2.Type.String(),
266
- eventPayload: import_typebox2.Type.String(),
267
- authToken: import_typebox2.Type.String(),
268
- settings: import_typebox2.Type.String(),
269
- ref: import_typebox2.Type.String(),
270
- signature: import_typebox2.Type.String()
289
+ var inputSchema2 = import_typebox4.Type.Object({
290
+ stateId: import_typebox4.Type.String(),
291
+ eventName: import_typebox4.Type.String(),
292
+ eventPayload: jsonType(import_typebox4.Type.Record(import_typebox4.Type.String(), import_typebox4.Type.Any())),
293
+ command: jsonType(commandCallSchema),
294
+ authToken: import_typebox4.Type.String(),
295
+ settings: jsonType(import_typebox4.Type.Record(import_typebox4.Type.String(), import_typebox4.Type.Any())),
296
+ ref: import_typebox4.Type.String(),
297
+ signature: import_typebox4.Type.String()
271
298
  });
272
299
  async function createActionsPlugin(handler, options) {
273
300
  const pluginOptions = {
@@ -275,51 +302,66 @@ async function createActionsPlugin(handler, options) {
275
302
  postCommentOnError: options?.postCommentOnError ?? true,
276
303
  settingsSchema: options?.settingsSchema,
277
304
  envSchema: options?.envSchema,
278
- kernelPublicKey: options?.kernelPublicKey ?? KERNEL_PUBLIC_KEY
305
+ commandSchema: options?.commandSchema,
306
+ kernelPublicKey: options?.kernelPublicKey ?? KERNEL_PUBLIC_KEY,
307
+ bypassSignatureVerification: options?.bypassSignatureVerification || false
279
308
  };
280
309
  const pluginGithubToken = process.env.PLUGIN_GITHUB_TOKEN;
281
310
  if (!pluginGithubToken) {
282
311
  core.setFailed("Error: PLUGIN_GITHUB_TOKEN env is not set");
283
312
  return;
284
313
  }
314
+ const body = github.context.payload.inputs;
315
+ const signature = body.signature;
316
+ if (!pluginOptions.bypassSignatureVerification && !await verifySignature(pluginOptions.kernelPublicKey, body, signature)) {
317
+ core.setFailed(`Error: Invalid signature`);
318
+ return;
319
+ }
285
320
  const inputPayload = github.context.payload.inputs;
286
- const inputSchemaErrors = [...import_value2.Value.Errors(inputSchema2, inputPayload)];
321
+ const inputSchemaErrors = [...import_value3.Value.Errors(inputSchema2, inputPayload)];
287
322
  if (inputSchemaErrors.length) {
288
323
  console.dir(inputSchemaErrors, { depth: null });
289
324
  core.setFailed(`Error: Invalid inputs payload: ${inputSchemaErrors.join(",")}`);
290
325
  return;
291
326
  }
292
- const inputs = import_value2.Value.Decode(inputSchema2, inputPayload);
293
- const signature = inputs.signature;
294
- if (!await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
295
- core.setFailed(`Error: Invalid signature`);
296
- return;
297
- }
327
+ const inputs = import_value3.Value.Decode(inputSchema2, inputPayload);
298
328
  let config2;
299
329
  if (pluginOptions.settingsSchema) {
300
330
  try {
301
- config2 = import_value2.Value.Decode(pluginOptions.settingsSchema, import_value2.Value.Default(pluginOptions.settingsSchema, JSON.parse(inputs.settings)));
331
+ config2 = import_value3.Value.Decode(pluginOptions.settingsSchema, import_value3.Value.Default(pluginOptions.settingsSchema, inputs.settings));
302
332
  } catch (e) {
303
- console.dir(...import_value2.Value.Errors(pluginOptions.settingsSchema, JSON.parse(inputs.settings)), { depth: null });
333
+ console.dir(...import_value3.Value.Errors(pluginOptions.settingsSchema, inputs.settings), { depth: null });
304
334
  throw e;
305
335
  }
306
336
  } else {
307
- config2 = JSON.parse(inputs.settings);
337
+ config2 = inputs.settings;
308
338
  }
309
339
  let env;
310
340
  if (pluginOptions.envSchema) {
311
341
  try {
312
- env = import_value2.Value.Decode(pluginOptions.envSchema, import_value2.Value.Default(pluginOptions.envSchema, process.env));
342
+ env = import_value3.Value.Decode(pluginOptions.envSchema, import_value3.Value.Default(pluginOptions.envSchema, process.env));
313
343
  } catch (e) {
314
- console.dir(...import_value2.Value.Errors(pluginOptions.envSchema, process.env), { depth: null });
344
+ console.dir(...import_value3.Value.Errors(pluginOptions.envSchema, process.env), { depth: null });
315
345
  throw e;
316
346
  }
317
347
  } else {
318
348
  env = process.env;
319
349
  }
350
+ let command = null;
351
+ if (inputs.command && pluginOptions.commandSchema) {
352
+ try {
353
+ command = import_value3.Value.Decode(pluginOptions.commandSchema, import_value3.Value.Default(pluginOptions.commandSchema, inputs.command));
354
+ } catch (e) {
355
+ console.dir(...import_value3.Value.Errors(pluginOptions.commandSchema, inputs.command), { depth: null });
356
+ throw e;
357
+ }
358
+ } else if (inputs.command) {
359
+ command = inputs.command;
360
+ }
320
361
  const context2 = {
321
362
  eventName: inputs.eventName,
322
- payload: JSON.parse(inputs.eventPayload),
363
+ payload: inputs.eventPayload,
364
+ command,
323
365
  octokit: new customOctokit({ auth: inputs.authToken }),
324
366
  config: config2,
325
367
  env,
package/dist/index.mjs CHANGED
@@ -95,7 +95,8 @@ async function verifySignature(publicKeyPem, inputs, signature) {
95
95
  eventPayload: inputs.eventPayload,
96
96
  settings: inputs.settings,
97
97
  authToken: inputs.authToken,
98
- ref: inputs.ref
98
+ ref: inputs.ref,
99
+ command: inputs.command
99
100
  };
100
101
  const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").trim();
101
102
  const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
@@ -123,16 +124,11 @@ var inputSchema = T.Object({
123
124
  stateId: T.String(),
124
125
  eventName: T.String(),
125
126
  eventPayload: T.Record(T.String(), T.Any()),
127
+ command: T.Union([T.Null(), T.Object({ name: T.String(), parameters: T.Unknown() })]),
126
128
  authToken: T.String(),
127
129
  settings: T.Record(T.String(), T.Any()),
128
130
  ref: T.String(),
129
- signature: T.String(),
130
- bypassSignatureVerification: T.Optional(
131
- T.Boolean({
132
- default: false,
133
- description: "Bypass signature verification (caution: only use this if you know what you're doing)"
134
- })
135
- )
131
+ signature: T.String()
136
132
  });
137
133
  function createPlugin(handler, manifest, options) {
138
134
  const pluginOptions = {
@@ -140,7 +136,9 @@ function createPlugin(handler, manifest, options) {
140
136
  logLevel: options?.logLevel ?? LOG_LEVEL.INFO,
141
137
  postCommentOnError: options?.postCommentOnError ?? true,
142
138
  settingsSchema: options?.settingsSchema,
143
- envSchema: options?.envSchema
139
+ envSchema: options?.envSchema,
140
+ commandSchema: options?.commandSchema,
141
+ bypassSignatureVerification: options?.bypassSignatureVerification || false
144
142
  };
145
143
  const app = new Hono();
146
144
  app.get("/manifest.json", (ctx) => {
@@ -153,12 +151,12 @@ function createPlugin(handler, manifest, options) {
153
151
  const body = await ctx.req.json();
154
152
  const inputSchemaErrors = [...Value.Errors(inputSchema, body)];
155
153
  if (inputSchemaErrors.length) {
156
- console.dir(inputSchemaErrors, { depth: null });
154
+ console.log(inputSchemaErrors, { depth: null });
157
155
  throw new HTTPException(400, { message: "Invalid body" });
158
156
  }
159
157
  const inputs = Value.Decode(inputSchema, body);
160
158
  const signature = inputs.signature;
161
- if (!options?.bypassSignatureVerification && !await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
159
+ if (!pluginOptions.bypassSignatureVerification && !await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
162
160
  throw new HTTPException(400, { message: "Invalid signature" });
163
161
  }
164
162
  let config2;
@@ -166,7 +164,7 @@ function createPlugin(handler, manifest, options) {
166
164
  try {
167
165
  config2 = Value.Decode(pluginOptions.settingsSchema, Value.Default(pluginOptions.settingsSchema, inputs.settings));
168
166
  } catch (e) {
169
- console.dir(...Value.Errors(pluginOptions.settingsSchema, inputs.settings), { depth: null });
167
+ console.log(...Value.Errors(pluginOptions.settingsSchema, inputs.settings), { depth: null });
170
168
  throw e;
171
169
  }
172
170
  } else {
@@ -178,15 +176,27 @@ function createPlugin(handler, manifest, options) {
178
176
  try {
179
177
  env = Value.Decode(pluginOptions.envSchema, Value.Default(pluginOptions.envSchema, honoEnvironment));
180
178
  } catch (e) {
181
- console.dir(...Value.Errors(pluginOptions.envSchema, honoEnvironment), { depth: null });
179
+ console.log(...Value.Errors(pluginOptions.envSchema, honoEnvironment), { depth: null });
182
180
  throw e;
183
181
  }
184
182
  } else {
185
183
  env = ctx.env;
186
184
  }
185
+ let command = null;
186
+ if (inputs.command && pluginOptions.commandSchema) {
187
+ try {
188
+ command = Value.Decode(pluginOptions.commandSchema, Value.Default(pluginOptions.commandSchema, inputs.command));
189
+ } catch (e) {
190
+ console.log(...Value.Errors(pluginOptions.commandSchema, inputs.command), { depth: null });
191
+ throw e;
192
+ }
193
+ } else if (inputs.command) {
194
+ command = inputs.command;
195
+ }
187
196
  const context2 = {
188
197
  eventName: inputs.eventName,
189
198
  payload: inputs.eventPayload,
199
+ command,
190
200
  octokit: new customOctokit({ auth: inputs.authToken }),
191
201
  config: config2,
192
202
  env,
@@ -194,7 +204,7 @@ function createPlugin(handler, manifest, options) {
194
204
  };
195
205
  try {
196
206
  const result = await handler(context2);
197
- return ctx.json({ stateId: inputs.stateId, output: result });
207
+ return ctx.json({ stateId: inputs.stateId, output: result ?? {} });
198
208
  } catch (error) {
199
209
  console.error(error);
200
210
  let loggerError;
@@ -217,19 +227,36 @@ function createPlugin(handler, manifest, options) {
217
227
  // src/actions.ts
218
228
  import * as core from "@actions/core";
219
229
  import * as github from "@actions/github";
220
- import { Type as T2 } from "@sinclair/typebox";
221
- import { Value as Value2 } from "@sinclair/typebox/value";
230
+ import { Type as T3 } from "@sinclair/typebox";
231
+ import { Value as Value3 } from "@sinclair/typebox/value";
222
232
  import { LOG_LEVEL as LOG_LEVEL2, LogReturn as LogReturn2, Logs as Logs2 } from "@ubiquity-os/ubiquity-os-logger";
223
233
  import { config } from "dotenv";
234
+
235
+ // src/types/util.ts
236
+ import { Type } from "@sinclair/typebox";
237
+ import { Value as Value2 } from "@sinclair/typebox/value";
238
+ function jsonType(type) {
239
+ return Type.Transform(Type.String()).Decode((value) => {
240
+ const parsed = JSON.parse(value);
241
+ return Value2.Decode(type, Value2.Default(type, parsed));
242
+ }).Encode((value) => JSON.stringify(value));
243
+ }
244
+
245
+ // src/types/command.ts
246
+ import { Type as T2 } from "@sinclair/typebox";
247
+ var commandCallSchema = T2.Union([T2.Null(), T2.Object({ name: T2.String(), parameters: T2.Unknown() })]);
248
+
249
+ // src/actions.ts
224
250
  config();
225
- var inputSchema2 = T2.Object({
226
- stateId: T2.String(),
227
- eventName: T2.String(),
228
- eventPayload: T2.String(),
229
- authToken: T2.String(),
230
- settings: T2.String(),
231
- ref: T2.String(),
232
- signature: T2.String()
251
+ var inputSchema2 = T3.Object({
252
+ stateId: T3.String(),
253
+ eventName: T3.String(),
254
+ eventPayload: jsonType(T3.Record(T3.String(), T3.Any())),
255
+ command: jsonType(commandCallSchema),
256
+ authToken: T3.String(),
257
+ settings: jsonType(T3.Record(T3.String(), T3.Any())),
258
+ ref: T3.String(),
259
+ signature: T3.String()
233
260
  });
234
261
  async function createActionsPlugin(handler, options) {
235
262
  const pluginOptions = {
@@ -237,51 +264,66 @@ async function createActionsPlugin(handler, options) {
237
264
  postCommentOnError: options?.postCommentOnError ?? true,
238
265
  settingsSchema: options?.settingsSchema,
239
266
  envSchema: options?.envSchema,
240
- kernelPublicKey: options?.kernelPublicKey ?? KERNEL_PUBLIC_KEY
267
+ commandSchema: options?.commandSchema,
268
+ kernelPublicKey: options?.kernelPublicKey ?? KERNEL_PUBLIC_KEY,
269
+ bypassSignatureVerification: options?.bypassSignatureVerification || false
241
270
  };
242
271
  const pluginGithubToken = process.env.PLUGIN_GITHUB_TOKEN;
243
272
  if (!pluginGithubToken) {
244
273
  core.setFailed("Error: PLUGIN_GITHUB_TOKEN env is not set");
245
274
  return;
246
275
  }
276
+ const body = github.context.payload.inputs;
277
+ const signature = body.signature;
278
+ if (!pluginOptions.bypassSignatureVerification && !await verifySignature(pluginOptions.kernelPublicKey, body, signature)) {
279
+ core.setFailed(`Error: Invalid signature`);
280
+ return;
281
+ }
247
282
  const inputPayload = github.context.payload.inputs;
248
- const inputSchemaErrors = [...Value2.Errors(inputSchema2, inputPayload)];
283
+ const inputSchemaErrors = [...Value3.Errors(inputSchema2, inputPayload)];
249
284
  if (inputSchemaErrors.length) {
250
285
  console.dir(inputSchemaErrors, { depth: null });
251
286
  core.setFailed(`Error: Invalid inputs payload: ${inputSchemaErrors.join(",")}`);
252
287
  return;
253
288
  }
254
- const inputs = Value2.Decode(inputSchema2, inputPayload);
255
- const signature = inputs.signature;
256
- if (!await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
257
- core.setFailed(`Error: Invalid signature`);
258
- return;
259
- }
289
+ const inputs = Value3.Decode(inputSchema2, inputPayload);
260
290
  let config2;
261
291
  if (pluginOptions.settingsSchema) {
262
292
  try {
263
- config2 = Value2.Decode(pluginOptions.settingsSchema, Value2.Default(pluginOptions.settingsSchema, JSON.parse(inputs.settings)));
293
+ config2 = Value3.Decode(pluginOptions.settingsSchema, Value3.Default(pluginOptions.settingsSchema, inputs.settings));
264
294
  } catch (e) {
265
- console.dir(...Value2.Errors(pluginOptions.settingsSchema, JSON.parse(inputs.settings)), { depth: null });
295
+ console.dir(...Value3.Errors(pluginOptions.settingsSchema, inputs.settings), { depth: null });
266
296
  throw e;
267
297
  }
268
298
  } else {
269
- config2 = JSON.parse(inputs.settings);
299
+ config2 = inputs.settings;
270
300
  }
271
301
  let env;
272
302
  if (pluginOptions.envSchema) {
273
303
  try {
274
- env = Value2.Decode(pluginOptions.envSchema, Value2.Default(pluginOptions.envSchema, process.env));
304
+ env = Value3.Decode(pluginOptions.envSchema, Value3.Default(pluginOptions.envSchema, process.env));
275
305
  } catch (e) {
276
- console.dir(...Value2.Errors(pluginOptions.envSchema, process.env), { depth: null });
306
+ console.dir(...Value3.Errors(pluginOptions.envSchema, process.env), { depth: null });
277
307
  throw e;
278
308
  }
279
309
  } else {
280
310
  env = process.env;
281
311
  }
312
+ let command = null;
313
+ if (inputs.command && pluginOptions.commandSchema) {
314
+ try {
315
+ command = Value3.Decode(pluginOptions.commandSchema, Value3.Default(pluginOptions.commandSchema, inputs.command));
316
+ } catch (e) {
317
+ console.dir(...Value3.Errors(pluginOptions.commandSchema, inputs.command), { depth: null });
318
+ throw e;
319
+ }
320
+ } else if (inputs.command) {
321
+ command = inputs.command;
322
+ }
282
323
  const context2 = {
283
324
  eventName: inputs.eventName,
284
- payload: JSON.parse(inputs.eventPayload),
325
+ payload: inputs.eventPayload,
326
+ command,
285
327
  octokit: new customOctokit({ auth: inputs.authToken }),
286
328
  config: config2,
287
329
  env,
@@ -5,6 +5,7 @@ declare const runEvent: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"bra
5
5
  declare const commandSchema: _sinclair_typebox.TObject<{
6
6
  description: _sinclair_typebox.TString;
7
7
  "ubiquity:example": _sinclair_typebox.TString;
8
+ parameters: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>>;
8
9
  }>;
9
10
  declare const manifestSchema: _sinclair_typebox.TObject<{
10
11
  name: _sinclair_typebox.TString;
@@ -12,9 +13,11 @@ declare const manifestSchema: _sinclair_typebox.TObject<{
12
13
  commands: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TObject<{
13
14
  description: _sinclair_typebox.TString;
14
15
  "ubiquity:example": _sinclair_typebox.TString;
16
+ parameters: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>>;
15
17
  }>>>;
16
18
  "ubiquity:listeners": _sinclair_typebox.TOptional<_sinclair_typebox.TArray<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"branch_protection_configuration" | "branch_protection_configuration.disabled" | "branch_protection_configuration.enabled" | "branch_protection_rule" | "branch_protection_rule.created" | "branch_protection_rule.deleted" | "branch_protection_rule.edited" | "check_run" | "check_run.completed" | "check_run.created" | "check_run.requested_action" | "check_run.rerequested" | "check_suite" | "check_suite.completed" | "check_suite.requested" | "check_suite.rerequested" | "code_scanning_alert" | "code_scanning_alert.appeared_in_branch" | "code_scanning_alert.closed_by_user" | "code_scanning_alert.created" | "code_scanning_alert.fixed" | "code_scanning_alert.reopened" | "code_scanning_alert.reopened_by_user" | "commit_comment" | "commit_comment.created" | "create" | "custom_property" | "custom_property.created" | "custom_property.deleted" | "custom_property.updated" | "custom_property_values" | "custom_property_values.updated" | "delete" | "dependabot_alert" | "dependabot_alert.auto_dismissed" | "dependabot_alert.auto_reopened" | "dependabot_alert.created" | "dependabot_alert.dismissed" | "dependabot_alert.fixed" | "dependabot_alert.reintroduced" | "dependabot_alert.reopened" | "deploy_key" | "deploy_key.created" | "deploy_key.deleted" | "deployment" | "deployment.created" | "deployment_protection_rule" | "deployment_protection_rule.requested" | "deployment_review" | "deployment_review.approved" | "deployment_review.rejected" | "deployment_review.requested" | "deployment_status" | "deployment_status.created" | "discussion" | "discussion.answered" | "discussion.category_changed" | "discussion.closed" | "discussion.created" | "discussion.deleted" | "discussion.edited" | "discussion.labeled" | "discussion.locked" | "discussion.pinned" | "discussion.reopened" | "discussion.transferred" | "discussion.unanswered" | "discussion.unlabeled" | "discussion.unlocked" | "discussion.unpinned" | "discussion_comment" | "discussion_comment.created" | "discussion_comment.deleted" | "discussion_comment.edited" | "fork" | "github_app_authorization" | "github_app_authorization.revoked" | "gollum" | "installation" | "installation.created" | "installation.deleted" | "installation.new_permissions_accepted" | "installation.suspend" | "installation.unsuspend" | "installation_repositories" | "installation_repositories.added" | "installation_repositories.removed" | "installation_target" | "installation_target.renamed" | "issue_comment" | "issue_comment.created" | "issue_comment.deleted" | "issue_comment.edited" | "issues" | "issues.assigned" | "issues.closed" | "issues.deleted" | "issues.demilestoned" | "issues.edited" | "issues.labeled" | "issues.locked" | "issues.milestoned" | "issues.opened" | "issues.pinned" | "issues.reopened" | "issues.transferred" | "issues.unassigned" | "issues.unlabeled" | "issues.unlocked" | "issues.unpinned" | "label" | "label.created" | "label.deleted" | "label.edited" | "marketplace_purchase" | "marketplace_purchase.cancelled" | "marketplace_purchase.changed" | "marketplace_purchase.pending_change" | "marketplace_purchase.pending_change_cancelled" | "marketplace_purchase.purchased" | "member" | "member.added" | "member.edited" | "member.removed" | "membership" | "membership.added" | "membership.removed" | "merge_group" | "merge_group.checks_requested" | "merge_group.destroyed" | "meta" | "meta.deleted" | "milestone" | "milestone.closed" | "milestone.created" | "milestone.deleted" | "milestone.edited" | "milestone.opened" | "org_block" | "org_block.blocked" | "org_block.unblocked" | "organization" | "organization.deleted" | "organization.member_added" | "organization.member_invited" | "organization.member_removed" | "organization.renamed" | "package" | "package.published" | "package.updated" | "page_build" | "personal_access_token_request" | "personal_access_token_request.approved" | "personal_access_token_request.cancelled" | "personal_access_token_request.created" | "personal_access_token_request.denied" | "ping" | "project" | "project.closed" | "project.created" | "project.deleted" | "project.edited" | "project.reopened" | "project_card" | "project_card.converted" | "project_card.created" | "project_card.deleted" | "project_card.edited" | "project_card.moved" | "project_column" | "project_column.created" | "project_column.deleted" | "project_column.edited" | "project_column.moved" | "projects_v2" | "projects_v2.closed" | "projects_v2.created" | "projects_v2.deleted" | "projects_v2.edited" | "projects_v2.reopened" | "projects_v2_item" | "projects_v2_item.archived" | "projects_v2_item.converted" | "projects_v2_item.created" | "projects_v2_item.deleted" | "projects_v2_item.edited" | "projects_v2_item.reordered" | "projects_v2_item.restored" | "public" | "pull_request" | "pull_request.assigned" | "pull_request.auto_merge_disabled" | "pull_request.auto_merge_enabled" | "pull_request.closed" | "pull_request.converted_to_draft" | "pull_request.demilestoned" | "pull_request.dequeued" | "pull_request.edited" | "pull_request.enqueued" | "pull_request.labeled" | "pull_request.locked" | "pull_request.milestoned" | "pull_request.opened" | "pull_request.ready_for_review" | "pull_request.reopened" | "pull_request.review_request_removed" | "pull_request.review_requested" | "pull_request.synchronize" | "pull_request.unassigned" | "pull_request.unlabeled" | "pull_request.unlocked" | "pull_request_review" | "pull_request_review.dismissed" | "pull_request_review.edited" | "pull_request_review.submitted" | "pull_request_review_comment" | "pull_request_review_comment.created" | "pull_request_review_comment.deleted" | "pull_request_review_comment.edited" | "pull_request_review_thread" | "pull_request_review_thread.resolved" | "pull_request_review_thread.unresolved" | "push" | "registry_package" | "registry_package.published" | "registry_package.updated" | "release" | "release.created" | "release.deleted" | "release.edited" | "release.prereleased" | "release.published" | "release.released" | "release.unpublished" | "repository" | "repository.archived" | "repository.created" | "repository.deleted" | "repository.edited" | "repository.privatized" | "repository.publicized" | "repository.renamed" | "repository.transferred" | "repository.unarchived" | "repository_advisory" | "repository_advisory.published" | "repository_advisory.reported" | "repository_dispatch" | "repository_dispatch.sample.collected" | "repository_import" | "repository_ruleset" | "repository_ruleset.created" | "repository_ruleset.deleted" | "repository_ruleset.edited" | "repository_vulnerability_alert" | "repository_vulnerability_alert.create" | "repository_vulnerability_alert.dismiss" | "repository_vulnerability_alert.reopen" | "repository_vulnerability_alert.resolve" | "secret_scanning_alert" | "secret_scanning_alert.created" | "secret_scanning_alert.reopened" | "secret_scanning_alert.resolved" | "secret_scanning_alert.revoked" | "secret_scanning_alert.validated" | "secret_scanning_alert_location" | "secret_scanning_alert_location.created" | "security_advisory" | "security_advisory.published" | "security_advisory.updated" | "security_advisory.withdrawn" | "security_and_analysis" | "sponsorship" | "sponsorship.cancelled" | "sponsorship.created" | "sponsorship.edited" | "sponsorship.pending_cancellation" | "sponsorship.pending_tier_change" | "sponsorship.tier_changed" | "star" | "star.created" | "star.deleted" | "status" | "team" | "team.added_to_repository" | "team.created" | "team.deleted" | "team.edited" | "team.removed_from_repository" | "team_add" | "watch" | "watch.started" | "workflow_dispatch" | "workflow_job" | "workflow_job.completed" | "workflow_job.in_progress" | "workflow_job.queued" | "workflow_job.waiting" | "workflow_run" | "workflow_run.completed" | "workflow_run.in_progress" | "workflow_run.requested">[]>>>;
17
19
  configuration: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>>;
20
+ skipBotEvents: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
18
21
  }>;
19
22
  type Manifest = Static<typeof manifestSchema>;
20
23
 
@@ -5,6 +5,7 @@ declare const runEvent: _sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"bra
5
5
  declare const commandSchema: _sinclair_typebox.TObject<{
6
6
  description: _sinclair_typebox.TString;
7
7
  "ubiquity:example": _sinclair_typebox.TString;
8
+ parameters: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>>;
8
9
  }>;
9
10
  declare const manifestSchema: _sinclair_typebox.TObject<{
10
11
  name: _sinclair_typebox.TString;
@@ -12,9 +13,11 @@ declare const manifestSchema: _sinclair_typebox.TObject<{
12
13
  commands: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TObject<{
13
14
  description: _sinclair_typebox.TString;
14
15
  "ubiquity:example": _sinclair_typebox.TString;
16
+ parameters: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>>;
15
17
  }>>>;
16
18
  "ubiquity:listeners": _sinclair_typebox.TOptional<_sinclair_typebox.TArray<_sinclair_typebox.TUnion<_sinclair_typebox.TLiteral<"branch_protection_configuration" | "branch_protection_configuration.disabled" | "branch_protection_configuration.enabled" | "branch_protection_rule" | "branch_protection_rule.created" | "branch_protection_rule.deleted" | "branch_protection_rule.edited" | "check_run" | "check_run.completed" | "check_run.created" | "check_run.requested_action" | "check_run.rerequested" | "check_suite" | "check_suite.completed" | "check_suite.requested" | "check_suite.rerequested" | "code_scanning_alert" | "code_scanning_alert.appeared_in_branch" | "code_scanning_alert.closed_by_user" | "code_scanning_alert.created" | "code_scanning_alert.fixed" | "code_scanning_alert.reopened" | "code_scanning_alert.reopened_by_user" | "commit_comment" | "commit_comment.created" | "create" | "custom_property" | "custom_property.created" | "custom_property.deleted" | "custom_property.updated" | "custom_property_values" | "custom_property_values.updated" | "delete" | "dependabot_alert" | "dependabot_alert.auto_dismissed" | "dependabot_alert.auto_reopened" | "dependabot_alert.created" | "dependabot_alert.dismissed" | "dependabot_alert.fixed" | "dependabot_alert.reintroduced" | "dependabot_alert.reopened" | "deploy_key" | "deploy_key.created" | "deploy_key.deleted" | "deployment" | "deployment.created" | "deployment_protection_rule" | "deployment_protection_rule.requested" | "deployment_review" | "deployment_review.approved" | "deployment_review.rejected" | "deployment_review.requested" | "deployment_status" | "deployment_status.created" | "discussion" | "discussion.answered" | "discussion.category_changed" | "discussion.closed" | "discussion.created" | "discussion.deleted" | "discussion.edited" | "discussion.labeled" | "discussion.locked" | "discussion.pinned" | "discussion.reopened" | "discussion.transferred" | "discussion.unanswered" | "discussion.unlabeled" | "discussion.unlocked" | "discussion.unpinned" | "discussion_comment" | "discussion_comment.created" | "discussion_comment.deleted" | "discussion_comment.edited" | "fork" | "github_app_authorization" | "github_app_authorization.revoked" | "gollum" | "installation" | "installation.created" | "installation.deleted" | "installation.new_permissions_accepted" | "installation.suspend" | "installation.unsuspend" | "installation_repositories" | "installation_repositories.added" | "installation_repositories.removed" | "installation_target" | "installation_target.renamed" | "issue_comment" | "issue_comment.created" | "issue_comment.deleted" | "issue_comment.edited" | "issues" | "issues.assigned" | "issues.closed" | "issues.deleted" | "issues.demilestoned" | "issues.edited" | "issues.labeled" | "issues.locked" | "issues.milestoned" | "issues.opened" | "issues.pinned" | "issues.reopened" | "issues.transferred" | "issues.unassigned" | "issues.unlabeled" | "issues.unlocked" | "issues.unpinned" | "label" | "label.created" | "label.deleted" | "label.edited" | "marketplace_purchase" | "marketplace_purchase.cancelled" | "marketplace_purchase.changed" | "marketplace_purchase.pending_change" | "marketplace_purchase.pending_change_cancelled" | "marketplace_purchase.purchased" | "member" | "member.added" | "member.edited" | "member.removed" | "membership" | "membership.added" | "membership.removed" | "merge_group" | "merge_group.checks_requested" | "merge_group.destroyed" | "meta" | "meta.deleted" | "milestone" | "milestone.closed" | "milestone.created" | "milestone.deleted" | "milestone.edited" | "milestone.opened" | "org_block" | "org_block.blocked" | "org_block.unblocked" | "organization" | "organization.deleted" | "organization.member_added" | "organization.member_invited" | "organization.member_removed" | "organization.renamed" | "package" | "package.published" | "package.updated" | "page_build" | "personal_access_token_request" | "personal_access_token_request.approved" | "personal_access_token_request.cancelled" | "personal_access_token_request.created" | "personal_access_token_request.denied" | "ping" | "project" | "project.closed" | "project.created" | "project.deleted" | "project.edited" | "project.reopened" | "project_card" | "project_card.converted" | "project_card.created" | "project_card.deleted" | "project_card.edited" | "project_card.moved" | "project_column" | "project_column.created" | "project_column.deleted" | "project_column.edited" | "project_column.moved" | "projects_v2" | "projects_v2.closed" | "projects_v2.created" | "projects_v2.deleted" | "projects_v2.edited" | "projects_v2.reopened" | "projects_v2_item" | "projects_v2_item.archived" | "projects_v2_item.converted" | "projects_v2_item.created" | "projects_v2_item.deleted" | "projects_v2_item.edited" | "projects_v2_item.reordered" | "projects_v2_item.restored" | "public" | "pull_request" | "pull_request.assigned" | "pull_request.auto_merge_disabled" | "pull_request.auto_merge_enabled" | "pull_request.closed" | "pull_request.converted_to_draft" | "pull_request.demilestoned" | "pull_request.dequeued" | "pull_request.edited" | "pull_request.enqueued" | "pull_request.labeled" | "pull_request.locked" | "pull_request.milestoned" | "pull_request.opened" | "pull_request.ready_for_review" | "pull_request.reopened" | "pull_request.review_request_removed" | "pull_request.review_requested" | "pull_request.synchronize" | "pull_request.unassigned" | "pull_request.unlabeled" | "pull_request.unlocked" | "pull_request_review" | "pull_request_review.dismissed" | "pull_request_review.edited" | "pull_request_review.submitted" | "pull_request_review_comment" | "pull_request_review_comment.created" | "pull_request_review_comment.deleted" | "pull_request_review_comment.edited" | "pull_request_review_thread" | "pull_request_review_thread.resolved" | "pull_request_review_thread.unresolved" | "push" | "registry_package" | "registry_package.published" | "registry_package.updated" | "release" | "release.created" | "release.deleted" | "release.edited" | "release.prereleased" | "release.published" | "release.released" | "release.unpublished" | "repository" | "repository.archived" | "repository.created" | "repository.deleted" | "repository.edited" | "repository.privatized" | "repository.publicized" | "repository.renamed" | "repository.transferred" | "repository.unarchived" | "repository_advisory" | "repository_advisory.published" | "repository_advisory.reported" | "repository_dispatch" | "repository_dispatch.sample.collected" | "repository_import" | "repository_ruleset" | "repository_ruleset.created" | "repository_ruleset.deleted" | "repository_ruleset.edited" | "repository_vulnerability_alert" | "repository_vulnerability_alert.create" | "repository_vulnerability_alert.dismiss" | "repository_vulnerability_alert.reopen" | "repository_vulnerability_alert.resolve" | "secret_scanning_alert" | "secret_scanning_alert.created" | "secret_scanning_alert.reopened" | "secret_scanning_alert.resolved" | "secret_scanning_alert.revoked" | "secret_scanning_alert.validated" | "secret_scanning_alert_location" | "secret_scanning_alert_location.created" | "security_advisory" | "security_advisory.published" | "security_advisory.updated" | "security_advisory.withdrawn" | "security_and_analysis" | "sponsorship" | "sponsorship.cancelled" | "sponsorship.created" | "sponsorship.edited" | "sponsorship.pending_cancellation" | "sponsorship.pending_tier_change" | "sponsorship.tier_changed" | "star" | "star.created" | "star.deleted" | "status" | "team" | "team.added_to_repository" | "team.created" | "team.deleted" | "team.edited" | "team.removed_from_repository" | "team_add" | "watch" | "watch.started" | "workflow_dispatch" | "workflow_job" | "workflow_job.completed" | "workflow_job.in_progress" | "workflow_job.queued" | "workflow_job.waiting" | "workflow_run" | "workflow_run.completed" | "workflow_run.in_progress" | "workflow_run.requested">[]>>>;
17
19
  configuration: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TAny>>;
20
+ skipBotEvents: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
18
21
  }>;
19
22
  type Manifest = Static<typeof manifestSchema>;
20
23
 
package/dist/manifest.js CHANGED
@@ -30,14 +30,16 @@ var import_webhooks = require("@octokit/webhooks");
30
30
  var runEvent = import_typebox.Type.Union(import_webhooks.emitterEventNames.map((o) => import_typebox.Type.Literal(o)));
31
31
  var commandSchema = import_typebox.Type.Object({
32
32
  description: import_typebox.Type.String({ minLength: 1 }),
33
- "ubiquity:example": import_typebox.Type.String({ minLength: 1 })
33
+ "ubiquity:example": import_typebox.Type.String({ minLength: 1 }),
34
+ parameters: import_typebox.Type.Optional(import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any()))
34
35
  });
35
36
  var manifestSchema = import_typebox.Type.Object({
36
37
  name: import_typebox.Type.String({ minLength: 1 }),
37
38
  description: import_typebox.Type.Optional(import_typebox.Type.String({ default: "" })),
38
- commands: import_typebox.Type.Optional(import_typebox.Type.Record(import_typebox.Type.String(), commandSchema, { default: {} })),
39
+ commands: import_typebox.Type.Optional(import_typebox.Type.Record(import_typebox.Type.String({ pattern: "^[A-Za-z-_]+$" }), commandSchema, { default: {} })),
39
40
  "ubiquity:listeners": import_typebox.Type.Optional(import_typebox.Type.Array(runEvent, { default: [] })),
40
- configuration: import_typebox.Type.Optional(import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any(), { default: {} }))
41
+ configuration: import_typebox.Type.Optional(import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any(), { default: {} })),
42
+ skipBotEvents: import_typebox.Type.Optional(import_typebox.Type.Boolean({ default: true }))
41
43
  });
42
44
  // Annotate the CommonJS export names for ESM import in node:
43
45
  0 && (module.exports = {
package/dist/manifest.mjs CHANGED
@@ -4,14 +4,16 @@ import { emitterEventNames } from "@octokit/webhooks";
4
4
  var runEvent = T.Union(emitterEventNames.map((o) => T.Literal(o)));
5
5
  var commandSchema = T.Object({
6
6
  description: T.String({ minLength: 1 }),
7
- "ubiquity:example": T.String({ minLength: 1 })
7
+ "ubiquity:example": T.String({ minLength: 1 }),
8
+ parameters: T.Optional(T.Record(T.String(), T.Any()))
8
9
  });
9
10
  var manifestSchema = T.Object({
10
11
  name: T.String({ minLength: 1 }),
11
12
  description: T.Optional(T.String({ default: "" })),
12
- commands: T.Optional(T.Record(T.String(), commandSchema, { default: {} })),
13
+ commands: T.Optional(T.Record(T.String({ pattern: "^[A-Za-z-_]+$" }), commandSchema, { default: {} })),
13
14
  "ubiquity:listeners": T.Optional(T.Array(runEvent, { default: [] })),
14
- configuration: T.Optional(T.Record(T.String(), T.Any(), { default: {} }))
15
+ configuration: T.Optional(T.Record(T.String(), T.Any(), { default: {} })),
16
+ skipBotEvents: T.Optional(T.Boolean({ default: true }))
15
17
  });
16
18
  export {
17
19
  commandSchema,
@@ -0,0 +1,16 @@
1
+ import * as _octokit_core_dist_types_types from '@octokit/core/dist-types/types';
2
+ import * as _octokit_plugin_paginate_graphql from '@octokit/plugin-paginate-graphql';
3
+ import * as _octokit_plugin_rest_endpoint_methods from '@octokit/plugin-rest-endpoint-methods';
4
+ import * as _octokit_plugin_paginate_rest from '@octokit/plugin-paginate-rest';
5
+ import * as _octokit_request_error from '@octokit/request-error';
6
+ import { Octokit } from '@octokit/core';
7
+
8
+ declare const customOctokit: typeof Octokit & _octokit_core_dist_types_types.Constructor<{
9
+ retry: {
10
+ retryRequest: (error: _octokit_request_error.RequestError, retries: number, retryAfter: number) => _octokit_request_error.RequestError;
11
+ };
12
+ } & {
13
+ paginate: _octokit_plugin_paginate_rest.PaginateInterface;
14
+ } & _octokit_plugin_rest_endpoint_methods.Api & _octokit_plugin_paginate_graphql.paginateGraphQLInterface>;
15
+
16
+ export { customOctokit };
@@ -0,0 +1,16 @@
1
+ import * as _octokit_core_dist_types_types from '@octokit/core/dist-types/types';
2
+ import * as _octokit_plugin_paginate_graphql from '@octokit/plugin-paginate-graphql';
3
+ import * as _octokit_plugin_rest_endpoint_methods from '@octokit/plugin-rest-endpoint-methods';
4
+ import * as _octokit_plugin_paginate_rest from '@octokit/plugin-paginate-rest';
5
+ import * as _octokit_request_error from '@octokit/request-error';
6
+ import { Octokit } from '@octokit/core';
7
+
8
+ declare const customOctokit: typeof Octokit & _octokit_core_dist_types_types.Constructor<{
9
+ retry: {
10
+ retryRequest: (error: _octokit_request_error.RequestError, retries: number, retryAfter: number) => _octokit_request_error.RequestError;
11
+ };
12
+ } & {
13
+ paginate: _octokit_plugin_paginate_rest.PaginateInterface;
14
+ } & _octokit_plugin_rest_endpoint_methods.Api & _octokit_plugin_paginate_graphql.paginateGraphQLInterface>;
15
+
16
+ export { customOctokit };
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/octokit.ts
21
+ var octokit_exports = {};
22
+ __export(octokit_exports, {
23
+ customOctokit: () => customOctokit
24
+ });
25
+ module.exports = __toCommonJS(octokit_exports);
26
+ var import_core = require("@octokit/core");
27
+ var import_plugin_paginate_rest = require("@octokit/plugin-paginate-rest");
28
+ var import_plugin_rest_endpoint_methods = require("@octokit/plugin-rest-endpoint-methods");
29
+ var import_plugin_retry = require("@octokit/plugin-retry");
30
+ var import_plugin_throttling = require("@octokit/plugin-throttling");
31
+ var import_plugin_paginate_graphql = require("@octokit/plugin-paginate-graphql");
32
+ var defaultOptions = {
33
+ throttle: {
34
+ onAbuseLimit: (retryAfter, options, octokit) => {
35
+ octokit.log.warn(`Abuse limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`);
36
+ return true;
37
+ },
38
+ onRateLimit: (retryAfter, options, octokit) => {
39
+ octokit.log.warn(`Rate limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`);
40
+ return true;
41
+ },
42
+ onSecondaryRateLimit: (retryAfter, options, octokit) => {
43
+ octokit.log.warn(`Secondary rate limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`);
44
+ return true;
45
+ }
46
+ }
47
+ };
48
+ var customOctokit = import_core.Octokit.plugin(import_plugin_throttling.throttling, import_plugin_retry.retry, import_plugin_paginate_rest.paginateRest, import_plugin_rest_endpoint_methods.restEndpointMethods, import_plugin_paginate_graphql.paginateGraphQL).defaults((instanceOptions) => {
49
+ return { ...defaultOptions, ...instanceOptions };
50
+ });
51
+ // Annotate the CommonJS export names for ESM import in node:
52
+ 0 && (module.exports = {
53
+ customOctokit
54
+ });
@@ -0,0 +1,29 @@
1
+ // src/octokit.ts
2
+ import { Octokit } from "@octokit/core";
3
+ import { paginateRest } from "@octokit/plugin-paginate-rest";
4
+ import { restEndpointMethods } from "@octokit/plugin-rest-endpoint-methods";
5
+ import { retry } from "@octokit/plugin-retry";
6
+ import { throttling } from "@octokit/plugin-throttling";
7
+ import { paginateGraphQL } from "@octokit/plugin-paginate-graphql";
8
+ var defaultOptions = {
9
+ throttle: {
10
+ onAbuseLimit: (retryAfter, options, octokit) => {
11
+ octokit.log.warn(`Abuse limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`);
12
+ return true;
13
+ },
14
+ onRateLimit: (retryAfter, options, octokit) => {
15
+ octokit.log.warn(`Rate limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`);
16
+ return true;
17
+ },
18
+ onSecondaryRateLimit: (retryAfter, options, octokit) => {
19
+ octokit.log.warn(`Secondary rate limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`);
20
+ return true;
21
+ }
22
+ }
23
+ };
24
+ var customOctokit = Octokit.plugin(throttling, retry, paginateRest, restEndpointMethods, paginateGraphQL).defaults((instanceOptions) => {
25
+ return { ...defaultOptions, ...instanceOptions };
26
+ });
27
+ export {
28
+ customOctokit
29
+ };
@@ -5,6 +5,7 @@ interface Inputs {
5
5
  authToken: unknown;
6
6
  settings: unknown;
7
7
  ref: unknown;
8
+ command: unknown;
8
9
  }
9
10
  declare function verifySignature(publicKeyPem: string, inputs: Inputs, signature: string): Promise<boolean>;
10
11
  declare function signPayload(payload: string, privateKey: string): Promise<string>;
@@ -5,6 +5,7 @@ interface Inputs {
5
5
  authToken: unknown;
6
6
  settings: unknown;
7
7
  ref: unknown;
8
+ command: unknown;
8
9
  }
9
10
  declare function verifySignature(publicKeyPem: string, inputs: Inputs, signature: string): Promise<boolean>;
10
11
  declare function signPayload(payload: string, privateKey: string): Promise<string>;
package/dist/signature.js CHANGED
@@ -32,7 +32,8 @@ async function verifySignature(publicKeyPem, inputs, signature) {
32
32
  eventPayload: inputs.eventPayload,
33
33
  settings: inputs.settings,
34
34
  authToken: inputs.authToken,
35
- ref: inputs.ref
35
+ ref: inputs.ref,
36
+ command: inputs.command
36
37
  };
37
38
  const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").trim();
38
39
  const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
@@ -7,7 +7,8 @@ async function verifySignature(publicKeyPem, inputs, signature) {
7
7
  eventPayload: inputs.eventPayload,
8
8
  settings: inputs.settings,
9
9
  authToken: inputs.authToken,
10
- ref: inputs.ref
10
+ ref: inputs.ref,
11
+ command: inputs.command
11
12
  };
12
13
  const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").trim();
13
14
  const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubiquity-os/plugin-sdk",
3
- "version": "1.0.11",
3
+ "version": "1.1.0",
4
4
  "description": "SDK for plugin support.",
5
5
  "author": "Ubiquity DAO",
6
6
  "license": "MIT",
@@ -21,6 +21,9 @@
21
21
  ],
22
22
  "signature": [
23
23
  "dist/signature.d.ts"
24
+ ],
25
+ "octokit": [
26
+ "dist/octokit.d.ts"
24
27
  ]
25
28
  }
26
29
  },
@@ -44,6 +47,11 @@
44
47
  "types": "./dist/signature.d.ts",
45
48
  "import": "./dist/signature.mjs",
46
49
  "require": "./dist/signature.js"
50
+ },
51
+ "./octokit": {
52
+ "types": "./dist/octokit.d.ts",
53
+ "import": "./dist/octokit.mjs",
54
+ "require": "./dist/octokit.js"
47
55
  }
48
56
  },
49
57
  "files": [
@@ -79,11 +87,13 @@
79
87
  "@octokit/rest": "^21.0.2",
80
88
  "@octokit/types": "^13.6.1",
81
89
  "@octokit/webhooks": "^13.3.0",
82
- "@sinclair/typebox": "^0.33.21",
83
90
  "@ubiquity-os/ubiquity-os-logger": "^1.3.2",
84
91
  "dotenv": "^16.4.5",
85
92
  "hono": "^4.6.9"
86
93
  },
94
+ "peerDependencies": {
95
+ "@sinclair/typebox": "0.34.3"
96
+ },
87
97
  "devDependencies": {
88
98
  "@commitlint/cli": "^18.6.1",
89
99
  "@commitlint/config-conventional": "^18.6.2",