@inkeep/agents-work-apps 0.65.2 → 0.66.1
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/github/config.js +1 -1
- package/dist/github/index.d.ts +3 -3
- package/dist/github/jwks.js +2 -2
- package/dist/github/mcp/index.d.ts +2 -2
- package/dist/github/oidcToken.js +2 -2
- package/dist/github/routes/setup.d.ts +2 -2
- package/dist/github/routes/tokenExchange.d.ts +2 -2
- package/dist/github/routes/tokenExchange.js +2 -2
- package/dist/github/routes/webhooks.d.ts +2 -2
- package/dist/github/routes/webhooks.js +1 -1
- package/dist/slack/mcp/auth.d.ts +2 -2
- package/dist/slack/mcp/index.d.ts +2 -2
- package/dist/slack/routes/events.js +6 -6
- package/dist/slack/routes/oauth.js +4 -4
- package/dist/slack/routes/workspaces.js +1 -1
- package/dist/slack/services/client.js +2 -2
- package/dist/slack/services/link-prompt.d.ts +2 -2
- package/dist/slack/services/nango.js +2 -2
- package/dist/slack/services/security.js +1 -1
- package/dist/slack/socket-mode.js +4 -4
- package/package.json +2 -2
package/dist/github/config.js
CHANGED
|
@@ -19,7 +19,7 @@ function getGitHubAppConfig() {
|
|
|
19
19
|
});
|
|
20
20
|
if (!result.success) {
|
|
21
21
|
const errorMessage = `GitHub App credentials are not configured. ${result.error.issues.map((issue) => issue.message).join(". ")}. Please set GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY environment variables.`;
|
|
22
|
-
logger.error(
|
|
22
|
+
logger.error(errorMessage);
|
|
23
23
|
throw new Error(errorMessage);
|
|
24
24
|
}
|
|
25
25
|
cachedConfig = result.data;
|
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_types0 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_types0.BlankEnv, hono_types0.BlankSchema, "/">;
|
|
11
|
+
declare const githubRoutes: Hono<hono_types0.BlankEnv, hono_types0.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 };
|
package/dist/github/jwks.js
CHANGED
|
@@ -7,7 +7,7 @@ const GITHUB_OIDC_JWKS_URL = "https://token.actions.githubusercontent.com/.well-
|
|
|
7
7
|
const CACHE_TTL_MS = 3600 * 1e3;
|
|
8
8
|
let jwksCache = null;
|
|
9
9
|
function createJwksWithLogging() {
|
|
10
|
-
logger.info(
|
|
10
|
+
logger.info("Creating new JWKS fetch function for GitHub OIDC");
|
|
11
11
|
return createRemoteJWKSet(new URL(GITHUB_OIDC_JWKS_URL), { cacheMaxAge: CACHE_TTL_MS });
|
|
12
12
|
}
|
|
13
13
|
function isCacheExpired() {
|
|
@@ -70,7 +70,7 @@ async function getJwkForToken(header) {
|
|
|
70
70
|
}
|
|
71
71
|
function clearJwksCache() {
|
|
72
72
|
jwksCache = null;
|
|
73
|
-
logger.debug(
|
|
73
|
+
logger.debug("JWKS cache cleared");
|
|
74
74
|
}
|
|
75
75
|
function getJwksCacheStatus() {
|
|
76
76
|
if (!jwksCache) return { cached: false };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types4 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/mcp/index.d.ts
|
|
5
5
|
declare const app: Hono<{
|
|
@@ -8,6 +8,6 @@ declare const app: Hono<{
|
|
|
8
8
|
tenantId: string;
|
|
9
9
|
projectId: string;
|
|
10
10
|
};
|
|
11
|
-
},
|
|
11
|
+
}, hono_types4.BlankSchema, "/">;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { app as default };
|
package/dist/github/oidcToken.js
CHANGED
|
@@ -72,7 +72,7 @@ async function validateOidcToken(token) {
|
|
|
72
72
|
};
|
|
73
73
|
} catch (error) {
|
|
74
74
|
if (error instanceof errors.JWTExpired) {
|
|
75
|
-
logger.warn(
|
|
75
|
+
logger.warn("OIDC token has expired");
|
|
76
76
|
return {
|
|
77
77
|
success: false,
|
|
78
78
|
errorType: "expired",
|
|
@@ -108,7 +108,7 @@ async function validateOidcToken(token) {
|
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
110
|
if (error instanceof errors.JWSSignatureVerificationFailed) {
|
|
111
|
-
logger.warn(
|
|
111
|
+
logger.warn("Invalid OIDC token signature");
|
|
112
112
|
return {
|
|
113
113
|
success: false,
|
|
114
114
|
errorType: "invalid_signature",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types5 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_types5.BlankEnv, hono_types5.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_types7 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_types7.BlankEnv, hono_types7.BlankSchema, "/">;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { app as default };
|
|
@@ -35,9 +35,9 @@ app.post("/", async (c) => {
|
|
|
35
35
|
}, 400);
|
|
36
36
|
}
|
|
37
37
|
const body = parseResult.data;
|
|
38
|
-
logger.info(
|
|
38
|
+
logger.info("Processing token exchange request");
|
|
39
39
|
if (!isGitHubAppConfigured()) {
|
|
40
|
-
logger.error(
|
|
40
|
+
logger.error("GitHub App credentials not configured");
|
|
41
41
|
const errorMessage = "GitHub App credentials are not configured. Please contact the administrator to set up GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY.";
|
|
42
42
|
c.header("Content-Type", "application/problem+json");
|
|
43
43
|
return c.json({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types9 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/routes/webhooks.d.ts
|
|
5
5
|
interface WebhookVerificationResult {
|
|
@@ -7,6 +7,6 @@ interface WebhookVerificationResult {
|
|
|
7
7
|
error?: string;
|
|
8
8
|
}
|
|
9
9
|
declare function verifyWebhookSignature(payload: string, signature: string | undefined, secret: string): WebhookVerificationResult;
|
|
10
|
-
declare const app: Hono<
|
|
10
|
+
declare const app: Hono<hono_types9.BlankEnv, hono_types9.BlankSchema, "/">;
|
|
11
11
|
//#endregion
|
|
12
12
|
export { WebhookVerificationResult, app as default, verifyWebhookSignature };
|
|
@@ -42,7 +42,7 @@ function verifyWebhookSignature(payload, signature, secret) {
|
|
|
42
42
|
const app = new Hono();
|
|
43
43
|
app.post("/", async (c) => {
|
|
44
44
|
if (!isWebhookConfigured()) {
|
|
45
|
-
logger.error(
|
|
45
|
+
logger.error("GitHub webhook secret not configured");
|
|
46
46
|
return c.json({ error: "GitHub webhook secret not configured" }, 500);
|
|
47
47
|
}
|
|
48
48
|
const rawBody = await c.req.text();
|
package/dist/slack/mcp/auth.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as hono0 from "hono";
|
|
2
2
|
|
|
3
3
|
//#region src/slack/mcp/auth.d.ts
|
|
4
|
-
declare const slackMcpAuth: () =>
|
|
4
|
+
declare const slackMcpAuth: () => hono0.MiddlewareHandler<{
|
|
5
5
|
Variables: {
|
|
6
6
|
toolId: string;
|
|
7
7
|
tenantId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types0 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/slack/mcp/index.d.ts
|
|
5
5
|
interface ChannelInfo {
|
|
@@ -18,6 +18,6 @@ declare const app: Hono<{
|
|
|
18
18
|
tenantId: string;
|
|
19
19
|
projectId: string;
|
|
20
20
|
};
|
|
21
|
-
},
|
|
21
|
+
}, hono_types0.BlankSchema, "/">;
|
|
22
22
|
//#endregion
|
|
23
23
|
export { ChannelInfo, app as default, pruneStaleChannelIds };
|
|
@@ -28,14 +28,14 @@ app.post("/commands", async (c) => {
|
|
|
28
28
|
const timestamp = c.req.header("x-slack-request-timestamp") || "";
|
|
29
29
|
const signature = c.req.header("x-slack-signature") || "";
|
|
30
30
|
if (!env.SLACK_SIGNING_SECRET) {
|
|
31
|
-
logger.error(
|
|
31
|
+
logger.error("SLACK_SIGNING_SECRET not configured - rejecting request");
|
|
32
32
|
return c.json({
|
|
33
33
|
response_type: "ephemeral",
|
|
34
34
|
text: "Server configuration error"
|
|
35
35
|
}, 500);
|
|
36
36
|
}
|
|
37
37
|
if (!verifySlackRequest(env.SLACK_SIGNING_SECRET, body, timestamp, signature)) {
|
|
38
|
-
logger.error(
|
|
38
|
+
logger.error("Invalid Slack request signature");
|
|
39
39
|
return c.json({
|
|
40
40
|
response_type: "ephemeral",
|
|
41
41
|
text: "Invalid request signature"
|
|
@@ -100,7 +100,7 @@ app.post("/events", async (c) => {
|
|
|
100
100
|
if (!env.SLACK_SIGNING_SECRET) {
|
|
101
101
|
outcome = "error";
|
|
102
102
|
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
103
|
-
logger.error(
|
|
103
|
+
logger.error("SLACK_SIGNING_SECRET not configured - rejecting request");
|
|
104
104
|
span.end();
|
|
105
105
|
return c.json({ error: "Server configuration error" }, 500);
|
|
106
106
|
}
|
|
@@ -114,7 +114,7 @@ app.post("/events", async (c) => {
|
|
|
114
114
|
if (eventType === "url_verification") {
|
|
115
115
|
outcome = "url_verification";
|
|
116
116
|
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
117
|
-
logger.info(
|
|
117
|
+
logger.info("Responding to Slack URL verification challenge");
|
|
118
118
|
span.end();
|
|
119
119
|
return c.text(String(eventBody.challenge));
|
|
120
120
|
}
|
|
@@ -146,12 +146,12 @@ app.post("/nango-webhook", async (c) => {
|
|
|
146
146
|
const body = await c.req.text();
|
|
147
147
|
const nangoSecret = env.NANGO_SLACK_SECRET_KEY || env.NANGO_SECRET_KEY;
|
|
148
148
|
if (!nangoSecret) {
|
|
149
|
-
logger.error(
|
|
149
|
+
logger.error("No Nango secret key configured — rejecting webhook");
|
|
150
150
|
return c.json({ error: "Server configuration error" }, 503);
|
|
151
151
|
}
|
|
152
152
|
const signature = c.req.header("x-nango-signature");
|
|
153
153
|
if (!signature) {
|
|
154
|
-
logger.warn(
|
|
154
|
+
logger.warn("Missing Nango webhook signature");
|
|
155
155
|
return c.json({ error: "Missing signature" }, 401);
|
|
156
156
|
}
|
|
157
157
|
const crypto = await import("node:crypto");
|
|
@@ -44,12 +44,12 @@ function parseOAuthState(stateStr) {
|
|
|
44
44
|
try {
|
|
45
45
|
const [data, signature] = stateStr.split(".");
|
|
46
46
|
if (!data || !signature) {
|
|
47
|
-
logger.warn(
|
|
47
|
+
logger.warn("OAuth state missing signature");
|
|
48
48
|
return null;
|
|
49
49
|
}
|
|
50
50
|
const expectedSignature = crypto$1.createHmac("sha256", getStateSigningSecret()).update(data).digest("base64url");
|
|
51
51
|
if (signature.length !== expectedSignature.length || !crypto$1.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
|
|
52
|
-
logger.warn(
|
|
52
|
+
logger.warn("Invalid OAuth state signature");
|
|
53
53
|
return null;
|
|
54
54
|
}
|
|
55
55
|
const decoded = Buffer.from(data, "base64url").toString("utf-8");
|
|
@@ -139,7 +139,7 @@ app.openapi(createProtectedRoute({
|
|
|
139
139
|
return c.redirect(`${dashboardUrl}?error=${encodeURIComponent(error)}`);
|
|
140
140
|
}
|
|
141
141
|
if (!code) {
|
|
142
|
-
logger.error(
|
|
142
|
+
logger.error("No code provided in OAuth callback");
|
|
143
143
|
return c.redirect(`${dashboardUrl}?error=no_code`);
|
|
144
144
|
}
|
|
145
145
|
try {
|
|
@@ -161,7 +161,7 @@ app.openapi(createProtectedRoute({
|
|
|
161
161
|
} catch (fetchErr) {
|
|
162
162
|
clearTimeout(timeout);
|
|
163
163
|
if (fetchErr.name === "AbortError") {
|
|
164
|
-
logger.error(
|
|
164
|
+
logger.error("Slack token exchange timed out");
|
|
165
165
|
return c.redirect(`${dashboardUrl}?error=timeout`);
|
|
166
166
|
}
|
|
167
167
|
throw fetchErr;
|
|
@@ -73,7 +73,7 @@ app.openapi(createProtectedRoute({
|
|
|
73
73
|
try {
|
|
74
74
|
const sessionTenantId = c.get("tenantId");
|
|
75
75
|
if (!sessionTenantId) {
|
|
76
|
-
logger.warn(
|
|
76
|
+
logger.warn("No tenantId in session context — cannot list workspaces");
|
|
77
77
|
return c.json({ workspaces: [] });
|
|
78
78
|
}
|
|
79
79
|
const workspaces = await listWorkspaceInstallations(sessionTenantId);
|
|
@@ -380,7 +380,7 @@ async function revokeSlackToken(token) {
|
|
|
380
380
|
try {
|
|
381
381
|
const result = await new WebClient(token).auth.revoke();
|
|
382
382
|
if (result.ok) {
|
|
383
|
-
logger.info(
|
|
383
|
+
logger.info("Successfully revoked Slack token");
|
|
384
384
|
return true;
|
|
385
385
|
}
|
|
386
386
|
logger.warn({ error: result.error }, "Token revocation returned non-ok status");
|
|
@@ -388,7 +388,7 @@ async function revokeSlackToken(token) {
|
|
|
388
388
|
} catch (error) {
|
|
389
389
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
390
390
|
if (errorMessage.includes("token_revoked") || errorMessage.includes("invalid_auth")) {
|
|
391
|
-
logger.info(
|
|
391
|
+
logger.info("Token already revoked or invalid");
|
|
392
392
|
return true;
|
|
393
393
|
}
|
|
394
394
|
logger.error({ error }, "Failed to revoke Slack token");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SlackLinkIntent } from "@inkeep/agents-core";
|
|
2
|
-
import * as
|
|
2
|
+
import * as slack_block_builder0 from "slack-block-builder";
|
|
3
3
|
|
|
4
4
|
//#region src/slack/services/link-prompt.d.ts
|
|
5
5
|
type LinkPromptResult = {
|
|
@@ -22,6 +22,6 @@ interface ResolveLinkActionParams {
|
|
|
22
22
|
intent?: SlackLinkIntent;
|
|
23
23
|
}
|
|
24
24
|
declare function resolveUnlinkedUserAction(params: ResolveLinkActionParams): Promise<LinkPromptResult>;
|
|
25
|
-
declare function buildLinkPromptMessage(result: LinkPromptResult): Readonly<
|
|
25
|
+
declare function buildLinkPromptMessage(result: LinkPromptResult): Readonly<slack_block_builder0.SlackMessageDto>;
|
|
26
26
|
//#endregion
|
|
27
27
|
export { LinkPromptResult, ResolveLinkActionParams, buildLinkPromptMessage, resolveUnlinkedUserAction };
|
|
@@ -57,7 +57,7 @@ function getSlackIntegrationId() {
|
|
|
57
57
|
}
|
|
58
58
|
async function createConnectSession(params) {
|
|
59
59
|
if (isSlackDevMode()) {
|
|
60
|
-
logger.debug(
|
|
60
|
+
logger.debug("Skipping Nango connect session in dev mode");
|
|
61
61
|
return null;
|
|
62
62
|
}
|
|
63
63
|
try {
|
|
@@ -340,7 +340,7 @@ async function storeWorkspaceInstallation(data) {
|
|
|
340
340
|
const integrationId = getSlackIntegrationId();
|
|
341
341
|
const secretKey = env.NANGO_SLACK_SECRET_KEY || env.NANGO_SECRET_KEY;
|
|
342
342
|
if (!secretKey) {
|
|
343
|
-
logger.error(
|
|
343
|
+
logger.error("No Nango secret key available");
|
|
344
344
|
return {
|
|
345
345
|
connectionId,
|
|
346
346
|
success: false
|
|
@@ -22,7 +22,7 @@ function verifySlackRequest(signingSecret, requestBody, timestamp, signature) {
|
|
|
22
22
|
try {
|
|
23
23
|
const fiveMinutesAgo = Math.floor(Date.now() / 1e3) - 300;
|
|
24
24
|
if (Number.parseInt(timestamp, 10) < fiveMinutesAgo) {
|
|
25
|
-
logger.warn(
|
|
25
|
+
logger.warn("Slack request timestamp too old");
|
|
26
26
|
return false;
|
|
27
27
|
}
|
|
28
28
|
const sigBaseString = `v0:${timestamp}:${requestBody}`;
|
|
@@ -11,7 +11,7 @@ const logger = getLogger("slack-socket-mode");
|
|
|
11
11
|
const GLOBAL_KEY = "__inkeep_slack_socket_mode_client__";
|
|
12
12
|
async function startSocketMode(appToken) {
|
|
13
13
|
if (globalThis[GLOBAL_KEY]) {
|
|
14
|
-
logger.info(
|
|
14
|
+
logger.info("Socket Mode client already running (HMR reload detected), skipping");
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
const { SocketModeClient } = await import("@slack/socket-mode");
|
|
@@ -19,7 +19,7 @@ async function startSocketMode(appToken) {
|
|
|
19
19
|
setupSocketModeListeners(client);
|
|
20
20
|
await client.start();
|
|
21
21
|
globalThis[GLOBAL_KEY] = client;
|
|
22
|
-
logger.info(
|
|
22
|
+
logger.info("Slack Socket Mode client started");
|
|
23
23
|
}
|
|
24
24
|
function registerBackgroundWork(work) {
|
|
25
25
|
work.catch((err) => {
|
|
@@ -31,10 +31,10 @@ function setupSocketModeListeners(client) {
|
|
|
31
31
|
logger.error({ error: args[0] }, "Socket Mode client error");
|
|
32
32
|
});
|
|
33
33
|
client.on("disconnected", () => {
|
|
34
|
-
logger.warn(
|
|
34
|
+
logger.warn("Socket Mode client disconnected");
|
|
35
35
|
});
|
|
36
36
|
client.on("reconnecting", () => {
|
|
37
|
-
logger.info(
|
|
37
|
+
logger.info("Socket Mode client reconnecting...");
|
|
38
38
|
});
|
|
39
39
|
client.on("slack_event", async (...args) => {
|
|
40
40
|
const { ack, body, type } = args[0];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/agents-work-apps",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.66.1",
|
|
4
4
|
"description": "First party integrations for Inkeep Agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"minimatch": "^10.2.1",
|
|
36
36
|
"oxfmt": "^0.42.0",
|
|
37
37
|
"slack-block-builder": "^2.8.0",
|
|
38
|
-
"@inkeep/agents-core": "0.
|
|
38
|
+
"@inkeep/agents-core": "0.66.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@hono/zod-openapi": "^1.1.5",
|