@inkeep/agents-work-apps 0.0.0-dev-20260224184340 → 0.0.0-dev-20260224190149

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.
@@ -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 hono_types0 from "hono/types";
7
+ import * as hono_types2 from "hono/types";
8
8
 
9
9
  //#region src/github/index.d.ts
10
- declare function createGithubRoutes(): Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
11
- declare const githubRoutes: Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
10
+ declare function createGithubRoutes(): Hono<hono_types2.BlankEnv, hono_types2.BlankSchema, "/">;
11
+ declare const githubRoutes: Hono<hono_types2.BlankEnv, hono_types2.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 hono_types9 from "hono/types";
2
+ import * as hono_types1 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
- }, hono_types9.BlankSchema, "/">;
9
+ }, hono_types1.BlankSchema, "/">;
10
10
  //#endregion
11
11
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types5 from "hono/types";
2
+ import * as hono_types0 from "hono/types";
3
3
 
4
4
  //#region src/github/routes/setup.d.ts
5
- declare const app: Hono<hono_types5.BlankEnv, hono_types5.BlankSchema, "/">;
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 hono_types7 from "hono/types";
2
+ import * as hono_types8 from "hono/types";
3
3
 
4
4
  //#region src/github/routes/tokenExchange.d.ts
5
- declare const app: Hono<hono_types7.BlankEnv, hono_types7.BlankSchema, "/">;
5
+ declare const app: Hono<hono_types8.BlankEnv, hono_types8.BlankSchema, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,5 +1,5 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types3 from "hono/types";
2
+ import * as hono_types6 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<hono_types3.BlankEnv, hono_types3.BlankSchema, "/">;
10
+ declare const app: Hono<hono_types6.BlankEnv, hono_types6.BlankSchema, "/">;
11
11
  //#endregion
12
12
  export { WebhookVerificationResult, app as default, verifyWebhookSignature };
@@ -8,6 +8,7 @@
8
8
  /** Configuration for a resolved agent */
9
9
  interface ResolvedAgentConfig {
10
10
  projectId: string;
11
+ projectName?: string;
11
12
  agentId: string;
12
13
  agentName?: string;
13
14
  source: 'channel' | 'workspace' | 'none';
@@ -1,7 +1,7 @@
1
1
  import { getLogger } from "../../logger.js";
2
2
  import runDbClient_default from "../../db/runDbClient.js";
3
3
  import { getWorkspaceDefaultAgentFromNango } from "./nango.js";
4
- import { fetchAgentsForProject } from "./events/utils.js";
4
+ import { fetchAgentsForProject, fetchProjectsForTenant } from "./events/utils.js";
5
5
  import { findWorkAppSlackChannelAgentConfig } from "@inkeep/agents-core";
6
6
 
7
7
  //#region src/slack/services/agent-resolution.ts
@@ -41,6 +41,35 @@ async function lookupAgentName(tenantId, projectId, agentId) {
41
41
  }
42
42
  return agents.find((a) => a.id === agentId)?.name || void 0;
43
43
  }
