@ubiquity-os/plugin-sdk 3.6.3 → 3.8.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.js CHANGED
@@ -41,7 +41,6 @@ module.exports = __toCommonJS(src_exports);
41
41
 
42
42
  // src/actions.ts
43
43
  var core = __toESM(require("@actions/core"));
44
- var github2 = __toESM(require("@actions/github"));
45
44
  var import_value3 = require("@sinclair/typebox/value");
46
45
 
47
46
  // ../../node_modules/@ubiquity-os/ubiquity-os-logger/dist/index.js
@@ -232,9 +231,9 @@ var Logs = class _Logs {
232
231
  const stackLines = new Error().stack?.split("\n") || [];
233
232
  if (stackLines.length > 3) {
234
233
  const callerLine = stackLines[3];
235
- const match = callerLine.match(/at (\S+)/);
236
- if (match) {
237
- metadata.caller = match[1];
234
+ const match2 = callerLine.match(/at (\S+)/);
235
+ if (match2) {
236
+ metadata.caller = match2[1];
238
237
  }
239
238
  }
240
239
  return metadata;
@@ -379,10 +378,58 @@ var Logs = class _Logs {
379
378
  // src/actions.ts
380
379
  var import_dotenv = require("dotenv");
381
380
 
382
- // src/helpers/runtime-info.ts
383
- var import_github = __toESM(require("@actions/github"));
381
+ // src/error.ts
382
+ function getErrorStatus(err) {
383
+ if (!err || typeof err !== "object") return null;
384
+ const candidate = err;
385
+ const directStatus = candidate.status ?? candidate.response?.status;
386
+ if (typeof directStatus === "number" && Number.isFinite(directStatus)) return directStatus;
387
+ if (typeof directStatus === "string" && directStatus.trim()) {
388
+ const parsed = Number.parseInt(directStatus, 10);
389
+ if (Number.isFinite(parsed)) return parsed;
390
+ }
391
+ if (err instanceof Error) {
392
+ const match2 = /LLM API error:\s*(\d{3})/i.exec(err.message);
393
+ if (match2) {
394
+ const parsed = Number.parseInt(match2[1], 10);
395
+ if (Number.isFinite(parsed)) return parsed;
396
+ }
397
+ }
398
+ return null;
399
+ }
400
+ function logByStatus(context, message, metadata) {
401
+ const status = getErrorStatus(metadata.err);
402
+ const payload = { ...metadata, ...status ? { status } : {} };
403
+ if (status && status >= 500) return context.logger.error(message, payload);
404
+ if (status && status >= 400) return context.logger.warn(message, payload);
405
+ if (status && status >= 300) return context.logger.debug(message, payload);
406
+ if (status && status >= 200) return context.logger.ok(message, payload);
407
+ if (status && status >= 100) return context.logger.info(message, payload);
408
+ return context.logger.error(message, payload);
409
+ }
410
+ function transformError(context, error) {
411
+ if (error instanceof LogReturn) {
412
+ return error;
413
+ }
414
+ if (error instanceof AggregateError) {
415
+ const message = error.errors.map((err) => {
416
+ if (err instanceof LogReturn) {
417
+ return err.logMessage.raw;
418
+ }
419
+ if (err instanceof Error) {
420
+ return err.message;
421
+ }
422
+ return String(err);
423
+ }).join("\n\n");
424
+ return logByStatus(context, message, { err: error });
425
+ }
426
+ if (error instanceof Error) {
427
+ return logByStatus(context, error.message, { err: error });
428
+ }
429
+ return logByStatus(context, String(error), { err: error });
430
+ }
384
431
 
385
- // ../../node_modules/hono/dist/helper/adapter/index.js
432
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/helper/adapter/index.js
386
433
  var env = (c, runtime) => {
387
434
  const global = globalThis;
388
435
  const globalEnv = global?.process?.env;
@@ -395,6 +442,7 @@ var env = (c, runtime) => {
395
442
  return Deno.env.toObject();
396
443
  },
397
444
  workerd: () => c.env,
445
+ // On Fastly Compute, you can use the ConfigStore to manage user-defined data.
398
446
  fastly: () => ({}),
399
447
  other: () => ({})
400
448
  };
@@ -432,6 +480,21 @@ var checkUserAgentEquals = (platform) => {
432
480
  return userAgent.startsWith(platform);
433
481
  };
434
482
 
483
+ // src/helpers/github-context.ts
484
+ var github = __toESM(require("@actions/github"));
485
+ function getGithubContext() {
486
+ const override = globalThis.__UOS_GITHUB_CONTEXT__;
487
+ if (override) {
488
+ return override;
489
+ }
490
+ const module2 = github;
491
+ const context = module2.context ?? module2.default?.context;
492
+ if (!context) {
493
+ throw new Error("GitHub context is unavailable.");
494
+ }
495
+ return context;
496
+ }
497
+
435
498
  // src/helpers/runtime-info.ts
436
499
  var PluginRuntimeInfo = class _PluginRuntimeInfo {
437
500
  static _instance = null;
@@ -480,10 +543,11 @@ var CfRuntimeInfo = class extends PluginRuntimeInfo {
480
543
  };
481
544
  var NodeRuntimeInfo = class extends PluginRuntimeInfo {
482
545
  get version() {
483
- return import_github.default.context.sha;
546
+ return getGithubContext().sha;
484
547
  }
485
548
  get runUrl() {
486
- return import_github.default.context.payload.repository ? `${import_github.default.context.payload.repository?.html_url}/actions/runs/${import_github.default.context.runId}` : "http://localhost";
549
+ const context = getGithubContext();
550
+ return context.payload.repository ? `${context.payload.repository?.html_url}/actions/runs/${context.runId}` : "http://localhost";
487
551
  }
488
552
  };
489
553
  var DenoRuntimeInfo = class extends PluginRuntimeInfo {
@@ -573,14 +637,72 @@ function getPluginOptions(options) {
573
637
  }
574
638
 
575
639
  // src/comment.ts
640
+ var COMMAND_RESPONSE_KIND = "command-response";
641
+ var COMMAND_RESPONSE_MARKER = `"commentKind": "${COMMAND_RESPONSE_KIND}"`;
642
+ var COMMAND_RESPONSE_COMMENT_LIMIT = 50;
643
+ var RECENT_COMMENTS_QUERY = `
644
+ query($owner: String!, $repo: String!, $number: Int!, $last: Int!) {
645
+ repository(owner: $owner, name: $repo) {
646
+ issueOrPullRequest(number: $number) {
647
+ __typename
648
+ ... on Issue {
649
+ comments(last: $last) {
650
+ nodes {
651
+ id
652
+ body
653
+ isMinimized
654
+ minimizedReason
655
+ author {
656
+ login
657
+ }
658
+ }
659
+ }
660
+ }
661
+ ... on PullRequest {
662
+ comments(last: $last) {
663
+ nodes {
664
+ id
665
+ body
666
+ isMinimized
667
+ minimizedReason
668
+ author {
669
+ login
670
+ }
671
+ }
672
+ }
673
+ }
674
+ }
675
+ }
676
+ }
677
+ `;
678
+ var MINIMIZE_COMMENT_MUTATION = `
679
+ mutation($id: ID!, $classifier: ReportedContentClassifiers!) {
680
+ minimizeComment(input: { subjectId: $id, classifier: $classifier }) {
681
+ minimizedComment {
682
+ isMinimized
683
+ minimizedReason
684
+ }
685
+ }
686
+ }
687
+ `;
688
+ function logByStatus2(logger, message, status, metadata) {
689
+ const payload = { ...metadata, ...status ? { status } : {} };
690
+ if (status && status >= 500) return logger.error(message, payload);
691
+ if (status && status >= 400) return logger.warn(message, payload);
692
+ if (status && status >= 300) return logger.debug(message, payload);
693
+ if (status && status >= 200) return logger.ok(message, payload);
694
+ if (status && status >= 100) return logger.info(message, payload);
695
+ return logger.error(message, payload);
696
+ }
576
697
  var CommentHandler = class _CommentHandler {
577
698
  static HEADER_NAME = "UbiquityOS";
578
699
  _lastCommentId = { reviewCommentId: null, issueCommentId: null };
579
- async _updateIssueComment(context2, params) {
700
+ _commandResponsePolicyApplied = false;
701
+ async _updateIssueComment(context, params) {
580
702
  if (!this._lastCommentId.issueCommentId) {
581
- throw context2.logger.error("issueCommentId is missing");
703
+ throw context.logger.error("issueCommentId is missing");
582
704
  }
583
- const commentData = await context2.octokit.rest.issues.updateComment({
705
+ const commentData = await context.octokit.rest.issues.updateComment({
584
706
  owner: params.owner,
585
707
  repo: params.repo,
586
708
  comment_id: this._lastCommentId.issueCommentId,
@@ -588,11 +710,11 @@ var CommentHandler = class _CommentHandler {
588
710
  });
589
711
  return { ...commentData.data, issueNumber: params.issueNumber };
590
712
  }
591
- async _updateReviewComment(context2, params) {
713
+ async _updateReviewComment(context, params) {
592
714
  if (!this._lastCommentId.reviewCommentId) {
593
- throw context2.logger.error("reviewCommentId is missing");
715
+ throw context.logger.error("reviewCommentId is missing");
594
716
  }
595
- const commentData = await context2.octokit.rest.pulls.updateReviewComment({
717
+ const commentData = await context.octokit.rest.pulls.updateReviewComment({
596
718
  owner: params.owner,
597
719
  repo: params.repo,
598
720
  comment_id: this._lastCommentId.reviewCommentId,
@@ -600,9 +722,9 @@ var CommentHandler = class _CommentHandler {
600
722
  });
601
723
  return { ...commentData.data, issueNumber: params.issueNumber };
602
724
  }
603
- async _createNewComment(context2, params) {
725
+ async _createNewComment(context, params) {
604
726
  if (params.commentId) {
605
- const commentData2 = await context2.octokit.rest.pulls.createReplyForReviewComment({
727
+ const commentData2 = await context.octokit.rest.pulls.createReplyForReviewComment({
606
728
  owner: params.owner,
607
729
  repo: params.repo,
608
730
  pull_number: params.issueNumber,
@@ -612,7 +734,7 @@ var CommentHandler = class _CommentHandler {
612
734
  this._lastCommentId.reviewCommentId = commentData2.data.id;
613
735
  return { ...commentData2.data, issueNumber: params.issueNumber };
614
736
  }
615
- const commentData = await context2.octokit.rest.issues.createComment({
737
+ const commentData = await context.octokit.rest.issues.createComment({
616
738
  owner: params.owner,
617
739
  repo: params.repo,
618
740
  issue_number: params.issueNumber,
@@ -621,54 +743,143 @@ var CommentHandler = class _CommentHandler {
621
743
  this._lastCommentId.issueCommentId = commentData.data.id;
622
744
  return { ...commentData.data, issueNumber: params.issueNumber };
623
745
  }
624
- _getIssueNumber(context2) {
625
- if ("issue" in context2.payload) return context2.payload.issue.number;
626
- if ("pull_request" in context2.payload) return context2.payload.pull_request.number;
627
- if ("discussion" in context2.payload) return context2.payload.discussion.number;
746
+ _getIssueNumber(context) {
747
+ if ("issue" in context.payload) return context.payload.issue.number;
748
+ if ("pull_request" in context.payload) return context.payload.pull_request.number;
749
+ if ("discussion" in context.payload) return context.payload.discussion.number;
628
750
  return void 0;
629
751
  }
630
- _getCommentId(context2) {
631
- return "pull_request" in context2.payload && "comment" in context2.payload ? context2.payload.comment.id : void 0;
752
+ _getCommentId(context) {
753
+ return "pull_request" in context.payload && "comment" in context.payload ? context.payload.comment.id : void 0;
632
754
  }
633
- _extractIssueContext(context2) {
634
- if (!("repository" in context2.payload) || !context2.payload.repository?.owner?.login) {
755
+ _getCommentNodeId(context) {
756
+ const payload = context.payload;
757
+ const nodeId = payload.comment?.node_id;
758
+ return typeof nodeId === "string" && nodeId.trim() ? nodeId : null;
759
+ }
760
+ _extractIssueContext(context) {
761
+ if (!("repository" in context.payload) || !context.payload.repository?.owner?.login) {
635
762
  return null;
636
763
  }
637
- const issueNumber = this._getIssueNumber(context2);
764
+ const issueNumber = this._getIssueNumber(context);
638
765
  if (!issueNumber) return null;
639
766
  return {
640
767
  issueNumber,
641
- commentId: this._getCommentId(context2),
642
- owner: context2.payload.repository.owner.login,
643
- repo: context2.payload.repository.name
768
+ commentId: this._getCommentId(context),
769
+ owner: context.payload.repository.owner.login,
770
+ repo: context.payload.repository.name
644
771
  };
645
772
  }
646
- _processMessage(context2, message) {
773
+ _extractIssueLocator(context) {
774
+ if (!("issue" in context.payload) && !("pull_request" in context.payload)) {
775
+ return null;
776
+ }
777
+ const issueContext = this._extractIssueContext(context);
778
+ if (!issueContext) return null;
779
+ return {
780
+ owner: issueContext.owner,
781
+ repo: issueContext.repo,
782
+ issueNumber: issueContext.issueNumber
783
+ };
784
+ }
785
+ _shouldApplyCommandResponsePolicy(context) {
786
+ const payload = context;
787
+ return Boolean(payload.command);
788
+ }
789
+ _isCommandResponseComment(body) {
790
+ return typeof body === "string" && body.includes(COMMAND_RESPONSE_MARKER);
791
+ }
792
+ _getGraphqlClient(context) {
793
+ const graphql = context.octokit.graphql;
794
+ return typeof graphql === "function" ? graphql : null;
795
+ }
796
+ async _fetchRecentComments(context, locator, last = COMMAND_RESPONSE_COMMENT_LIMIT) {
797
+ const graphql = this._getGraphqlClient(context);
798
+ if (!graphql) return [];
799
+ try {
800
+ const data = await graphql(RECENT_COMMENTS_QUERY, {
801
+ owner: locator.owner,
802
+ repo: locator.repo,
803
+ number: locator.issueNumber,
804
+ last
805
+ });
806
+ const nodes = data.repository?.issueOrPullRequest?.comments?.nodes ?? [];
807
+ return nodes.filter((node) => Boolean(node));
808
+ } catch (error) {
809
+ context.logger.debug("Failed to fetch recent comments (non-fatal)", { err: error });
810
+ return [];
811
+ }
812
+ }
813
+ _findPreviousCommandResponseComment(comments, currentCommentId) {
814
+ for (let idx = comments.length - 1; idx >= 0; idx -= 1) {
815
+ const comment = comments[idx];
816
+ if (!comment) continue;
817
+ if (currentCommentId && comment.id === currentCommentId) continue;
818
+ if (this._isCommandResponseComment(comment.body)) {
819
+ return comment;
820
+ }
821
+ }
822
+ return null;
823
+ }
824
+ async _minimizeComment(context, commentNodeId, classifier = "RESOLVED") {
825
+ const graphql = this._getGraphqlClient(context);
826
+ if (!graphql) return;
827
+ try {
828
+ await graphql(MINIMIZE_COMMENT_MUTATION, {
829
+ id: commentNodeId,
830
+ classifier
831
+ });
832
+ } catch (error) {
833
+ context.logger.debug("Failed to minimize comment (non-fatal)", { err: error, commentNodeId });
834
+ }
835
+ }
836
+ async _applyCommandResponsePolicy(context) {
837
+ if (this._commandResponsePolicyApplied) return;
838
+ this._commandResponsePolicyApplied = true;
839
+ if (!this._shouldApplyCommandResponsePolicy(context)) return;
840
+ const locator = this._extractIssueLocator(context);
841
+ const commentNodeId = this._getCommentNodeId(context);
842
+ const comments = locator ? await this._fetchRecentComments(context, locator) : [];
843
+ const current = commentNodeId ? comments.find((comment) => comment.id === commentNodeId) : null;
844
+ const currentIsMinimized = current?.isMinimized ?? false;
845
+ if (commentNodeId && !currentIsMinimized) {
846
+ await this._minimizeComment(context, commentNodeId);
847
+ }
848
+ const previous = this._findPreviousCommandResponseComment(comments, commentNodeId);
849
+ if (previous && !previous.isMinimized) {
850
+ await this._minimizeComment(context, previous.id);
851
+ }
852
+ }
853
+ _processMessage(context, message) {
647
854
  if (message instanceof Error) {
648
855
  const metadata2 = {
649
856
  message: message.message,
650
857
  name: message.name,
651
858
  stack: message.stack
652
859
  };
653
- return { metadata: metadata2, logMessage: context2.logger.error(message.message).logMessage };
860
+ const status = getErrorStatus(message);
861
+ const logReturn = logByStatus2(context.logger, message.message, status, metadata2);
862
+ return { metadata: { ...metadata2, ...status ? { status } : {} }, logMessage: logReturn.logMessage };
654
863
  }
864
+ const stackLine = message.metadata?.error?.stack?.split("\n")[2];
865
+ const callerMatch = stackLine ? /at (\S+)/.exec(stackLine) : null;
655
866
  const metadata = message.metadata ? {
656
867
  ...message.metadata,
657
868
  message: message.metadata.message,
658
869
  stack: message.metadata.stack || message.metadata.error?.stack,
659
- caller: message.metadata.caller || message.metadata.error?.stack?.split("\n")[2]?.match(/at (\S+)/)?.[1]
870
+ caller: message.metadata.caller || callerMatch?.[1]
660
871
  } : { ...message };
661
872
  return { metadata, logMessage: message.logMessage };
662
873
  }
663
- _getInstigatorName(context2) {
664
- if ("installation" in context2.payload && context2.payload.installation && "account" in context2.payload.installation && context2.payload.installation?.account?.name) {
665
- return context2.payload.installation?.account?.name;
874
+ _getInstigatorName(context) {
875
+ if ("installation" in context.payload && context.payload.installation && "account" in context.payload.installation && context.payload.installation?.account?.name) {
876
+ return context.payload.installation?.account?.name;
666
877
  }
667
- return context2.payload.sender?.login || _CommentHandler.HEADER_NAME;
878
+ return context.payload.sender?.login || _CommentHandler.HEADER_NAME;
668
879
  }
669
- _createMetadataContent(context2, metadata) {
880
+ _createMetadataContent(context, metadata) {
670
881
  const jsonPretty = sanitizeMetadata(metadata);
671
- const instigatorName = this._getInstigatorName(context2);
882
+ const instigatorName = this._getInstigatorName(context);
672
883
  const runUrl = PluginRuntimeInfo.getInstance().runUrl;
673
884
  const version = PluginRuntimeInfo.getInstance().version;
674
885
  const callingFnName = metadata.caller || "anonymous";
@@ -685,63 +896,46 @@ var CommentHandler = class _CommentHandler {
685
896
  /*
686
897
  * Creates the body for the comment, embeds the metadata and the header hidden in the body as well.
687
898
  */
688
- createCommentBody(context2, message, options) {
689
- return this._createCommentBody(context2, message, options);
690
- }
691
- _createCommentBody(context2, message, options) {
692
- const { metadata, logMessage } = this._processMessage(context2, message);
693
- const { header, jsonPretty } = this._createMetadataContent(context2, metadata);
899
+ createCommentBody(context, message, options) {
900
+ return this._createCommentBody(context, message, options);
901
+ }
902
+ _createCommentBody(context, message, options) {
903
+ const { metadata, logMessage } = this._processMessage(context, message);
904
+ const shouldTagCommandResponse = options?.commentKind && typeof metadata === "object" && metadata !== null && !("commentKind" in metadata);
905
+ const metadataWithKind = shouldTagCommandResponse ? { ...metadata, commentKind: options?.commentKind } : metadata;
906
+ const { header, jsonPretty } = this._createMetadataContent(context, metadataWithKind);
694
907
  const metadataContent = this._formatMetadataContent(logMessage, header, jsonPretty);
695
908
  return `${options?.raw ? logMessage?.raw : logMessage?.diff}
696
909
 
697
910
  ${metadataContent}
698
911
  `;
699
912
  }
700
- async postComment(context2, message, options = { updateComment: true, raw: false }) {
701
- const issueContext = this._extractIssueContext(context2);
913
+ async postComment(context, message, options = { updateComment: true, raw: false }) {
914
+ await this._applyCommandResponsePolicy(context);
915
+ const issueContext = this._extractIssueContext(context);
702
916
  if (!issueContext) {
703
- context2.logger.warn("Cannot post comment: missing issue context in payload");
917
+ context.logger.warn("Cannot post comment: missing issue context in payload");
704
918
  return null;
705
919
  }
706
- const body = this._createCommentBody(context2, message, options);
920
+ const shouldTagCommandResponse = this._shouldApplyCommandResponsePolicy(context);
921
+ const body = this._createCommentBody(context, message, {
922
+ ...options,
923
+ commentKind: options.commentKind ?? (shouldTagCommandResponse ? COMMAND_RESPONSE_KIND : void 0)
924
+ });
707
925
  const { issueNumber, commentId, owner, repo } = issueContext;
708
926
  const params = { owner, repo, body, issueNumber };
709
927
  if (options.updateComment) {
710
- if (this._lastCommentId.issueCommentId && !("pull_request" in context2.payload && "comment" in context2.payload)) {
711
- return this._updateIssueComment(context2, params);
928
+ if (this._lastCommentId.issueCommentId && !("pull_request" in context.payload && "comment" in context.payload)) {
929
+ return this._updateIssueComment(context, params);
712
930
  }
713
- if (this._lastCommentId.reviewCommentId && "pull_request" in context2.payload && "comment" in context2.payload) {
714
- return this._updateReviewComment(context2, params);
931
+ if (this._lastCommentId.reviewCommentId && "pull_request" in context.payload && "comment" in context.payload) {
932
+ return this._updateReviewComment(context, params);
715
933
  }
716
934
  }
717
- return this._createNewComment(context2, { ...params, commentId });
935
+ return this._createNewComment(context, { ...params, commentId });
718
936
  }
719
937
  };
720
938
 
721
- // src/error.ts
722
- function transformError(context2, error) {
723
- let loggerError;
724
- if (error instanceof AggregateError) {
725
- loggerError = context2.logger.error(
726
- error.errors.map((err) => {
727
- if (err instanceof LogReturn) {
728
- return err.logMessage.raw;
729
- } else if (err instanceof Error) {
730
- return err.message;
731
- } else {
732
- return err;
733
- }
734
- }).join("\n\n"),
735
- { error }
736
- );
737
- } else if (error instanceof Error || error instanceof LogReturn) {
738
- loggerError = error;
739
- } else {
740
- loggerError = context2.logger.error(String(error));
741
- }
742
- return loggerError;
743
- }
744
-
745
939
  // src/helpers/command.ts
746
940
  var import_value = require("@sinclair/typebox/value");
747
941
  function getCommand(inputs, pluginOptions) {
@@ -974,7 +1168,7 @@ async function verifySignature(publicKeyPem, inputs, signature) {
974
1168
  ref: inputs.ref,
975
1169
  command: inputs.command
976
1170
  };
977
- const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").trim();
1171
+ const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").replace(/\s+/g, "");
978
1172
  const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
979
1173
  const publicKey = await crypto.subtle.importKey(
980
1174
  "spki",
@@ -1027,16 +1221,12 @@ var inputSchema = import_typebox3.Type.Object({
1027
1221
 
1028
1222
  // src/actions.ts
1029
1223
  (0, import_dotenv.config)();
1030
- async function handleError(context2, pluginOptions, error) {
1224
+ async function handleError(context, pluginOptions, error) {
1031
1225
  console.error(error);
1032
- const loggerError = transformError(context2, error);
1033
- if (loggerError instanceof LogReturn) {
1034
- core.setFailed(loggerError.logMessage.diff);
1035
- } else if (loggerError instanceof Error) {
1036
- core.setFailed(loggerError);
1037
- }
1226
+ const loggerError = transformError(context, error);
1227
+ core.setFailed(loggerError.logMessage.diff);
1038
1228
  if (pluginOptions.postCommentOnError && loggerError) {
1039
- await context2.commentHandler.postComment(context2, loggerError);
1229
+ await context.commentHandler.postComment(context, loggerError);
1040
1230
  }
1041
1231
  }
1042
1232
  async function createActionsPlugin(handler, options) {
@@ -1046,7 +1236,8 @@ async function createActionsPlugin(handler, options) {
1046
1236
  core.setFailed("Error: PLUGIN_GITHUB_TOKEN env is not set");
1047
1237
  return;
1048
1238
  }
1049
- const body = github2.context.payload.inputs;
1239
+ const githubContext = getGithubContext();
1240
+ const body = githubContext.payload.inputs;
1050
1241
  const inputSchemaErrors = [...import_value3.Value.Errors(inputSchema, body)];
1051
1242
  if (inputSchemaErrors.length) {
1052
1243
  console.dir(inputSchemaErrors, { depth: null });
@@ -1084,7 +1275,7 @@ async function createActionsPlugin(handler, options) {
1084
1275
  env2 = process.env;
1085
1276
  }
1086
1277
  const command = getCommand(inputs, pluginOptions);
1087
- const context2 = {
1278
+ const context = {
1088
1279
  eventName: inputs.eventName,
1089
1280
  payload: inputs.eventPayload,
1090
1281
  command,
@@ -1097,20 +1288,21 @@ async function createActionsPlugin(handler, options) {
1097
1288
  commentHandler: new CommentHandler()
1098
1289
  };
1099
1290
  try {
1100
- const result = await handler(context2);
1291
+ const result = await handler(context);
1101
1292
  core.setOutput("result", result);
1102
1293
  if (pluginOptions?.returnDataToKernel) {
1103
1294
  await returnDataToKernel(pluginGithubToken, inputs.stateId, result);
1104
1295
  }
1105
1296
  } catch (error) {
1106
- await handleError(context2, pluginOptions, error);
1297
+ await handleError(context, pluginOptions, error);
1107
1298
  }
1108
1299
  }
1109
1300
  async function returnDataToKernel(repoToken, stateId, output) {
1301
+ const githubContext = getGithubContext();
1110
1302
  const octokit = new customOctokit({ auth: repoToken });
1111
1303
  await octokit.rest.repos.createDispatchEvent({
1112
- owner: github2.context.repo.owner,
1113
- repo: github2.context.repo.repo,
1304
+ owner: githubContext.repo.owner,
1305
+ repo: githubContext.repo.repo,
1114
1306
  event_type: "return-data-to-ubiquity-os-kernel",
1115
1307
  client_payload: {
1116
1308
  state_id: stateId,
@@ -1127,12 +1319,12 @@ function cleanMarkdown(md, options = {}) {
1127
1319
  const segments = [];
1128
1320
  let lastIndex = 0;
1129
1321
  const matches = [...md.matchAll(codeBlockRegex)];
1130
- for (const match of matches) {
1131
- if (match.index > lastIndex) {
1132
- segments.push(processSegment(md.slice(lastIndex, match.index), tags, shouldCollapseEmptyLines));
1322
+ for (const match2 of matches) {
1323
+ if (match2.index > lastIndex) {
1324
+ segments.push(processSegment(md.slice(lastIndex, match2.index), tags, shouldCollapseEmptyLines));
1133
1325
  }
1134
- segments.push(match[0]);
1135
- lastIndex = match.index + match[0].length;
1326
+ segments.push(match2[0]);
1327
+ lastIndex = match2.index + match2[0].length;
1136
1328
  }
1137
1329
  if (lastIndex < md.length) {
1138
1330
  segments.push(processSegment(md.slice(lastIndex), tags, shouldCollapseEmptyLines));
@@ -1175,9 +1367,9 @@ function processSegment(segment, extraTags, shouldCollapseEmptyLines) {
1175
1367
  // src/server.ts
1176
1368
  var import_value4 = require("@sinclair/typebox/value");
1177
1369
 
1178
- // ../../node_modules/hono/dist/compose.js
1370
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/compose.js
1179
1371
  var compose = (middleware, onError, onNotFound) => {
1180
- return (context2, next) => {
1372
+ return (context, next) => {
1181
1373
  let index = -1;
1182
1374
  return dispatch(0);
1183
1375
  async function dispatch(i) {
@@ -1190,39 +1382,72 @@ var compose = (middleware, onError, onNotFound) => {
1190
1382
  let handler;
1191
1383
  if (middleware[i]) {
1192
1384
  handler = middleware[i][0][0];
1193
- context2.req.routeIndex = i;
1385
+ context.req.routeIndex = i;
1194
1386
  } else {
1195
1387
  handler = i === middleware.length && next || void 0;
1196
1388
  }
1197
1389
  if (handler) {
1198
1390
  try {
1199
- res = await handler(context2, () => dispatch(i + 1));
1391
+ res = await handler(context, () => dispatch(i + 1));
1200
1392
  } catch (err) {
1201
1393
  if (err instanceof Error && onError) {
1202
- context2.error = err;
1203
- res = await onError(err, context2);
1394
+ context.error = err;
1395
+ res = await onError(err, context);
1204
1396
  isError = true;
1205
1397
  } else {
1206
1398
  throw err;
1207
1399
  }
1208
1400
  }
1209
1401
  } else {
1210
- if (context2.finalized === false && onNotFound) {
1211
- res = await onNotFound(context2);
1402
+ if (context.finalized === false && onNotFound) {
1403
+ res = await onNotFound(context);
1212
1404
  }
1213
1405
  }
1214
- if (res && (context2.finalized === false || isError)) {
1215
- context2.res = res;
1406
+ if (res && (context.finalized === false || isError)) {
1407
+ context.res = res;
1216
1408
  }
1217
- return context2;
1409
+ return context;
1218
1410
  }
1219
1411
  };
1220
1412
  };
1221
1413
 
1222
- // ../../node_modules/hono/dist/request/constants.js
1223
- var GET_MATCH_RESULT = Symbol();
1414
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/http-exception.js
1415
+ var HTTPException = class extends Error {
1416
+ res;
1417
+ status;
1418
+ /**
1419
+ * Creates an instance of `HTTPException`.
1420
+ * @param status - HTTP status code for the exception. Defaults to 500.
1421
+ * @param options - Additional options for the exception.
1422
+ */
1423
+ constructor(status = 500, options) {
1424
+ super(options?.message, { cause: options?.cause });
1425
+ this.res = options?.res;
1426
+ this.status = status;
1427
+ }
1428
+ /**
1429
+ * Returns the response object associated with the exception.
1430
+ * If a response object is not provided, a new response is created with the error message and status code.
1431
+ * @returns The response object.
1432
+ */
1433
+ getResponse() {
1434
+ if (this.res) {
1435
+ const newResponse = new Response(this.res.body, {
1436
+ status: this.status,
1437
+ headers: this.res.headers
1438
+ });
1439
+ return newResponse;
1440
+ }
1441
+ return new Response(this.message, {
1442
+ status: this.status
1443
+ });
1444
+ }
1445
+ };
1446
+
1447
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/request/constants.js
1448
+ var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
1224
1449
 
1225
- // ../../node_modules/hono/dist/utils/body.js
1450
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/utils/body.js
1226
1451
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
1227
1452
  const { all = false, dot = false } = options;
1228
1453
  const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
@@ -1291,7 +1516,7 @@ var handleParsingNestedValues = (form, key, value) => {
1291
1516
  });
1292
1517
  };
1293
1518
 
1294
- // ../../node_modules/hono/dist/utils/url.js
1519
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/utils/url.js
1295
1520
  var splitPath = (path) => {
1296
1521
  const paths = path.split("/");
1297
1522
  if (paths[0] === "") {
@@ -1306,9 +1531,9 @@ var splitRoutingPath = (routePath) => {
1306
1531
  };
1307
1532
  var extractGroupsFromPath = (path) => {
1308
1533
  const groups = [];
1309
- path = path.replace(/\{[^}]+\}/g, (match, index) => {
1534
+ path = path.replace(/\{[^}]+\}/g, (match2, index) => {
1310
1535
  const mark = `@${index}`;
1311
- groups.push([mark, match]);
1536
+ groups.push([mark, match2]);
1312
1537
  return mark;
1313
1538
  });
1314
1539
  return { groups, path };
@@ -1330,14 +1555,14 @@ var getPattern = (label, next) => {
1330
1555
  if (label === "*") {
1331
1556
  return "*";
1332
1557
  }
1333
- const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
1334
- if (match) {
1558
+ const match2 = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
1559
+ if (match2) {
1335
1560
  const cacheKey = `${label}#${next}`;
1336
1561
  if (!patternCache[cacheKey]) {
1337
- if (match[2]) {
1338
- patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match[1], new RegExp(`^${match[2]}(?=/${next})`)] : [label, match[1], new RegExp(`^${match[2]}$`)];
1562
+ if (match2[2]) {
1563
+ patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match2[1], new RegExp(`^${match2[2]}(?=/${next})`)] : [label, match2[1], new RegExp(`^${match2[2]}$`)];
1339
1564
  } else {
1340
- patternCache[cacheKey] = [label, match[1], true];
1565
+ patternCache[cacheKey] = [label, match2[1], true];
1341
1566
  }
1342
1567
  }
1343
1568
  return patternCache[cacheKey];
@@ -1348,11 +1573,11 @@ var tryDecode = (str, decoder) => {
1348
1573
  try {
1349
1574
  return decoder(str);
1350
1575
  } catch {
1351
- return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
1576
+ return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => {
1352
1577
  try {
1353
- return decoder(match);
1578
+ return decoder(match2);
1354
1579
  } catch {
1355
- return match;
1580
+ return match2;
1356
1581
  }
1357
1582
  });
1358
1583
  }
@@ -1360,10 +1585,7 @@ var tryDecode = (str, decoder) => {
1360
1585
  var tryDecodeURI = (str) => tryDecode(str, decodeURI);
1361
1586
  var getPath = (request) => {
1362
1587
  const url = request.url;
1363
- const start = url.indexOf(
1364
- "/",
1365
- url.charCodeAt(9) === 58 ? 13 : 8
1366
- );
1588
+ const start = url.indexOf("/", url.indexOf(":") + 4);
1367
1589
  let i = start;
1368
1590
  for (; i < url.length; i++) {
1369
1591
  const charCode = url.charCodeAt(i);
@@ -1426,9 +1648,12 @@ var _decodeURI = (value) => {
1426
1648
  var _getQueryParam = (url, key, multiple) => {
1427
1649
  let encoded;
1428
1650
  if (!multiple && key && !/[%+]/.test(key)) {
1429
- let keyIndex2 = url.indexOf(`?${key}`, 8);
1651
+ let keyIndex2 = url.indexOf("?", 8);
1430
1652
  if (keyIndex2 === -1) {
1431
- keyIndex2 = url.indexOf(`&${key}`, 8);
1653
+ return void 0;
1654
+ }
1655
+ if (!url.startsWith(key, keyIndex2 + 1)) {
1656
+ keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
1432
1657
  }
1433
1658
  while (keyIndex2 !== -1) {
1434
1659
  const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
@@ -1493,13 +1718,40 @@ var getQueryParams = (url, key) => {
1493
1718
  };
1494
1719
  var decodeURIComponent_ = decodeURIComponent;
1495
1720
 
1496
- // ../../node_modules/hono/dist/request.js
1721
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/request.js
1497
1722
  var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
1498
1723
  var HonoRequest = class {
1724
+ /**
1725
+ * `.raw` can get the raw Request object.
1726
+ *
1727
+ * @see {@link https://hono.dev/docs/api/request#raw}
1728
+ *
1729
+ * @example
1730
+ * ```ts
1731
+ * // For Cloudflare Workers
1732
+ * app.post('/', async (c) => {
1733
+ * const metadata = c.req.raw.cf?.hostMetadata?
1734
+ * ...
1735
+ * })
1736
+ * ```
1737
+ */
1499
1738
  raw;
1500
1739
  #validatedData;
1740
+ // Short name of validatedData
1501
1741
  #matchResult;
1502
1742
  routeIndex = 0;
1743
+ /**
1744
+ * `.path` can get the pathname of the request.
1745
+ *
1746
+ * @see {@link https://hono.dev/docs/api/request#path}
1747
+ *
1748
+ * @example
1749
+ * ```ts
1750
+ * app.get('/about/me', (c) => {
1751
+ * const pathname = c.req.path // `/about/me`
1752
+ * })
1753
+ * ```
1754
+ */
1503
1755
  path;
1504
1756
  bodyCache = {};
1505
1757
  constructor(request, path = "/", matchResult = [[]]) {
@@ -1514,14 +1766,14 @@ var HonoRequest = class {
1514
1766
  #getDecodedParam(key) {
1515
1767
  const paramKey = this.#matchResult[0][this.routeIndex][1][key];
1516
1768
  const param = this.#getParamValue(paramKey);
1517
- return param ? /\%/.test(param) ? tryDecodeURIComponent(param) : param : void 0;
1769
+ return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
1518
1770
  }
1519
1771
  #getAllDecodedParams() {
1520
1772
  const decoded = {};
1521
1773
  const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);
1522
1774
  for (const key of keys) {
1523
1775
  const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
1524
- if (value && typeof value === "string") {
1776
+ if (value !== void 0) {
1525
1777
  decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value;
1526
1778
  }
1527
1779
  }
@@ -1566,45 +1818,175 @@ var HonoRequest = class {
1566
1818
  }
1567
1819
  return bodyCache[key] = raw2[key]();
1568
1820
  };
1821
+ /**
1822
+ * `.json()` can parse Request body of type `application/json`
1823
+ *
1824
+ * @see {@link https://hono.dev/docs/api/request#json}
1825
+ *
1826
+ * @example
1827
+ * ```ts
1828
+ * app.post('/entry', async (c) => {
1829
+ * const body = await c.req.json()
1830
+ * })
1831
+ * ```
1832
+ */
1569
1833
  json() {
1570
1834
  return this.#cachedBody("text").then((text) => JSON.parse(text));
1571
1835
  }
1836
+ /**
1837
+ * `.text()` can parse Request body of type `text/plain`
1838
+ *
1839
+ * @see {@link https://hono.dev/docs/api/request#text}
1840
+ *
1841
+ * @example
1842
+ * ```ts
1843
+ * app.post('/entry', async (c) => {
1844
+ * const body = await c.req.text()
1845
+ * })
1846
+ * ```
1847
+ */
1572
1848
  text() {
1573
1849
  return this.#cachedBody("text");
1574
1850
  }
1851
+ /**
1852
+ * `.arrayBuffer()` parse Request body as an `ArrayBuffer`
1853
+ *
1854
+ * @see {@link https://hono.dev/docs/api/request#arraybuffer}
1855
+ *
1856
+ * @example
1857
+ * ```ts
1858
+ * app.post('/entry', async (c) => {
1859
+ * const body = await c.req.arrayBuffer()
1860
+ * })
1861
+ * ```
1862
+ */
1575
1863
  arrayBuffer() {
1576
1864
  return this.#cachedBody("arrayBuffer");
1577
1865
  }
1866
+ /**
1867
+ * Parses the request body as a `Blob`.
1868
+ * @example
1869
+ * ```ts
1870
+ * app.post('/entry', async (c) => {
1871
+ * const body = await c.req.blob();
1872
+ * });
1873
+ * ```
1874
+ * @see https://hono.dev/docs/api/request#blob
1875
+ */
1578
1876
  blob() {
1579
1877
  return this.#cachedBody("blob");
1580
1878
  }
1879
+ /**
1880
+ * Parses the request body as `FormData`.
1881
+ * @example
1882
+ * ```ts
1883
+ * app.post('/entry', async (c) => {
1884
+ * const body = await c.req.formData();
1885
+ * });
1886
+ * ```
1887
+ * @see https://hono.dev/docs/api/request#formdata
1888
+ */
1581
1889
  formData() {
1582
1890
  return this.#cachedBody("formData");
1583
1891
  }
1892
+ /**
1893
+ * Adds validated data to the request.
1894
+ *
1895
+ * @param target - The target of the validation.
1896
+ * @param data - The validated data to add.
1897
+ */
1584
1898
  addValidatedData(target, data) {
1585
1899
  this.#validatedData[target] = data;
1586
1900
  }
1587
1901
  valid(target) {
1588
1902
  return this.#validatedData[target];
1589
1903
  }
1904
+ /**
1905
+ * `.url()` can get the request url strings.
1906
+ *
1907
+ * @see {@link https://hono.dev/docs/api/request#url}
1908
+ *
1909
+ * @example
1910
+ * ```ts
1911
+ * app.get('/about/me', (c) => {
1912
+ * const url = c.req.url // `http://localhost:8787/about/me`
1913
+ * ...
1914
+ * })
1915
+ * ```
1916
+ */
1590
1917
  get url() {
1591
1918
  return this.raw.url;
1592
1919
  }
1920
+ /**
1921
+ * `.method()` can get the method name of the request.
1922
+ *
1923
+ * @see {@link https://hono.dev/docs/api/request#method}
1924
+ *
1925
+ * @example
1926
+ * ```ts
1927
+ * app.get('/about/me', (c) => {
1928
+ * const method = c.req.method // `GET`
1929
+ * })
1930
+ * ```
1931
+ */
1593
1932
  get method() {
1594
1933
  return this.raw.method;
1595
1934
  }
1596
1935
  get [GET_MATCH_RESULT]() {
1597
1936
  return this.#matchResult;
1598
1937
  }
1938
+ /**
1939
+ * `.matchedRoutes()` can return a matched route in the handler
1940
+ *
1941
+ * @deprecated
1942
+ *
1943
+ * Use matchedRoutes helper defined in "hono/route" instead.
1944
+ *
1945
+ * @see {@link https://hono.dev/docs/api/request#matchedroutes}
1946
+ *
1947
+ * @example
1948
+ * ```ts
1949
+ * app.use('*', async function logger(c, next) {
1950
+ * await next()
1951
+ * c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
1952
+ * const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
1953
+ * console.log(
1954
+ * method,
1955
+ * ' ',
1956
+ * path,
1957
+ * ' '.repeat(Math.max(10 - path.length, 0)),
1958
+ * name,
1959
+ * i === c.req.routeIndex ? '<- respond from here' : ''
1960
+ * )
1961
+ * })
1962
+ * })
1963
+ * ```
1964
+ */
1599
1965
  get matchedRoutes() {
1600
1966
  return this.#matchResult[0].map(([[, route]]) => route);
1601
1967
  }
1968
+ /**
1969
+ * `routePath()` can retrieve the path registered within the handler
1970
+ *
1971
+ * @deprecated
1972
+ *
1973
+ * Use routePath helper defined in "hono/route" instead.
1974
+ *
1975
+ * @see {@link https://hono.dev/docs/api/request#routepath}
1976
+ *
1977
+ * @example
1978
+ * ```ts
1979
+ * app.get('/posts/:id', (c) => {
1980
+ * return c.json({ path: c.req.routePath })
1981
+ * })
1982
+ * ```
1983
+ */
1602
1984
  get routePath() {
1603
1985
  return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
1604
1986
  }
1605
1987
  };
1606
1988
 
1607
- // ../../node_modules/hono/dist/utils/html.js
1989
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/utils/html.js
1608
1990
  var HtmlEscapedCallbackPhase = {
1609
1991
  Stringify: 1,
1610
1992
  BeforeStream: 2,
@@ -1616,7 +1998,7 @@ var raw = (value, callbacks) => {
1616
1998
  escapedString.callbacks = callbacks;
1617
1999
  return escapedString;
1618
2000
  };
1619
- var resolveCallback = async (str, phase, preserveCallbacks, context2, buffer) => {
2001
+ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
1620
2002
  if (typeof str === "object" && !(str instanceof String)) {
1621
2003
  if (!(str instanceof Promise)) {
1622
2004
  str = str.toString();
@@ -1634,9 +2016,9 @@ var resolveCallback = async (str, phase, preserveCallbacks, context2, buffer) =>
1634
2016
  } else {
1635
2017
  buffer = [str];
1636
2018
  }
1637
- const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context: context2 }))).then(
2019
+ const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then(
1638
2020
  (res) => Promise.all(
1639
- res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context2, buffer))
2021
+ res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer))
1640
2022
  ).then(() => buffer[0])
1641
2023
  );
1642
2024
  if (preserveCallbacks) {
@@ -1646,7 +2028,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context2, buffer) =>
1646
2028
  }
1647
2029
  };
1648
2030
 
1649
- // ../../node_modules/hono/dist/context.js
2031
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/context.js
1650
2032
  var TEXT_PLAIN = "text/plain; charset=UTF-8";
1651
2033
  var setDefaultContentType = (contentType, headers) => {
1652
2034
  return {
@@ -1657,9 +2039,37 @@ var setDefaultContentType = (contentType, headers) => {
1657
2039
  var Context = class {
1658
2040
  #rawRequest;
1659
2041
  #req;
2042
+ /**
2043
+ * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
2044
+ *
2045
+ * @see {@link https://hono.dev/docs/api/context#env}
2046
+ *
2047
+ * @example
2048
+ * ```ts
2049
+ * // Environment object for Cloudflare Workers
2050
+ * app.get('*', async c => {
2051
+ * const counter = c.env.COUNTER
2052
+ * })
2053
+ * ```
2054
+ */
1660
2055
  env = {};
1661
2056
  #var;
1662
2057
  finalized = false;
2058
+ /**
2059
+ * `.error` can get the error object from the middleware if the Handler throws an error.
2060
+ *
2061
+ * @see {@link https://hono.dev/docs/api/context#error}
2062
+ *
2063
+ * @example
2064
+ * ```ts
2065
+ * app.use('*', async (c, next) => {
2066
+ * await next()
2067
+ * if (c.error) {
2068
+ * // do something...
2069
+ * }
2070
+ * })
2071
+ * ```
2072
+ */
1663
2073
  error;
1664
2074
  #status;
1665
2075
  #executionCtx;
@@ -1670,6 +2080,12 @@ var Context = class {
1670
2080
  #preparedHeaders;
1671
2081
  #matchResult;
1672
2082
  #path;
2083
+ /**
2084
+ * Creates an instance of the Context class.
2085
+ *
2086
+ * @param req - The Request object.
2087
+ * @param options - Optional configuration options for the context.
2088
+ */
1673
2089
  constructor(req, options) {
1674
2090
  this.#rawRequest = req;
1675
2091
  if (options) {
@@ -1680,10 +2096,19 @@ var Context = class {
1680
2096
  this.#matchResult = options.matchResult;
1681
2097
  }
1682
2098
  }
2099
+ /**
2100
+ * `.req` is the instance of {@link HonoRequest}.
2101
+ */
1683
2102
  get req() {
1684
2103
  this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);
1685
2104
  return this.#req;
1686
2105
  }
2106
+ /**
2107
+ * @see {@link https://hono.dev/docs/api/context#event}
2108
+ * The FetchEvent associated with the current request.
2109
+ *
2110
+ * @throws Will throw an error if the context does not have a FetchEvent.
2111
+ */
1687
2112
  get event() {
1688
2113
  if (this.#executionCtx && "respondWith" in this.#executionCtx) {
1689
2114
  return this.#executionCtx;
@@ -1691,6 +2116,12 @@ var Context = class {
1691
2116
  throw Error("This context has no FetchEvent");
1692
2117
  }
1693
2118
  }
2119
+ /**
2120
+ * @see {@link https://hono.dev/docs/api/context#executionctx}
2121
+ * The ExecutionContext associated with the current request.
2122
+ *
2123
+ * @throws Will throw an error if the context does not have an ExecutionContext.
2124
+ */
1694
2125
  get executionCtx() {
1695
2126
  if (this.#executionCtx) {
1696
2127
  return this.#executionCtx;
@@ -1698,11 +2129,20 @@ var Context = class {
1698
2129
  throw Error("This context has no ExecutionContext");
1699
2130
  }
1700
2131
  }
2132
+ /**
2133
+ * @see {@link https://hono.dev/docs/api/context#res}
2134
+ * The Response object for the current request.
2135
+ */
1701
2136
  get res() {
1702
2137
  return this.#res ||= new Response(null, {
1703
2138
  headers: this.#preparedHeaders ??= new Headers()
1704
2139
  });
1705
2140
  }
2141
+ /**
2142
+ * Sets the Response object for the current request.
2143
+ *
2144
+ * @param _res - The Response object to set.
2145
+ */
1706
2146
  set res(_res) {
1707
2147
  if (this.#res && _res) {
1708
2148
  _res = new Response(_res.body, _res);
@@ -1724,15 +2164,75 @@ var Context = class {
1724
2164
  this.#res = _res;
1725
2165
  this.finalized = true;
1726
2166
  }
2167
+ /**
2168
+ * `.render()` can create a response within a layout.
2169
+ *
2170
+ * @see {@link https://hono.dev/docs/api/context#render-setrenderer}
2171
+ *
2172
+ * @example
2173
+ * ```ts
2174
+ * app.get('/', (c) => {
2175
+ * return c.render('Hello!')
2176
+ * })
2177
+ * ```
2178
+ */
1727
2179
  render = (...args) => {
1728
2180
  this.#renderer ??= (content) => this.html(content);
1729
2181
  return this.#renderer(...args);
1730
2182
  };
2183
+ /**
2184
+ * Sets the layout for the response.
2185
+ *
2186
+ * @param layout - The layout to set.
2187
+ * @returns The layout function.
2188
+ */
1731
2189
  setLayout = (layout) => this.#layout = layout;
2190
+ /**
2191
+ * Gets the current layout for the response.
2192
+ *
2193
+ * @returns The current layout function.
2194
+ */
1732
2195
  getLayout = () => this.#layout;
2196
+ /**
2197
+ * `.setRenderer()` can set the layout in the custom middleware.
2198
+ *
2199
+ * @see {@link https://hono.dev/docs/api/context#render-setrenderer}
2200
+ *
2201
+ * @example
2202
+ * ```tsx
2203
+ * app.use('*', async (c, next) => {
2204
+ * c.setRenderer((content) => {
2205
+ * return c.html(
2206
+ * <html>
2207
+ * <body>
2208
+ * <p>{content}</p>
2209
+ * </body>
2210
+ * </html>
2211
+ * )
2212
+ * })
2213
+ * await next()
2214
+ * })
2215
+ * ```
2216
+ */
1733
2217
  setRenderer = (renderer) => {
1734
2218
  this.#renderer = renderer;
1735
2219
  };
2220
+ /**
2221
+ * `.header()` can set headers.
2222
+ *
2223
+ * @see {@link https://hono.dev/docs/api/context#header}
2224
+ *
2225
+ * @example
2226
+ * ```ts
2227
+ * app.get('/welcome', (c) => {
2228
+ * // Set headers
2229
+ * c.header('X-Message', 'Hello!')
2230
+ * c.header('Content-Type', 'text/plain')
2231
+ *
2232
+ * return c.body('Thank you for coming')
2233
+ * })
2234
+ * ```
2235
+ */
1736
2236
  header = (name, value, options) => {
1737
2237
  if (this.finalized) {
1738
2238
  this.#res = new Response(this.#res.body, this.#res);
@@ -1749,13 +2249,50 @@ var Context = class {
1749
2249
  status = (status) => {
1750
2250
  this.#status = status;
1751
2251
  };
2252
+ /**
2253
+ * `.set()` can set the value specified by the key.
2254
+ *
2255
+ * @see {@link https://hono.dev/docs/api/context#set-get}
2256
+ *
2257
+ * @example
2258
+ * ```ts
2259
+ * app.use('*', async (c, next) => {
2260
+ * c.set('message', 'Hono is hot!!')
2261
+ * await next()
2262
+ * })
2263
+ * ```
2264
+ */
1752
2265
  set = (key, value) => {
1753
2266
  this.#var ??= /* @__PURE__ */ new Map();
1754
2267
  this.#var.set(key, value);
1755
2268
  };
2269
+ /**
2270
+ * `.get()` can use the value specified by the key.
2271
+ *
2272
+ * @see {@link https://hono.dev/docs/api/context#set-get}
2273
+ *
2274
+ * @example
2275
+ * ```ts
2276
+ * app.get('/', (c) => {
2277
+ * const message = c.get('message')
2278
+ * return c.text(`The message is "${message}"`)
2279
+ * })
2280
+ * ```
2281
+ */
1756
2282
  get = (key) => {
1757
2283
  return this.#var ? this.#var.get(key) : void 0;
1758
2284
  };
2285
+ /**
2286
+ * `.var` can access the value of a variable.
2287
+ *
2288
+ * @see {@link https://hono.dev/docs/api/context#var}
2289
+ *
2290
+ * @example
2291
+ * ```ts
2292
+ * const result = c.var.client.oneMethod()
2293
+ * ```
2294
+ */
2295
+ // c.var.propName is a read-only
1759
2296
  get var() {
1760
2297
  if (!this.#var) {
1761
2298
  return {};
@@ -1790,7 +2327,40 @@ var Context = class {
1790
2327
  return new Response(data, { status, headers: responseHeaders });
1791
2328
  }
1792
2329
  newResponse = (...args) => this.#newResponse(...args);
2330
+ /**
2331
+ * `.body()` can return the HTTP response.
2332
+ * You can set headers with `.header()` and set HTTP status code with `.status`.
2333
+ * This can also be set in `.text()`, `.json()` and so on.
2334
+ *
2335
+ * @see {@link https://hono.dev/docs/api/context#body}
2336
+ *
2337
+ * @example
2338
+ * ```ts
2339
+ * app.get('/welcome', (c) => {
2340
+ * // Set headers
2341
+ * c.header('X-Message', 'Hello!')
2342
+ * c.header('Content-Type', 'text/plain')
2343
+ * // Set HTTP status code
2344
+ * c.status(201)
2345
+ *
2346
+ * // Return the response body
2347
+ * return c.body('Thank you for coming')
2348
+ * })
2349
+ * ```
2350
+ */
1793
2351
  body = (data, arg, headers) => this.#newResponse(data, arg, headers);
2352
+ /**
2353
+ * `.text()` can render text as `Content-Type:text/plain`.
2354
+ *
2355
+ * @see {@link https://hono.dev/docs/api/context#text}
2356
+ *
2357
+ * @example
2358
+ * ```ts
2359
+ * app.get('/say', (c) => {
2360
+ * return c.text('Hello!')
2361
+ * })
2362
+ * ```
2363
+ */
1794
2364
  text = (text, arg, headers) => {
1795
2365
  return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(
1796
2366
  text,
@@ -1798,6 +2368,18 @@ var Context = class {
1798
2368
  setDefaultContentType(TEXT_PLAIN, headers)
1799
2369
  );
1800
2370
  };
2371
+ /**
2372
+ * `.json()` can render JSON as `Content-Type:application/json`.
2373
+ *
2374
+ * @see {@link https://hono.dev/docs/api/context#json}
2375
+ *
2376
+ * @example
2377
+ * ```ts
2378
+ * app.get('/api', (c) => {
2379
+ * return c.json({ message: 'Hello!' })
2380
+ * })
2381
+ * ```
2382
+ */
1801
2383
  json = (object, arg, headers) => {
1802
2384
  return this.#newResponse(
1803
2385
  JSON.stringify(object),
@@ -1809,21 +2391,50 @@ var Context = class {
1809
2391
  const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers));
1810
2392
  return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
1811
2393
  };
2394
+ /**
2395
+ * `.redirect()` can Redirect, default status code is 302.
2396
+ *
2397
+ * @see {@link https://hono.dev/docs/api/context#redirect}
2398
+ *
2399
+ * @example
2400
+ * ```ts
2401
+ * app.get('/redirect', (c) => {
2402
+ * return c.redirect('/')
2403
+ * })
2404
+ * app.get('/redirect-permanently', (c) => {
2405
+ * return c.redirect('/', 301)
2406
+ * })
2407
+ * ```
2408
+ */
1812
2409
  redirect = (location, status) => {
1813
2410
  const locationString = String(location);
1814
2411
  this.header(
1815
2412
  "Location",
2413
+ // Multibyes should be encoded
2414
+ // eslint-disable-next-line no-control-regex
1816
2415
  !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
1817
2416
  );
1818
2417
  return this.newResponse(null, status ?? 302);
1819
2418
  };
2419
+ /**
2420
+ * `.notFound()` can return the Not Found Response.
2421
+ *
2422
+ * @see {@link https://hono.dev/docs/api/context#notfound}
2423
+ *
2424
+ * @example
2425
+ * ```ts
2426
+ * app.get('/notfound', (c) => {
2427
+ * return c.notFound()
2428
+ * })
2429
+ * ```
2430
+ */
1820
2431
  notFound = () => {
1821
2432
  this.#notFoundHandler ??= () => new Response();
1822
2433
  return this.#notFoundHandler(this);
1823
2434
  };
1824
2435
  };
1825
2436
 
1826
- // ../../node_modules/hono/dist/router.js
2437
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router.js
1827
2438
  var METHOD_NAME_ALL = "ALL";
1828
2439
  var METHOD_NAME_ALL_LOWERCASE = "all";
1829
2440
  var METHODS = ["get", "post", "put", "delete", "options", "patch"];
@@ -1831,10 +2442,10 @@ var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is
1831
2442
  var UnsupportedPathError = class extends Error {
1832
2443
  };
1833
2444
 
1834
- // ../../node_modules/hono/dist/utils/constants.js
2445
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/utils/constants.js
1835
2446
  var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
1836
2447
 
1837
- // ../../node_modules/hono/dist/hono-base.js
2448
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/hono-base.js
1838
2449
  var notFoundHandler = (c) => {
1839
2450
  return c.text("404 Not Found", 404);
1840
2451
  };
@@ -1846,7 +2457,7 @@ var errorHandler = (err, c) => {
1846
2457
  console.error(err);
1847
2458
  return c.text("Internal Server Error", 500);
1848
2459
  };
1849
- var Hono = class {
2460
+ var Hono = class _Hono {
1850
2461
  get;
1851
2462
  post;
1852
2463
  put;
@@ -1856,8 +2467,13 @@ var Hono = class {
1856
2467
  all;
1857
2468
  on;
1858
2469
  use;
2470
+ /*
2471
+ This class is like an abstract class and does not have a router.
2472
+ To use it, inherit the class and implement router in the constructor.
2473
+ */
1859
2474
  router;
1860
2475
  getPath;
2476
+ // Cannot use `#` because it requires visibility at JavaScript runtime.
1861
2477
  _basePath = "/";
1862
2478
  #path = "/";
1863
2479
  routes = [];
@@ -1904,7 +2520,7 @@ var Hono = class {
1904
2520
  this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
1905
2521
  }
1906
2522
  #clone() {
1907
- const clone = new Hono({
2523
+ const clone = new _Hono({
1908
2524
  router: this.router,
1909
2525
  getPath: this.getPath
1910
2526
  });
@@ -1914,7 +2530,26 @@ var Hono = class {
1914
2530
  return clone;
1915
2531
  }
1916
2532
  #notFoundHandler = notFoundHandler;
2533
+ // Cannot use `#` because it requires visibility at JavaScript runtime.
1917
2534
  errorHandler = errorHandler;
2535
+ /**
2536
+ * `.route()` allows grouping other Hono instance in routes.
2537
+ *
2538
+ * @see {@link https://hono.dev/docs/api/routing#grouping}
2539
+ *
2540
+ * @param {string} path - base Path
2541
+ * @param {Hono} app - other Hono instance
2542
+ * @returns {Hono} routed Hono instance
2543
+ *
2544
+ * @example
2545
+ * ```ts
2546
+ * const app = new Hono()
2547
+ * const app2 = new Hono()
2548
+ *
2549
+ * app2.get("/user", (c) => c.text("user"))
2550
+ * app.route("/api", app2) // GET /api/user
2551
+ * ```
2552
+ */
1918
2553
  route(path, app) {
1919
2554
  const subApp = this.basePath(path);
1920
2555
  app.routes.map((r) => {
@@ -1929,19 +2564,95 @@ var Hono = class {
1929
2564
  });
1930
2565
  return this;
1931
2566
  }
2567
+ /**
2568
+ * `.basePath()` allows base paths to be specified.
2569
+ *
2570
+ * @see {@link https://hono.dev/docs/api/routing#base-path}
2571
+ *
2572
+ * @param {string} path - base Path
2573
+ * @returns {Hono} changed Hono instance
2574
+ *
2575
+ * @example
2576
+ * ```ts
2577
+ * const api = new Hono().basePath('/api')
2578
+ * ```
2579
+ */
1932
2580
  basePath(path) {
1933
2581
  const subApp = this.#clone();
1934
2582
  subApp._basePath = mergePath(this._basePath, path);
1935
2583
  return subApp;
1936
2584
  }
2585
+ /**
2586
+ * `.onError()` handles an error and returns a customized Response.
2587
+ *
2588
+ * @see {@link https://hono.dev/docs/api/hono#error-handling}
2589
+ *
2590
+ * @param {ErrorHandler} handler - request Handler for error
2591
+ * @returns {Hono} changed Hono instance
2592
+ *
2593
+ * @example
2594
+ * ```ts
2595
+ * app.onError((err, c) => {
2596
+ * console.error(`${err}`)
2597
+ * return c.text('Custom Error Message', 500)
2598
+ * })
2599
+ * ```
2600
+ */
1937
2601
  onError = (handler) => {
1938
2602
  this.errorHandler = handler;
1939
2603
  return this;
1940
2604
  };
2605
+ /**
2606
+ * `.notFound()` allows you to customize a Not Found Response.
2607
+ *
2608
+ * @see {@link https://hono.dev/docs/api/hono#not-found}
2609
+ *
2610
+ * @param {NotFoundHandler} handler - request handler for not-found
2611
+ * @returns {Hono} changed Hono instance
2612
+ *
2613
+ * @example
2614
+ * ```ts
2615
+ * app.notFound((c) => {
2616
+ * return c.text('Custom 404 Message', 404)
2617
+ * })
2618
+ * ```
2619
+ */
1941
2620
  notFound = (handler) => {
1942
2621
  this.#notFoundHandler = handler;
1943
2622
  return this;
1944
2623
  };
2624
+ /**
2625
+ * `.mount()` allows you to mount applications built with other frameworks into your Hono application.
2626
+ *
2627
+ * @see {@link https://hono.dev/docs/api/hono#mount}
2628
+ *
2629
+ * @param {string} path - base Path
2630
+ * @param {Function} applicationHandler - other Request Handler
2631
+ * @param {MountOptions} [options] - options of `.mount()`
2632
+ * @returns {Hono} mounted Hono instance
2633
+ *
2634
+ * @example
2635
+ * ```ts
2636
+ * import { Router as IttyRouter } from 'itty-router'
2637
+ * import { Hono } from 'hono'
2638
+ * // Create itty-router application
2639
+ * const ittyRouter = IttyRouter()
2640
+ * // GET /itty-router/hello
2641
+ * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
2642
+ *
2643
+ * const app = new Hono()
2644
+ * app.mount('/itty-router', ittyRouter.handle)
2645
+ * ```
2646
+ *
2647
+ * @example
2648
+ * ```ts
2649
+ * const app = new Hono()
2650
+ * // Send the request to another application without modification.
2651
+ * app.mount('/app', anotherApp, {
2652
+ * replaceRequest: (req) => req,
2653
+ * })
2654
+ * ```
2655
+ */
1945
2656
  mount(path, applicationHandler, options) {
1946
2657
  let replaceRequest;
1947
2658
  let optionHandler;
@@ -2029,21 +2740,44 @@ var Hono = class {
2029
2740
  const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
2030
2741
  return (async () => {
2031
2742
  try {
2032
- const context2 = await composed(c);
2033
- if (!context2.finalized) {
2743
+ const context = await composed(c);
2744
+ if (!context.finalized) {
2034
2745
  throw new Error(
2035
2746
  "Context is not finalized. Did you forget to return a Response object or `await next()`?"
2036
2747
  );
2037
2748
  }
2038
- return context2.res;
2749
+ return context.res;
2039
2750
  } catch (err) {
2040
2751
  return this.#handleError(err, c);
2041
2752
  }
2042
2753
  })();
2043
2754
  }
2755
+ /**
2756
+ * `.fetch()` will be entry point of your app.
2757
+ *
2758
+ * @see {@link https://hono.dev/docs/api/hono#fetch}
2759
+ *
2760
+ * @param {Request} request - request Object of request
2761
+ * @param {Env} Env - env Object
2762
+ * @param {ExecutionContext} - context of execution
2763
+ * @returns {Response | Promise<Response>} response of request
2764
+ *
2765
+ */
2044
2766
  fetch = (request, ...rest) => {
2045
2767
  return this.#dispatch(request, rest[1], rest[0], request.method);
2046
2768
  };
2769
+ /**
2770
+ * `.request()` is a useful method for testing.
2771
+ * You can pass a URL or pathname to send a GET request.
2772
+ * app will return a Response object.
2773
+ * ```ts
2774
+ * test('GET /hello is ok', async () => {
2775
+ * const res = await app.request('/hello')
2776
+ * expect(res.status).toBe(200)
2777
+ * })
2778
+ * ```
2779
+ * @see https://hono.dev/docs/api/hono#request
2780
+ */
2047
2781
  request = (input, requestInit, Env, executionCtx) => {
2048
2782
  if (input instanceof Request) {
2049
2783
  return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
@@ -2058,6 +2792,23 @@ var Hono = class {
2058
2792
  executionCtx
2059
2793
  );
2060
2794
  };
2795
+ /**
2796
+ * `.fire()` automatically adds a global fetch event listener.
2797
+ * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
2798
+ * @deprecated
2799
+ * Use `fire` from `hono/service-worker` instead.
2800
+ * ```ts
2801
+ * import { Hono } from 'hono'
2802
+ * import { fire } from 'hono/service-worker'
2803
+ *
2804
+ * const app = new Hono()
2805
+ * // ...
2806
+ * fire(app)
2807
+ * ```
2808
+ * @see https://hono.dev/docs/api/hono#fire
2809
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
2810
+ * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
2811
+ */
2061
2812
  fire = () => {
2062
2813
  addEventListener("fetch", (event) => {
2063
2814
  event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
@@ -2065,11 +2816,32 @@ var Hono = class {
2065
2816
  };
2066
2817
  };
2067
2818
 
2068
- // ../../node_modules/hono/dist/router/reg-exp-router/node.js
2819
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/reg-exp-router/matcher.js
2820
+ var emptyParam = [];
2821
+ function match(method, path) {
2822
+ const matchers = this.buildAllMatchers();
2823
+ const match2 = ((method2, path2) => {
2824
+ const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
2825
+ const staticMatch = matcher[2][path2];
2826
+ if (staticMatch) {
2827
+ return staticMatch;
2828
+ }
2829
+ const match3 = path2.match(matcher[0]);
2830
+ if (!match3) {
2831
+ return [[], emptyParam];
2832
+ }
2833
+ const index = match3.indexOf("", 1);
2834
+ return [matcher[1][index], match3];
2835
+ });
2836
+ this.match = match2;
2837
+ return match2(method, path);
2838
+ }
2839
+
2840
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/reg-exp-router/node.js
2069
2841
  var LABEL_REG_EXP_STR = "[^/]+";
2070
2842
  var ONLY_WILDCARD_REG_EXP_STR = ".*";
2071
2843
  var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
2072
- var PATH_ERROR = Symbol();
2844
+ var PATH_ERROR = /* @__PURE__ */ Symbol();
2073
2845
  var regExpMetaChars = new Set(".\\+*[^]$()");
2074
2846
  function compareKey(a, b) {
2075
2847
  if (a.length === 1) {
@@ -2090,11 +2862,11 @@ function compareKey(a, b) {
2090
2862
  }
2091
2863
  return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;
2092
2864
  }
2093
- var Node = class {
2865
+ var Node = class _Node {
2094
2866
  #index;
2095
2867
  #varIndex;
2096
2868
  #children = /* @__PURE__ */ Object.create(null);
2097
- insert(tokens, index, paramMap, context2, pathErrorCheckOnly) {
2869
+ insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
2098
2870
  if (tokens.length === 0) {
2099
2871
  if (this.#index !== void 0) {
2100
2872
  throw PATH_ERROR;
@@ -2130,9 +2902,9 @@ var Node = class {
2130
2902
  if (pathErrorCheckOnly) {
2131
2903
  return;
2132
2904
  }
2133
- node = this.#children[regexpStr] = new Node();
2905
+ node = this.#children[regexpStr] = new _Node();
2134
2906
  if (name !== "") {
2135
- node.#varIndex = context2.varIndex++;
2907
+ node.#varIndex = context.varIndex++;
2136
2908
  }
2137
2909
  }
2138
2910
  if (!pathErrorCheckOnly && name !== "") {
@@ -2149,10 +2921,10 @@ var Node = class {
2149
2921
  if (pathErrorCheckOnly) {
2150
2922
  return;
2151
2923
  }
2152
- node = this.#children[token] = new Node();
2924
+ node = this.#children[token] = new _Node();
2153
2925
  }
2154
2926
  }
2155
- node.insert(restTokens, index, paramMap, context2, pathErrorCheckOnly);
2927
+ node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
2156
2928
  }
2157
2929
  buildRegExpStr() {
2158
2930
  const childKeys = Object.keys(this.#children).sort(compareKey);
@@ -2173,7 +2945,7 @@ var Node = class {
2173
2945
  }
2174
2946
  };
2175
2947
 
2176
- // ../../node_modules/hono/dist/router/reg-exp-router/trie.js
2948
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/reg-exp-router/trie.js
2177
2949
  var Trie = class {
2178
2950
  #context = { varIndex: 0 };
2179
2951
  #root = new Node();
@@ -2229,8 +3001,7 @@ var Trie = class {
2229
3001
  }
2230
3002
  };
2231
3003
 
2232
- // ../../node_modules/hono/dist/router/reg-exp-router/router.js
2233
- var emptyParam = [];
3004
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/reg-exp-router/router.js
2234
3005
  var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
2235
3006
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
2236
3007
  function buildWildcardRegExp(path) {
@@ -2377,30 +3148,14 @@ var RegExpRouter = class {
2377
3148
  });
2378
3149
  }
2379
3150
  }
2380
- match(method, path) {
2381
- clearWildcardRegExpCache();
2382
- const matchers = this.#buildAllMatchers();
2383
- this.match = (method2, path2) => {
2384
- const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
2385
- const staticMatch = matcher[2][path2];
2386
- if (staticMatch) {
2387
- return staticMatch;
2388
- }
2389
- const match = path2.match(matcher[0]);
2390
- if (!match) {
2391
- return [[], emptyParam];
2392
- }
2393
- const index = match.indexOf("", 1);
2394
- return [matcher[1][index], match];
2395
- };
2396
- return this.match(method, path);
2397
- }
2398
- #buildAllMatchers() {
3151
+ match = match;
3152
+ buildAllMatchers() {
2399
3153
  const matchers = /* @__PURE__ */ Object.create(null);
2400
3154
  Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
2401
3155
  matchers[method] ||= this.#buildMatcher(method);
2402
3156
  });
2403
3157
  this.#middleware = this.#routes = void 0;
3158
+ clearWildcardRegExpCache();
2404
3159
  return matchers;
2405
3160
  }
2406
3161
  #buildMatcher(method) {
@@ -2425,7 +3180,7 @@ var RegExpRouter = class {
2425
3180
  }
2426
3181
  };
2427
3182
 
2428
- // ../../node_modules/hono/dist/router/smart-router/router.js
3183
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/smart-router/router.js
2429
3184
  var SmartRouter = class {
2430
3185
  name = "SmartRouter";
2431
3186
  #routers = [];
@@ -2480,9 +3235,9 @@ var SmartRouter = class {
2480
3235
  }
2481
3236
  };
2482
3237
 
2483
- // ../../node_modules/hono/dist/router/trie-router/node.js
3238
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/trie-router/node.js
2484
3239
  var emptyParams = /* @__PURE__ */ Object.create(null);
2485
- var Node2 = class {
3240
+ var Node2 = class _Node2 {
2486
3241
  #methods;
2487
3242
  #children;
2488
3243
  #patterns;
@@ -2515,7 +3270,7 @@ var Node2 = class {
2515
3270
  }
2516
3271
  continue;
2517
3272
  }
2518
- curNode.#children[key] = new Node2();
3273
+ curNode.#children[key] = new _Node2();
2519
3274
  if (pattern) {
2520
3275
  curNode.#patterns.push(pattern);
2521
3276
  possibleKeys.push(pattern[1]);
@@ -2638,7 +3393,7 @@ var Node2 = class {
2638
3393
  }
2639
3394
  };
2640
3395
 
2641
- // ../../node_modules/hono/dist/router/trie-router/router.js
3396
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/trie-router/router.js
2642
3397
  var TrieRouter = class {
2643
3398
  name = "TrieRouter";
2644
3399
  #node;
@@ -2660,8 +3415,13 @@ var TrieRouter = class {
2660
3415
  }
2661
3416
  };
2662
3417
 
2663
- // ../../node_modules/hono/dist/hono.js
3418
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/hono.js
2664
3419
  var Hono2 = class extends Hono {
3420
+ /**
3421
+ * Creates an instance of the Hono class.
3422
+ *
3423
+ * @param options - Optional configuration options for the Hono instance.
3424
+ */
2665
3425
  constructor(options = {}) {
2666
3426
  super(options);
2667
3427
  this.router = options.router ?? new SmartRouter({
@@ -2670,35 +3430,12 @@ var Hono2 = class extends Hono {
2670
3430
  }
2671
3431
  };
2672
3432
 
2673
- // ../../node_modules/hono/dist/http-exception.js
2674
- var HTTPException = class extends Error {
2675
- res;
2676
- status;
2677
- constructor(status = 500, options) {
2678
- super(options?.message, { cause: options?.cause });
2679
- this.res = options?.res;
2680
- this.status = status;
2681
- }
2682
- getResponse() {
2683
- if (this.res) {
2684
- const newResponse = new Response(this.res.body, {
2685
- status: this.status,
2686
- headers: this.res.headers
2687
- });
2688
- return newResponse;
2689
- }
2690
- return new Response(this.message, {
2691
- status: this.status
2692
- });
2693
- }
2694
- };
2695
-
2696
3433
  // src/server.ts
2697
- async function handleError2(context2, pluginOptions, error) {
3434
+ async function handleError2(context, pluginOptions, error) {
2698
3435
  console.error(error);
2699
- const loggerError = transformError(context2, error);
3436
+ const loggerError = transformError(context, error);
2700
3437
  if (pluginOptions.postCommentOnError && loggerError) {
2701
- await context2.commentHandler.postComment(context2, loggerError);
3438
+ await context.commentHandler.postComment(context, loggerError);
2702
3439
  }
2703
3440
  throw new HTTPException(500, { message: "Unexpected error" });
2704
3441
  }
@@ -2749,7 +3486,7 @@ function createPlugin(handler, manifest, options) {
2749
3486
  const workerName = new URL(inputs.ref).hostname.split(".")[0];
2750
3487
  PluginRuntimeInfo.getInstance({ ...env2, CLOUDFLARE_WORKER_NAME: workerName });
2751
3488
  const command = getCommand(inputs, pluginOptions);
2752
- const context2 = {
3489
+ const context = {
2753
3490
  eventName: inputs.eventName,
2754
3491
  payload: inputs.eventPayload,
2755
3492
  command,
@@ -2762,10 +3499,10 @@ function createPlugin(handler, manifest, options) {
2762
3499
  commentHandler: new CommentHandler()
2763
3500
  };
2764
3501
  try {
2765
- const result = await handler(context2);
3502
+ const result = await handler(context);
2766
3503
  return ctx.json({ stateId: inputs.stateId, output: result ?? {} });
2767
3504
  } catch (error) {
2768
- await handleError2(context2, pluginOptions, error);
3505
+ await handleError2(context, pluginOptions, error);
2769
3506
  }
2770
3507
  });
2771
3508
  return app;
@@ -2780,6 +3517,14 @@ function normalizeBaseUrl(baseUrl) {
2780
3517
  }
2781
3518
  return normalized;
2782
3519
  }
3520
+ var MAX_LLM_RETRIES = 2;
3521
+ var RETRY_BACKOFF_MS = [250, 750];
3522
+ function getRetryDelayMs(attempt) {
3523
+ return RETRY_BACKOFF_MS[Math.min(attempt, RETRY_BACKOFF_MS.length - 1)] ?? 750;
3524
+ }
3525
+ function sleep(ms) {
3526
+ return new Promise((resolve) => setTimeout(resolve, ms));
3527
+ }
2783
3528
  function getEnvString(name) {
2784
3529
  if (typeof process === "undefined" || !process?.env) return EMPTY_STRING;
2785
3530
  return String(process.env[name] ?? EMPTY_STRING).trim();
@@ -2794,7 +3539,11 @@ function getAiBaseUrl(options) {
2794
3539
  }
2795
3540
  async function callLlm(options, input) {
2796
3541
  const authToken = String(input.authToken ?? EMPTY_STRING).trim();
2797
- if (!authToken) throw new Error("Missing authToken in input");
3542
+ if (!authToken) {
3543
+ const err = new Error("Missing authToken in input");
3544
+ err.status = 401;
3545
+ throw err;
3546
+ }
2798
3547
  const kernelToken = "ubiquityKernelToken" in input ? input.ubiquityKernelToken : void 0;
2799
3548
  const payload = getPayload(input);
2800
3549
  const { owner, repo, installationId } = getRepoMetadata(payload);
@@ -2814,13 +3563,7 @@ async function callLlm(options, input) {
2814
3563
  installationId,
2815
3564
  ubiquityKernelToken: kernelToken
2816
3565
  });
2817
- const response = await fetch(url, { method: "POST", headers, body });
2818
- if (!response.ok) {
2819
- const err = await response.text();
2820
- const error = new Error(`LLM API error: ${response.status} - ${err}`);
2821
- error.status = response.status;
2822
- throw error;
2823
- }
3566
+ const response = await fetchWithRetry(url, { method: "POST", headers, body }, MAX_LLM_RETRIES);
2824
3567
  if (isStream) {
2825
3568
  if (!response.body) {
2826
3569
  throw new Error("LLM API error: missing response body for streaming request");
@@ -2832,17 +3575,46 @@ async function callLlm(options, input) {
2832
3575
  function ensureKernelToken(authToken, kernelToken) {
2833
3576
  const isKernelTokenRequired = authToken.startsWith("gh");
2834
3577
  if (isKernelTokenRequired && !kernelToken) {
2835
- throw new Error("Missing ubiquityKernelToken in input (kernel attestation is required for GitHub auth)");
3578
+ const err = new Error("Missing ubiquityKernelToken in input (kernel attestation is required for GitHub auth)");
3579
+ err.status = 401;
3580
+ throw err;
2836
3581
  }
2837
3582
  }
2838
3583
  function ensureMessages(messages) {
2839
3584
  if (!Array.isArray(messages) || messages.length === 0) {
2840
- throw new Error("messages must be a non-empty array");
3585
+ const err = new Error("messages must be a non-empty array");
3586
+ err.status = 400;
3587
+ throw err;
2841
3588
  }
2842
3589
  }
2843
3590
  function buildAiUrl(options, baseUrl) {
2844
3591
  return `${getAiBaseUrl({ ...options, baseUrl })}/v1/chat/completions`;
2845
3592
  }
3593
+ async function fetchWithRetry(url, options, maxRetries) {
3594
+ let attempt = 0;
3595
+ let lastError;
3596
+ while (attempt <= maxRetries) {
3597
+ try {
3598
+ const response = await fetch(url, options);
3599
+ if (response.ok) return response;
3600
+ const errText = await response.text();
3601
+ if (response.status >= 500 && attempt < maxRetries) {
3602
+ await sleep(getRetryDelayMs(attempt));
3603
+ attempt += 1;
3604
+ continue;
3605
+ }
3606
+ const error = new Error(`LLM API error: ${response.status} - ${errText}`);
3607
+ error.status = response.status;
3608
+ throw error;
3609
+ } catch (error) {
3610
+ lastError = error;
3611
+ if (attempt >= maxRetries) throw error;
3612
+ await sleep(getRetryDelayMs(attempt));
3613
+ attempt += 1;
3614
+ }
3615
+ }
3616
+ throw lastError ?? new Error("LLM API error: request failed after retries");
3617
+ }
2846
3618
  function getPayload(input) {
2847
3619
  if ("payload" in input) {
2848
3620
  return input.payload;
@@ -2904,7 +3676,7 @@ function getEventData(event) {
2904
3676
  if (!event.trim()) return null;
2905
3677
  const dataLines = event.split("\n").filter((line) => line.startsWith("data:"));
2906
3678
  if (!dataLines.length) return null;
2907
- const data = dataLines.map((line) => line.startsWith("data: ") ? line.slice(6) : line.slice(5).replace(/^ /, "")).join("\n");
3679
+ const data = dataLines.map((line) => line.startsWith("data: ") ? line.slice(6) : line.slice(5).replace(/^ /, EMPTY_STRING)).join("\n");
2908
3680
  return data || null;
2909
3681
  }
2910
3682
  function parseEventData(data) {