@inkeep/agents-work-apps 0.0.0-dev-20260219103848 → 0.0.0-dev-20260219105522
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/env.d.ts +2 -2
- package/dist/github/index.d.ts +3 -3
- package/dist/github/mcp/index.d.ts +2 -2
- package/dist/github/mcp/schemas.d.ts +1 -1
- package/dist/github/routes/setup.d.ts +2 -2
- package/dist/github/routes/tokenExchange.d.ts +2 -2
- package/dist/slack/i18n/strings.d.ts +5 -5
- package/dist/slack/i18n/strings.js +9 -9
- package/dist/slack/routes/workspaces.js +1 -1
- package/dist/slack/services/blocks/index.js +7 -11
- package/dist/slack/services/events/app-mention.js +4 -13
- package/dist/slack/services/events/modal-submission.js +2 -2
- package/dist/slack/services/events/utils.d.ts +1 -1
- package/dist/slack/services/events/utils.js +5 -5
- package/dist/slack/services/modals.js +2 -2
- package/package.json +2 -2
package/dist/env.d.ts
CHANGED
|
@@ -14,11 +14,11 @@ declare const envSchema: z.ZodObject<{
|
|
|
14
14
|
pentest: "pentest";
|
|
15
15
|
}>>;
|
|
16
16
|
LOG_LEVEL: z.ZodDefault<z.ZodEnum<{
|
|
17
|
+
error: "error";
|
|
17
18
|
trace: "trace";
|
|
18
19
|
debug: "debug";
|
|
19
20
|
info: "info";
|
|
20
21
|
warn: "warn";
|
|
21
|
-
error: "error";
|
|
22
22
|
}>>;
|
|
23
23
|
INKEEP_AGENTS_RUN_DATABASE_URL: z.ZodString;
|
|
24
24
|
INKEEP_AGENTS_MANAGE_UI_URL: z.ZodOptional<z.ZodString>;
|
|
@@ -44,7 +44,7 @@ declare const envSchema: z.ZodObject<{
|
|
|
44
44
|
declare const env: {
|
|
45
45
|
NODE_ENV: "development" | "production" | "test";
|
|
46
46
|
ENVIRONMENT: "development" | "production" | "test" | "pentest";
|
|
47
|
-
LOG_LEVEL: "
|
|
47
|
+
LOG_LEVEL: "error" | "trace" | "debug" | "info" | "warn";
|
|
48
48
|
INKEEP_AGENTS_RUN_DATABASE_URL: string;
|
|
49
49
|
INKEEP_AGENTS_MANAGE_UI_URL?: string | undefined;
|
|
50
50
|
GITHUB_APP_ID?: string | undefined;
|
package/dist/github/index.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ import "./routes/setup.js";
|
|
|
4
4
|
import "./routes/tokenExchange.js";
|
|
5
5
|
import { WebhookVerificationResult, verifyWebhookSignature } from "./routes/webhooks.js";
|
|
6
6
|
import { Hono } from "hono";
|
|
7
|
-
import * as
|
|
7
|
+
import * as hono_types4 from "hono/types";
|
|
8
8
|
|
|
9
9
|
//#region src/github/index.d.ts
|
|
10
|
-
declare function createGithubRoutes(): Hono<
|
|
11
|
-
declare const githubRoutes: Hono<
|
|
10
|
+
declare function createGithubRoutes(): Hono<hono_types4.BlankEnv, hono_types4.BlankSchema, "/">;
|
|
11
|
+
declare const githubRoutes: Hono<hono_types4.BlankEnv, hono_types4.BlankSchema, "/">;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { GenerateInstallationAccessTokenResult, GenerateTokenError, GenerateTokenResult, GitHubAppConfig, InstallationAccessToken, InstallationInfo, LookupInstallationError, LookupInstallationForRepoResult, LookupInstallationResult, WebhookVerificationResult, clearConfigCache, createAppJwt, createGithubRoutes, determineStatus, fetchInstallationDetails, fetchInstallationRepositories, generateInstallationAccessToken, getGitHubAppConfig, getGitHubAppName, getStateSigningSecret, getWebhookSecret, githubRoutes, isGitHubAppConfigured, isGitHubAppNameConfigured, isStateSigningConfigured, isWebhookConfigured, lookupInstallationForRepo, validateGitHubAppConfigOnStartup, validateGitHubInstallFlowConfigOnStartup, validateGitHubWebhookConfigOnStartup, verifyWebhookSignature };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types0 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/mcp/index.d.ts
|
|
5
5
|
declare const app: Hono<{
|
|
6
6
|
Variables: {
|
|
7
7
|
toolId: string;
|
|
8
8
|
};
|
|
9
|
-
},
|
|
9
|
+
}, hono_types0.BlankSchema, "/">;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { app as default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types0 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/routes/setup.d.ts
|
|
5
|
-
declare const app: Hono<
|
|
5
|
+
declare const app: Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { app as default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types2 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/routes/tokenExchange.d.ts
|
|
5
|
-
declare const app: Hono<
|
|
5
|
+
declare const app: Hono<hono_types2.BlankEnv, hono_types2.BlankSchema, "/">;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { app as default };
|
|
@@ -11,7 +11,7 @@ declare const SlackStrings: {
|
|
|
11
11
|
readonly send: "Send";
|
|
12
12
|
readonly followUp: "Follow Up";
|
|
13
13
|
readonly cancel: "Cancel";
|
|
14
|
-
readonly openDashboard: "
|
|
14
|
+
readonly openDashboard: "Open Dashboard";
|
|
15
15
|
};
|
|
16
16
|
readonly modals: {
|
|
17
17
|
readonly triggerAgent: "Trigger Agent";
|
|
@@ -46,18 +46,18 @@ declare const SlackStrings: {
|
|
|
46
46
|
readonly status: {
|
|
47
47
|
readonly thinking: (agentName: string) => string;
|
|
48
48
|
readonly noAgentsAvailable: "No agents available";
|
|
49
|
-
readonly noProjectsConfigured: "
|
|
49
|
+
readonly noProjectsConfigured: "No projects configured. Set up projects in the dashboard.";
|
|
50
50
|
};
|
|
51
51
|
readonly errors: {
|
|
52
|
-
readonly generic: "
|
|
53
|
-
readonly failedToOpenSelector: "
|
|
52
|
+
readonly generic: "Something went wrong. Please try again.";
|
|
53
|
+
readonly failedToOpenSelector: "Failed to open agent selector. Please try again.";
|
|
54
54
|
};
|
|
55
55
|
readonly help: {
|
|
56
56
|
readonly title: "Inkeep — How to Use";
|
|
57
57
|
readonly publicSection: string;
|
|
58
58
|
readonly privateSection: string;
|
|
59
59
|
readonly otherCommands: string;
|
|
60
|
-
readonly docsLink: "
|
|
60
|
+
readonly docsLink: "<https://docs.inkeep.com/talk-to-your-agents/slack/overview|Learn more>";
|
|
61
61
|
};
|
|
62
62
|
readonly messageContext: {
|
|
63
63
|
readonly label: "Message:";
|
|
@@ -11,7 +11,7 @@ const SlackStrings = {
|
|
|
11
11
|
send: "Send",
|
|
12
12
|
followUp: "Follow Up",
|
|
13
13
|
cancel: "Cancel",
|
|
14
|
-
openDashboard: "
|
|
14
|
+
openDashboard: "Open Dashboard"
|
|
15
15
|
},
|
|
16
16
|
modals: {
|
|
17
17
|
triggerAgent: "Trigger Agent",
|
|
@@ -38,22 +38,22 @@ const SlackStrings = {
|
|
|
38
38
|
poweredBy: (agentName) => `Powered by *${agentName}* via Inkeep`,
|
|
39
39
|
privateResponse: "_Private response_"
|
|
40
40
|
},
|
|
41
|
-
usage: { mentionEmpty: "*
|
|
41
|
+
usage: { mentionEmpty: "*Include a message to use your Inkeep agent:*\n\n• `@Inkeep <message>` — Message the default agent (reply appears in a thread)\n• `@Inkeep <message>` in a thread — Includes thread as context\n• `@Inkeep` in a thread — Uses the full thread as context\n\nUse `/inkeep help` for all available commands." },
|
|
42
42
|
status: {
|
|
43
43
|
thinking: (agentName) => `_${agentName} is thinking..._`,
|
|
44
44
|
noAgentsAvailable: "No agents available",
|
|
45
|
-
noProjectsConfigured: "
|
|
45
|
+
noProjectsConfigured: "No projects configured. Set up projects in the dashboard."
|
|
46
46
|
},
|
|
47
47
|
errors: {
|
|
48
|
-
generic: "
|
|
49
|
-
failedToOpenSelector: "
|
|
48
|
+
generic: "Something went wrong. Please try again.",
|
|
49
|
+
failedToOpenSelector: "Failed to open agent selector. Please try again."
|
|
50
50
|
},
|
|
51
51
|
help: {
|
|
52
52
|
title: "Inkeep — How to Use",
|
|
53
|
-
publicSection: "
|
|
54
|
-
privateSection: "
|
|
55
|
-
otherCommands: "
|
|
56
|
-
docsLink: "
|
|
53
|
+
publicSection: "*Public* — visible to everyone in the channel\n\n• `@Inkeep <message>` — Message the default agent in this channel\n• `@Inkeep <message>` in a thread — Includes thread as context\n• `@Inkeep` in a thread — Uses the full thread as context",
|
|
54
|
+
privateSection: "*Private* — only visible to you\n\n• `/inkeep <message>` — Message the default agent in this channel\n• `/inkeep` — Open the agent picker to choose an agent and write a prompt",
|
|
55
|
+
otherCommands: "*Other Commands*\n\n• `/inkeep status` — Check your connection and agent config\n• `/inkeep link` / `/inkeep unlink` — Manage account connection\n• `/inkeep help` — Show this message",
|
|
56
|
+
docsLink: "<https://docs.inkeep.com/talk-to-your-agents/slack/overview|Learn more>"
|
|
57
57
|
},
|
|
58
58
|
messageContext: { label: "Message:" }
|
|
59
59
|
};
|
|
@@ -854,7 +854,7 @@ app.openapi(createProtectedRoute({
|
|
|
854
854
|
}, 404);
|
|
855
855
|
try {
|
|
856
856
|
const slackClient = getSlackClient(workspace.botToken);
|
|
857
|
-
const testMessage = message || "
|
|
857
|
+
const testMessage = message || "*Test message from Inkeep*\n\nYour Slack integration is working correctly.";
|
|
858
858
|
const result = await slackClient.chat.postMessage({
|
|
859
859
|
channel: channelId,
|
|
860
860
|
text: testMessage,
|
|
@@ -3,7 +3,7 @@ import { Blocks, Elements, Md, Message } from "slack-block-builder";
|
|
|
3
3
|
|
|
4
4
|
//#region src/slack/services/blocks/index.ts
|
|
5
5
|
function createErrorMessage(message) {
|
|
6
|
-
return Message().blocks(Blocks.Section().text(
|
|
6
|
+
return Message().blocks(Blocks.Section().text(message)).buildToObject();
|
|
7
7
|
}
|
|
8
8
|
function createContextBlock(params) {
|
|
9
9
|
const { agentName, isPrivate = false } = params;
|
|
@@ -40,7 +40,7 @@ function buildConversationResponseBlocks(params) {
|
|
|
40
40
|
type: "context",
|
|
41
41
|
elements: [{
|
|
42
42
|
type: "mrkdwn",
|
|
43
|
-
text:
|
|
43
|
+
text: `*You:* ${userMessage.length > 200 ? `${userMessage.slice(0, 200)}...` : userMessage}`
|
|
44
44
|
}]
|
|
45
45
|
},
|
|
46
46
|
{ type: "divider" },
|
|
@@ -69,27 +69,23 @@ function createUpdatedHelpMessage() {
|
|
|
69
69
|
return Message().blocks(Blocks.Section().text(`${Md.bold(SlackStrings.help.title)}`), Blocks.Section().text(SlackStrings.help.publicSection), Blocks.Divider(), Blocks.Section().text(SlackStrings.help.privateSection), Blocks.Divider(), Blocks.Section().text(SlackStrings.help.otherCommands), Blocks.Divider(), Blocks.Section().text(SlackStrings.help.docsLink)).buildToObject();
|
|
70
70
|
}
|
|
71
71
|
function createAlreadyLinkedMessage(email, linkedAt, dashboardUrl) {
|
|
72
|
-
return Message().blocks(Blocks.Section().text(Md.bold("
|
|
72
|
+
return Message().blocks(Blocks.Section().text(Md.bold("Already linked") + "\n\nYour Slack account is connected to Inkeep.\n\n" + Md.bold("Account:") + ` ${email}\n` + Md.bold("Linked:") + ` ${new Date(linkedAt).toLocaleDateString()}\n\nTo switch accounts, first run \`/inkeep unlink\``), Blocks.Actions().elements(Elements.Button().text(SlackStrings.buttons.openDashboard).url(dashboardUrl).actionId("open_dashboard"))).buildToObject();
|
|
73
73
|
}
|
|
74
74
|
function createUnlinkSuccessMessage() {
|
|
75
|
-
return Message().blocks(Blocks.Section().text(Md.bold("
|
|
75
|
+
return Message().blocks(Blocks.Section().text(Md.bold("Account unlinked") + "\n\nYour Slack account has been disconnected from Inkeep.\n\nRun `/inkeep link` to connect a new account.")).buildToObject();
|
|
76
76
|
}
|
|
77
77
|
function createNotLinkedMessage() {
|
|
78
|
-
return Message().blocks(Blocks.Section().text(Md.bold("
|
|
78
|
+
return Message().blocks(Blocks.Section().text(Md.bold("Not linked") + "\n\nYour Slack account is not connected to Inkeep. Run `/inkeep link` to connect.")).buildToObject();
|
|
79
79
|
}
|
|
80
80
|
function createStatusMessage(email, linkedAt, dashboardUrl, agentConfigs) {
|
|
81
81
|
const { effective } = agentConfigs;
|
|
82
82
|
let agentLine;
|
|
83
83
|
if (effective) agentLine = `${Md.bold("Agent:")} ${effective.agentName || effective.agentId}`;
|
|
84
84
|
else agentLine = `${Md.bold("Agent:")} None configured\n${Md.italic("Ask your admin to set up an agent in the dashboard.")}`;
|
|
85
|
-
return Message().blocks(Blocks.Section().text(Md.bold("
|
|
85
|
+
return Message().blocks(Blocks.Section().text(Md.bold("Connected to Inkeep") + `\n\n${Md.bold("Account:")} ${email}\n${Md.bold("Linked:")} ${new Date(linkedAt).toLocaleDateString()}\n` + agentLine), Blocks.Actions().elements(Elements.Button().text(SlackStrings.buttons.openDashboard).url(dashboardUrl).actionId("open_dashboard"))).buildToObject();
|
|
86
86
|
}
|
|
87
87
|
function createJwtLinkMessage(linkUrl, expiresInMinutes) {
|
|
88
|
-
return Message().blocks(Blocks.Section().text(`${Md.bold("
|
|
89
|
-
• Get personalized responses from AI agents
|
|
90
|
-
• Set your own default agent preferences`), Blocks.Section().text(`${Md.bold("How to link:")}\n1. Click the button below
|
|
91
|
-
2. Sign in to Inkeep (or create an account)
|
|
92
|
-
3. Done! Come back here and start asking questions`), Blocks.Actions().elements(Elements.Button().text("🔗 Link Account").url(linkUrl).actionId("link_account").primary()), Blocks.Context().elements(`This link expires in ${expiresInMinutes} minutes`)).buildToObject();
|
|
88
|
+
return Message().blocks(Blocks.Section().text(`${Md.bold("Link your Inkeep account")}\n\nConnect your Slack and Inkeep accounts to use Inkeep agents.`), Blocks.Actions().elements(Elements.Button().text("Link Account").url(linkUrl).actionId("link_account").primary()), Blocks.Context().elements(`This link expires in ${expiresInMinutes} minutes.`)).buildToObject();
|
|
93
89
|
}
|
|
94
90
|
|
|
95
91
|
//#endregion
|
|
@@ -72,7 +72,7 @@ async function handleAppMention(params) {
|
|
|
72
72
|
await getSlackClient(botToken).chat.postEphemeral({
|
|
73
73
|
channel,
|
|
74
74
|
user: slackUserId,
|
|
75
|
-
text: "
|
|
75
|
+
text: "This workspace is not properly configured. Please reinstall the Slack app from the Inkeep dashboard."
|
|
76
76
|
}).catch((e) => logger.warn({
|
|
77
77
|
error: e,
|
|
78
78
|
channel
|
|
@@ -104,7 +104,7 @@ async function handleAppMention(params) {
|
|
|
104
104
|
channel,
|
|
105
105
|
user: slackUserId,
|
|
106
106
|
thread_ts: isInThread ? threadTs : void 0,
|
|
107
|
-
text:
|
|
107
|
+
text: `No agents configured for this workspace. *<${dashboardUrl}|Set up agents in the dashboard>*`
|
|
108
108
|
});
|
|
109
109
|
span.end();
|
|
110
110
|
return;
|
|
@@ -122,11 +122,7 @@ async function handleAppMention(params) {
|
|
|
122
122
|
channel,
|
|
123
123
|
user: slackUserId,
|
|
124
124
|
thread_ts: isInThread ? threadTs : void 0,
|
|
125
|
-
text:
|
|
126
|
-
|
|
127
|
-
Run \`/inkeep link\` to connect your Slack and Inkeep accounts.
|
|
128
|
-
|
|
129
|
-
This workspace uses: *${agentDisplayName}*`
|
|
125
|
+
text: "*Link your account to use @Inkeep*\n\nRun `/inkeep link` to connect your Slack and Inkeep accounts."
|
|
130
126
|
});
|
|
131
127
|
span.end();
|
|
132
128
|
return;
|
|
@@ -162,12 +158,7 @@ This workspace uses: *${agentDisplayName}*`
|
|
|
162
158
|
channel,
|
|
163
159
|
user: slackUserId,
|
|
164
160
|
thread_ts: threadTs,
|
|
165
|
-
text:
|
|
166
|
-
|
|
167
|
-
Just type your follow-up — no need to mention me in this thread.
|
|
168
|
-
Or use \`@Inkeep <prompt>\` to run a new prompt.
|
|
169
|
-
|
|
170
|
-
_Using: ${agentDisplayName}_`
|
|
161
|
+
text: "*Continue the conversation*\n\nType your follow-up directly in this thread — no need to mention me.\nOr use `@Inkeep <prompt>` to start a new prompt."
|
|
171
162
|
});
|
|
172
163
|
span.end();
|
|
173
164
|
return;
|
|
@@ -90,7 +90,7 @@ async function handleModalSubmission(view) {
|
|
|
90
90
|
await slackClient.chat.postEphemeral({
|
|
91
91
|
channel: metadata.channel,
|
|
92
92
|
user: metadata.slackUserId,
|
|
93
|
-
text: "
|
|
93
|
+
text: "Link your account first. Run `/inkeep link` to connect."
|
|
94
94
|
});
|
|
95
95
|
span.end();
|
|
96
96
|
return;
|
|
@@ -215,7 +215,7 @@ async function handleFollowUpSubmission(view) {
|
|
|
215
215
|
await slackClient.chat.postEphemeral({
|
|
216
216
|
channel,
|
|
217
217
|
user: slackUserId,
|
|
218
|
-
text: "
|
|
218
|
+
text: "Link your account first. Run `/inkeep link` to connect."
|
|
219
219
|
});
|
|
220
220
|
span.end();
|
|
221
221
|
return;
|
|
@@ -8,9 +8,9 @@ import { AgentOption } from "../modals.js";
|
|
|
8
8
|
* Called on every @mention and /inkeep command — caching avoids redundant DB queries.
|
|
9
9
|
*/
|
|
10
10
|
declare function findCachedUserMapping(tenantId: string, slackUserId: string, teamId: string, clientId?: string): Promise<{
|
|
11
|
+
id: string;
|
|
11
12
|
createdAt: string;
|
|
12
13
|
updatedAt: string;
|
|
13
|
-
id: string;
|
|
14
14
|
tenantId: string;
|
|
15
15
|
clientId: string;
|
|
16
16
|
slackUserId: string;
|
|
@@ -97,11 +97,11 @@ function classifyError(error, httpStatus) {
|
|
|
97
97
|
function getUserFriendlyErrorMessage(errorType, agentName) {
|
|
98
98
|
const agent = agentName || "The agent";
|
|
99
99
|
switch (errorType) {
|
|
100
|
-
case SlackErrorType.TIMEOUT: return
|
|
101
|
-
case SlackErrorType.RATE_LIMIT: return
|
|
102
|
-
case SlackErrorType.AUTH_ERROR: return
|
|
103
|
-
case SlackErrorType.API_ERROR: return
|
|
104
|
-
default: return
|
|
100
|
+
case SlackErrorType.TIMEOUT: return `*Request timed out.* ${agent} took too long to respond. Try again with a simpler question.`;
|
|
101
|
+
case SlackErrorType.RATE_LIMIT: return "*Rate limited.* Wait a moment and try again.";
|
|
102
|
+
case SlackErrorType.AUTH_ERROR: return "*Authentication error.* Run `/inkeep link` to reconnect your account.";
|
|
103
|
+
case SlackErrorType.API_ERROR: return `*Something went wrong.* ${agent} encountered an error. Try again in a moment.`;
|
|
104
|
+
default: return "*Unexpected error.* Something went wrong. Try again in a moment.";
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
const INTERNAL_FETCH_TIMEOUT_MS = 1e4;
|
|
@@ -137,7 +137,7 @@ function buildAgentSelectorModal(params) {
|
|
|
137
137
|
type: "context",
|
|
138
138
|
elements: [{
|
|
139
139
|
type: "mrkdwn",
|
|
140
|
-
text:
|
|
140
|
+
text: `<${manageUiBaseUrl}${dashboardUrl}|Open Dashboard>`
|
|
141
141
|
}]
|
|
142
142
|
});
|
|
143
143
|
return {
|
|
@@ -325,7 +325,7 @@ function buildMessageShortcutModal(params) {
|
|
|
325
325
|
type: "context",
|
|
326
326
|
elements: [{
|
|
327
327
|
type: "mrkdwn",
|
|
328
|
-
text:
|
|
328
|
+
text: `<${manageUiBaseUrl}${dashboardUrl}|Open Dashboard>`
|
|
329
329
|
}]
|
|
330
330
|
});
|
|
331
331
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/agents-work-apps",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20260219105522",
|
|
4
4
|
"description": "First party integrations for Inkeep Agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"jose": "^6.1.0",
|
|
34
34
|
"minimatch": "^10.1.1",
|
|
35
35
|
"slack-block-builder": "^2.8.0",
|
|
36
|
-
"@inkeep/agents-core": "0.0.0-dev-
|
|
36
|
+
"@inkeep/agents-core": "0.0.0-dev-20260219105522"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@hono/zod-openapi": "^1.1.5",
|