44
+ const PROJECT_NAME_CACHE_TTL_MS = 300 * 1e3;
45
+ const PROJECT_NAME_CACHE_MAX_SIZE = 200;
46
+ const projectNameCache = /* @__PURE__ */ new Map();
47
+ async function lookupProjectName(tenantId, projectId) {
48
+ const cacheKey = `${tenantId}:${projectId}`;
49
+ const cached = projectNameCache.get(cacheKey);
50
+ if (cached && cached.expiresAt > Date.now()) return cached.name || void 0;
51
+ const projects = await fetchProjectsForTenant(tenantId);
52
+ for (const project of projects) {
53
+ const key = `${tenantId}:${project.id}`;
54
+ projectNameCache.set(key, {
55
+ name: project.name || null,
56
+ expiresAt: Date.now() + PROJECT_NAME_CACHE_TTL_MS
57
+ });
58
+ }
59
+ if (projectNameCache.size > PROJECT_NAME_CACHE_MAX_SIZE) {
60
+ const now = Date.now();
61
+ for (const [key, entry] of projectNameCache) if (entry.expiresAt <= now) projectNameCache.delete(key);
62
+ if (projectNameCache.size > PROJECT_NAME_CACHE_MAX_SIZE) {
63
+ const excess = projectNameCache.size - PROJECT_NAME_CACHE_MAX_SIZE;
64
+ const keys = projectNameCache.keys();
65
+ for (let i = 0; i < excess; i++) {
66
+ const { value } = keys.next();
67
+ if (value) projectNameCache.delete(value);
68
+ }
69
+ }
70
+ }
71
+ return projects.find((p) => p.id === projectId)?.name || void 0;
72
+ }
44
73
  /**
45
74
  * Resolve the effective agent configuration.
46
75
  * Priority: Channel default > Workspace default
@@ -83,6 +112,7 @@ async function resolveEffectiveAgent(params) {
83
112
  }, "Resolved agent from workspace config");
84
113
  result = {
85
114
  projectId: workspaceConfig.projectId,
115
+ projectName: workspaceConfig.projectName,
86
116
  agentId: workspaceConfig.agentId,
87
117
  agentName: workspaceConfig.agentName,
88
118
  source: "workspace",
@@ -100,6 +130,10 @@ async function resolveEffectiveAgent(params) {
100
130
  }, "Enriched agent config with name from manage API");
101
131
  }
102
132
  }
133
+ if (result && !result.projectName) {
134
+ const projectName = await lookupProjectName(tenantId, result.projectId);
135
+ if (projectName) result.projectName = projectName;
136
+ }
103
137
  if (!result) logger.debug({
104
138
  tenantId,
105
139
  teamId,
@@ -130,6 +164,7 @@ async function getAgentConfigSources(params) {
130
164
  const wsConfig = await getWorkspaceDefaultAgentFromNango(teamId);
131
165
  if (wsConfig?.agentId && wsConfig.projectId) workspaceConfig = {
132
166
  projectId: wsConfig.projectId,
167
+ projectName: wsConfig.projectName,
133
168
  agentId: wsConfig.agentId,
134
169
  agentName: wsConfig.agentName,
135
170
  source: "workspace",
@@ -140,6 +175,10 @@ async function getAgentConfigSources(params) {
140
175
  const name = await lookupAgentName(tenantId, effective.projectId, effective.agentId);
141
176
  if (name) effective.agentName = name;
142
177
  }
178
+ if (effective && !effective.projectName) {
179
+ const projectName = await lookupProjectName(tenantId, effective.projectId);
180
+ if (projectName) effective.projectName = projectName;
181
+ }
143
182
  return {
144
183
  channelConfig,
145
184
  workspaceConfig,
@@ -53,14 +53,20 @@ interface AgentConfigSources {
53
53
  channelConfig: {
54
54
  agentName?: string;
55
55
  agentId: string;
56
+ projectId: string;
57
+ projectName?: string;
56
58
  } | null;
57
59
  workspaceConfig: {
58
60
  agentName?: string;
59
61
  agentId: string;
62
+ projectId: string;
63
+ projectName?: string;
60
64
  } | null;
61
65
  effective: {
62
66
  agentName?: string;
63
67
  agentId: string;
68
+ projectId: string;
69
+ projectName?: string;
64
70
  source: string;
65
71
  } | null;
66
72
  }
@@ -67,10 +67,29 @@ function createNotLinkedMessage() {
67
67
  }
68
68
  function createStatusMessage(email, linkedAt, dashboardUrl, agentConfigs) {
69
69
  const { effective } = agentConfigs;
70
+ const baseUrl = dashboardUrl.replace(/\/work-apps\/slack$/, "");
70
71
  let agentLine;
71
- if (effective) agentLine = `${Md.bold("Agent:")} ${effective.agentName || effective.agentId}`;
72
- else agentLine = `${Md.bold("Agent:")} None configured\n${Md.italic("Ask your admin to set up an agent in the dashboard.")}`;
73
- 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();
72
+ let projectLine;
73
+ if (effective) {
74
+ const agentDisplayName = effective.agentName || effective.agentId;
75
+ const agentUrl = `${baseUrl}/projects/${effective.projectId}/agents/${effective.agentId}`;
76
+ agentLine = `${Md.bold("Agent:")} <${agentUrl}|${agentDisplayName}>`;
77
+ const projectDisplayName = effective.projectName || effective.projectId;
78
+ const projectUrl = `${baseUrl}/projects/${effective.projectId}/agents`;
79
+ projectLine = `${Md.bold("Project:")} <${projectUrl}|${projectDisplayName}>`;
80
+ } else {
81
+ agentLine = `${Md.bold("Agent:")} None configured\n${Md.italic("Ask your admin to set up an agent in the dashboard.")}`;
82
+ projectLine = "";
83
+ }
84
+ const lines = [
85
+ Md.bold("Connected to Inkeep"),
86
+ "",
87
+ `${Md.bold("Account:")} ${email}`,
88
+ `${Md.bold("Linked:")} ${new Date(linkedAt).toLocaleDateString()}`,
89
+ agentLine
90
+ ];
91
+ if (projectLine) lines.push(projectLine);
92
+ return Message().blocks(Blocks.Section().text(lines.join("\n")), Blocks.Actions().elements(Elements.Button().text(SlackStrings.buttons.openDashboard).url(dashboardUrl).actionId("open_dashboard"))).buildToObject();
74
93
  }
75
94
  const ToolApprovalButtonValueSchema = z.object({
76
95
  toolCallId: z.string(),
@@ -8,10 +8,10 @@ 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
- slackUserId: string;
12
11
  id: string;
13
12
  createdAt: string;
14
13
  updatedAt: string;
14
+ slackUserId: string;
15
15
  tenantId: string;
16
16
  clientId: string;
17
17
  slackTeamId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-work-apps",
3
- "version": "0.0.0-dev-20260224184340",
3
+ "version": "0.0.0-dev-20260224190149",
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-20260224184340"
36
+ "@inkeep/agents-core": "0.0.0-dev-20260224190149"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@hono/zod-openapi": "^1.1.5",