@inkeep/agents-core 0.0.0-dev-20260120222159 → 0.0.0-dev-20260121022749

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.
Files changed (64) hide show
  1. package/dist/auth/auth.d.ts +53 -53
  2. package/dist/auth/auth.js +1 -1
  3. package/dist/auth/permissions.d.ts +13 -13
  4. package/dist/context/ContextConfig.js +3 -3
  5. package/dist/data-access/index.d.ts +5 -5
  6. package/dist/data-access/index.js +5 -5
  7. package/dist/data-access/manage/agents.d.ts +37 -37
  8. package/dist/data-access/manage/artifactComponents.d.ts +12 -12
  9. package/dist/data-access/manage/contextConfigs.d.ts +12 -12
  10. package/dist/data-access/manage/dataComponents.d.ts +6 -6
  11. package/dist/data-access/manage/evalConfig.d.ts +12 -2
  12. package/dist/data-access/manage/evalConfig.js +25 -1
  13. package/dist/data-access/manage/functionTools.d.ts +14 -14
  14. package/dist/data-access/manage/projectFull.d.ts +0 -4
  15. package/dist/data-access/manage/projectFull.js +8 -21
  16. package/dist/data-access/manage/subAgentExternalAgentRelations.d.ts +24 -24
  17. package/dist/data-access/manage/subAgentRelations.d.ts +36 -36
  18. package/dist/data-access/manage/subAgentTeamAgentRelations.d.ts +18 -18
  19. package/dist/data-access/manage/subAgents.d.ts +27 -27
  20. package/dist/data-access/manage/tools.d.ts +41 -34
  21. package/dist/data-access/manage/tools.js +9 -1
  22. package/dist/data-access/manage/triggers.d.ts +0 -4
  23. package/dist/data-access/manage/triggers.js +1 -15
  24. package/dist/data-access/runtime/apiKeys.d.ts +20 -20
  25. package/dist/data-access/runtime/conversations.d.ts +31 -31
  26. package/dist/data-access/runtime/messages.d.ts +18 -18
  27. package/dist/data-access/runtime/organizations.d.ts +10 -1
  28. package/dist/data-access/runtime/organizations.js +13 -1
  29. package/dist/data-access/runtime/tasks.d.ts +7 -7
  30. package/dist/db/manage/manage-client.d.ts +3 -1
  31. package/dist/db/manage/manage-client.js +13 -1
  32. package/dist/db/manage/manage-schema.d.ts +375 -375
  33. package/dist/db/migrations/cleanup-old-trigger-auth.d.ts +1 -0
  34. package/dist/db/migrations/cleanup-old-trigger-auth.js +68 -0
  35. package/dist/db/runtime/runtime-schema.d.ts +181 -181
  36. package/dist/dolt/branch.d.ts +4 -53
  37. package/dist/dolt/branch.js +23 -81
  38. package/dist/dolt/branches-api.js +1 -1
  39. package/dist/dolt/index.d.ts +5 -3
  40. package/dist/dolt/index.js +5 -3
  41. package/dist/dolt/migrate-all-branches.js +1 -1
  42. package/dist/dolt/{ref.d.ts → ref-helpers.d.ts} +5 -2
  43. package/dist/dolt/{ref.js → ref-helpers.js} +15 -3
  44. package/dist/dolt/ref-middleware.d.ts +82 -0
  45. package/dist/dolt/ref-middleware.js +217 -0
  46. package/dist/dolt/ref-scope.d.ts +101 -0
  47. package/dist/dolt/ref-scope.js +231 -0
  48. package/dist/env.d.ts +2 -2
  49. package/dist/env.js +1 -1
  50. package/dist/index.d.ts +12 -10
  51. package/dist/index.js +15 -13
  52. package/dist/types/entities.d.ts +3 -2
  53. package/dist/types/index.d.ts +2 -2
  54. package/dist/utils/index.d.ts +2 -2
  55. package/dist/utils/index.js +2 -2
  56. package/dist/utils/third-party-mcp-servers/composio-client.js +23 -23
  57. package/dist/utils/trigger-auth.d.ts +37 -7
  58. package/dist/utils/trigger-auth.js +72 -77
  59. package/dist/validation/dolt-schemas.d.ts +1 -1
  60. package/dist/validation/index.d.ts +2 -2
  61. package/dist/validation/index.js +2 -2
  62. package/dist/validation/schemas.d.ts +473 -486
  63. package/dist/validation/schemas.js +23 -28
  64. package/package.json +2 -1
@@ -54,58 +54,9 @@ declare const doltCheckout: (db: AgentsManageDatabaseClient) => (params: {
54
54
  declare const doltActiveBranch: (db: AgentsManageDatabaseClient) => () => Promise<string>;
55
55
  declare const doltGetBranchNamespace: (scopes: branchScopes) => () => string;
56
56
  /**
57
- * Execute a callback function with the database connection on a specific branch.
58
- * After the callback completes (success or error), the connection is returned to the original branch.
59
- *
60
- * @param db - The database client
61
- * @param branchName - The branch to checkout before executing the callback
62
- * @param callback - The async function to execute while on the specified branch
63
- * @returns The result of the callback function
64
- *
65
- * @example
66
- * ```ts
67
- * const result = await withBranch(db)({
68
- * branchName: 'default_andrew1_main',
69
- * callback: async () => {
70
- * return await getFullProjectWithRelationIds(db)({ scopes });
71
- * },
72
- * });
73
- * ```
57
+ * Create a branch if it doesn't exist, handling race conditions gracefully.
58
+ * If multiple concurrent requests try to create the same branch, only one will succeed.
74
59
  */
75
- /**
76
- * Execute a callback function with the database connection on a specific branch.
77
- *
78
- * IMPORTANT: This function uses a transaction to ensure all queries within the callback
79
- * run on the same database connection. This is critical because DoltGres branching is
80
- * connection-scoped - a DOLT_CHECKOUT only affects the specific connection that runs it.
81
- * Without a transaction, subsequent queries might use different connections from the pool
82
- * that are still on the original branch.
83
- *
84
- * After the callback completes (success or error), the connection is returned to the original branch.
85
- *
86
- * @param db - The database client
87
- * @param branchName - The branch to checkout before executing the callback
88
- * @param callback - The async function to execute while on the specified branch
89
- * @returns The result of the callback function
90
- *
91
- * @example
92
- * ```ts
93
- * const result = await withBranch(db)({
94
- * branchName: 'default_andrew1_main',
95
- * callback: async (txDb) => {
96
- * return await getFullProjectWithRelationIds(txDb)({ scopes });
97
- * },
98
- * });
99
- * ```
100
- */
101
- declare const withBranch: (db: AgentsManageDatabaseClient) => <T>(params: {
102
- branchName: string;
103
- callback: (txDb: AgentsManageDatabaseClient) => Promise<T>;
104
- }) => Promise<T>;
105
- /**
106
- * Generate the standard project branch name from tenant and project IDs.
107
- * Format: {tenantId}_{projectId}_main
108
- */
109
- declare const getProjectBranchName: (tenantId: string, projectId: string) => string;
60
+ declare const ensureBranchExists: (db: AgentsManageDatabaseClient, branchName: string) => Promise<void>;
110
61
  //#endregion
111
- export { branchScopes, doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, getProjectBranchName, withBranch };
62
+ export { branchScopes, doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, ensureBranchExists };
@@ -1,25 +1,9 @@
1
1
  import { doltHashOf } from "./commit.js";
2
+ import { resolveRef } from "./ref-helpers.js";
2
3
  import { sql } from "drizzle-orm";
4
+ import { logger } from "@composio/core";
3
5
 
4
6
  //#region src/dolt/branch.ts
5
- const isDoltCache = /* @__PURE__ */ new WeakMap();
6
- const isTestEnvironment = process.env.NODE_ENV === "test" || process.env.VITEST === "true";
7
- /**
8
- * Check if the database supports Dolt operations (cached per db instance)
9
- */
10
- async function checkIsDolt(db) {
11
- if (isTestEnvironment) return false;
12
- const cached = isDoltCache.get(db);
13
- if (cached !== void 0) return cached;
14
- let isDolt = true;
15
- try {
16
- await db.execute(sql`SELECT ACTIVE_BRANCH() as branch`);
17
- } catch {
18
- isDolt = false;
19
- }
20
- isDoltCache.set(db, isDolt);
21
- return isDolt;
22
- }
23
7
  /**
24
8
  * Create a new branch
25
9
  */
@@ -70,71 +54,29 @@ const doltGetBranchNamespace = (scopes) => () => {
70
54
  return `${scopes.tenantId}_${scopes.projectId}_${scopes.branchName}`;
71
55
  };
72
56
  /**
73
- * Execute a callback function with the database connection on a specific branch.
74
- * After the callback completes (success or error), the connection is returned to the original branch.
75
- *
76
- * @param db - The database client
77
- * @param branchName - The branch to checkout before executing the callback
78
- * @param callback - The async function to execute while on the specified branch
79
- * @returns The result of the callback function
80
- *
81
- * @example
82
- * ```ts
83
- * const result = await withBranch(db)({
84
- * branchName: 'default_andrew1_main',
85
- * callback: async () => {
86
- * return await getFullProjectWithRelationIds(db)({ scopes });
87
- * },
88
- * });
89
- * ```
90
- */
91
- /**
92
- * Execute a callback function with the database connection on a specific branch.
93
- *
94
- * IMPORTANT: This function uses a transaction to ensure all queries within the callback
95
- * run on the same database connection. This is critical because DoltGres branching is
96
- * connection-scoped - a DOLT_CHECKOUT only affects the specific connection that runs it.
97
- * Without a transaction, subsequent queries might use different connections from the pool
98
- * that are still on the original branch.
99
- *
100
- * After the callback completes (success or error), the connection is returned to the original branch.
101
- *
102
- * @param db - The database client
103
- * @param branchName - The branch to checkout before executing the callback
104
- * @param callback - The async function to execute while on the specified branch
105
- * @returns The result of the callback function
106
- *
107
- * @example
108
- * ```ts
109
- * const result = await withBranch(db)({
110
- * branchName: 'default_andrew1_main',
111
- * callback: async (txDb) => {
112
- * return await getFullProjectWithRelationIds(txDb)({ scopes });
113
- * },
114
- * });
115
- * ```
57
+ * Create a branch if it doesn't exist, handling race conditions gracefully.
58
+ * If multiple concurrent requests try to create the same branch, only one will succeed.
116
59
  */
117
- const withBranch = (db) => async (params) => {
118
- const { branchName, callback } = params;
119
- if (!await checkIsDolt(db)) return callback(db);
120
- return db.transaction(async (tx) => {
121
- const originalBranch = (await tx.execute(sql`SELECT ACTIVE_BRANCH() as branch`)).rows[0]?.branch;
122
- if (originalBranch === branchName) return callback(tx);
123
- try {
124
- await tx.execute(sql.raw(`SELECT DOLT_CHECKOUT('${branchName}')`));
125
- return await callback(tx);
126
- } finally {
127
- if (originalBranch !== branchName) await tx.execute(sql.raw(`SELECT DOLT_CHECKOUT('${originalBranch}')`));
60
+ const ensureBranchExists = async (db, branchName) => {
61
+ if (await resolveRef(db)(branchName)) {
62
+ logger.debug({ branchName }, "Branch already exists, skipping creation");
63
+ return;
64
+ }
65
+ try {
66
+ await doltBranch(db)({ name: branchName });
67
+ logger.debug({ branchName }, "Branch created successfully");
68
+ } catch (error) {
69
+ if (await resolveRef(db)(branchName)) {
70
+ logger.debug({ branchName }, "Branch creation failed but branch exists (concurrent creation), continuing");
71
+ return;
128
72
  }
129
- });
130
- };
131
- /**
132
- * Generate the standard project branch name from tenant and project IDs.
133
- * Format: {tenantId}_{projectId}_main
134
- */
135
- const getProjectBranchName = (tenantId, projectId) => {
136
- return `${tenantId}_${projectId}_main`;
73
+ logger.error({
74
+ branchName,
75
+ error
76
+ }, "Branch creation failed and branch does not exist");
77
+ throw error;
78
+ }
137
79
  };
138
80
 
139
81
  //#endregion
140
- export { doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, getProjectBranchName, withBranch };
82
+ export { doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, ensureBranchExists };
@@ -1,5 +1,5 @@
1
- import { doltBranch, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches } from "./branch.js";
2
1
  import { SCHEMA_SOURCE_BRANCH, ensureSchemaSync, getSchemaDiff, syncSchemaFromMain } from "./schema-sync.js";
2
+ import { doltBranch, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches } from "./branch.js";
3
3
  import { sql } from "drizzle-orm";
4
4
 
5
5
  //#region src/dolt/branches-api.ts
@@ -1,8 +1,10 @@
1
- import { branchScopes, doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, getProjectBranchName, withBranch } from "./branch.js";
1
+ import { branchScopes, doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, ensureBranchExists } from "./branch.js";
2
2
  import { CheckoutBranchParams, CheckoutBranchResult, CreateBranchParams, DeleteBranchParams, GetBranchParams, MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTenantMainBranch, isProtectedBranchName, listBranches, listBranchesForAgent } from "./branches-api.js";
3
3
  import { doltAdd, doltAddAndCommit, doltCommit, doltDeleteTag, doltHashOf, doltListTags, doltLog, doltReset, doltStatus, doltTag } from "./commit.js";
4
4
  import { doltDiff, doltDiffSummary } from "./diff.js";
5
5
  import { doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts } from "./merge.js";
6
- import { RefType, checkoutRef, getCurrentBranchOrCommit, isRefWritable, isValidCommitHash, resolveRef } from "./ref.js";
6
+ import { RefType, checkoutRef, getCurrentBranchOrCommit, getProjectMainResolvedRef, getProjectScopedRef, getTenantScopedRef, isRefWritable, isValidCommitHash, resolveRef } from "./ref-helpers.js";
7
+ import { RefContext, RefMiddlewareOptions, createRefMiddleware, createWriteProtectionMiddleware, refMiddlewareFactory, writeProtectionMiddlewareFactory } from "./ref-middleware.js";
8
+ import { NestedRefScopeError, WithRefOptions, getCurrentRefScope, getRefScopedDb, isInRefScope, withRef } from "./ref-scope.js";
7
9
  import { EnsureSchemaSyncOptions, SCHEMA_SOURCE_BRANCH, SchemaDiff, SchemaSyncOptions, SchemaSyncResult, areBranchesSchemaCompatible, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getSchemaDiff, hasSchemaDifferences, hasUncommittedChanges, syncSchemaFromMain } from "./schema-sync.js";
8
- export { CheckoutBranchParams, CheckoutBranchResult, CreateBranchParams, DeleteBranchParams, EnsureSchemaSyncOptions, GetBranchParams, MAIN_BRANCH_SUFFIX, RefType, SCHEMA_SOURCE_BRANCH, SchemaDiff, SchemaSyncOptions, SchemaSyncResult, areBranchesSchemaCompatible, branchScopes, checkoutBranch, checkoutRef, createBranch, deleteBranch, doltAbortMerge, doltActiveBranch, doltAdd, doltAddAndCommit, doltBranch, doltBranchExists, doltCheckout, doltCommit, doltConflicts, doltDeleteBranch, doltDeleteTag, doltDiff, doltDiffSummary, doltGetBranchNamespace, doltHashOf, doltListBranches, doltListTags, doltLog, doltMerge, doltMergeStatus, doltRenameBranch, doltReset, doltResolveConflicts, doltSchemaConflicts, doltStatus, doltTableConflicts, doltTag, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getBranch, getCurrentBranchOrCommit, getProjectBranchName, getSchemaDiff, getTenantMainBranch, hasSchemaDifferences, hasUncommittedChanges, isProtectedBranchName, isRefWritable, isValidCommitHash, listBranches, listBranchesForAgent, resolveRef, syncSchemaFromMain, withBranch };
10
+ export { CheckoutBranchParams, CheckoutBranchResult, CreateBranchParams, DeleteBranchParams, EnsureSchemaSyncOptions, GetBranchParams, MAIN_BRANCH_SUFFIX, NestedRefScopeError, RefContext, RefMiddlewareOptions, RefType, SCHEMA_SOURCE_BRANCH, SchemaDiff, SchemaSyncOptions, SchemaSyncResult, WithRefOptions, areBranchesSchemaCompatible, branchScopes, checkoutBranch, checkoutRef, createBranch, createRefMiddleware, createWriteProtectionMiddleware, deleteBranch, doltAbortMerge, doltActiveBranch, doltAdd, doltAddAndCommit, doltBranch, doltBranchExists, doltCheckout, doltCommit, doltConflicts, doltDeleteBranch, doltDeleteTag, doltDiff, doltDiffSummary, doltGetBranchNamespace, doltHashOf, doltListBranches, doltListTags, doltLog, doltMerge, doltMergeStatus, doltRenameBranch, doltReset, doltResolveConflicts, doltSchemaConflicts, doltStatus, doltTableConflicts, doltTag, ensureBranchExists, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getBranch, getCurrentBranchOrCommit, getCurrentRefScope, getProjectMainResolvedRef, getProjectScopedRef, getRefScopedDb, getSchemaDiff, getTenantMainBranch, getTenantScopedRef, hasSchemaDifferences, hasUncommittedChanges, isInRefScope, isProtectedBranchName, isRefWritable, isValidCommitHash, listBranches, listBranchesForAgent, refMiddlewareFactory, resolveRef, syncSchemaFromMain, withRef, writeProtectionMiddlewareFactory };
@@ -1,9 +1,11 @@
1
1
  import { doltAdd, doltAddAndCommit, doltCommit, doltDeleteTag, doltHashOf, doltListTags, doltLog, doltReset, doltStatus, doltTag } from "./commit.js";
2
- import { doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, getProjectBranchName, withBranch } from "./branch.js";
3
2
  import { doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts } from "./merge.js";
4
3
  import { SCHEMA_SOURCE_BRANCH, areBranchesSchemaCompatible, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getSchemaDiff, hasSchemaDifferences, hasUncommittedChanges, syncSchemaFromMain } from "./schema-sync.js";
5
4
  import { MAIN_BRANCH_SUFFIX, checkoutBranch, createBranch, deleteBranch, getBranch, getTenantMainBranch, isProtectedBranchName, listBranches, listBranchesForAgent } from "./branches-api.js";
5
+ import { checkoutRef, getCurrentBranchOrCommit, getProjectMainResolvedRef, getProjectScopedRef, getTenantScopedRef, isRefWritable, isValidCommitHash, resolveRef } from "./ref-helpers.js";
6
+ import { doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, ensureBranchExists } from "./branch.js";
6
7
  import { doltDiff, doltDiffSummary } from "./diff.js";
7
- import { checkoutRef, getCurrentBranchOrCommit, isRefWritable, isValidCommitHash, resolveRef } from "./ref.js";
8
+ import { createRefMiddleware, createWriteProtectionMiddleware, refMiddlewareFactory, writeProtectionMiddlewareFactory } from "./ref-middleware.js";
9
+ import { NestedRefScopeError, getCurrentRefScope, getRefScopedDb, isInRefScope, withRef } from "./ref-scope.js";
8
10
 
9
- export { MAIN_BRANCH_SUFFIX, SCHEMA_SOURCE_BRANCH, areBranchesSchemaCompatible, checkoutBranch, checkoutRef, createBranch, deleteBranch, doltAbortMerge, doltActiveBranch, doltAdd, doltAddAndCommit, doltBranch, doltBranchExists, doltCheckout, doltCommit, doltConflicts, doltDeleteBranch, doltDeleteTag, doltDiff, doltDiffSummary, doltGetBranchNamespace, doltHashOf, doltListBranches, doltListTags, doltLog, doltMerge, doltMergeStatus, doltRenameBranch, doltReset, doltResolveConflicts, doltSchemaConflicts, doltStatus, doltTableConflicts, doltTag, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getBranch, getCurrentBranchOrCommit, getProjectBranchName, getSchemaDiff, getTenantMainBranch, hasSchemaDifferences, hasUncommittedChanges, isProtectedBranchName, isRefWritable, isValidCommitHash, listBranches, listBranchesForAgent, resolveRef, syncSchemaFromMain, withBranch };
11
+ export { MAIN_BRANCH_SUFFIX, NestedRefScopeError, SCHEMA_SOURCE_BRANCH, areBranchesSchemaCompatible, checkoutBranch, checkoutRef, createBranch, createRefMiddleware, createWriteProtectionMiddleware, deleteBranch, doltAbortMerge, doltActiveBranch, doltAdd, doltAddAndCommit, doltBranch, doltBranchExists, doltCheckout, doltCommit, doltConflicts, doltDeleteBranch, doltDeleteTag, doltDiff, doltDiffSummary, doltGetBranchNamespace, doltHashOf, doltListBranches, doltListTags, doltLog, doltMerge, doltMergeStatus, doltRenameBranch, doltReset, doltResolveConflicts, doltSchemaConflicts, doltStatus, doltTableConflicts, doltTag, ensureBranchExists, ensureSchemaSync, formatSchemaDiffSummary, getActiveBranch, getBranch, getCurrentBranchOrCommit, getCurrentRefScope, getProjectMainResolvedRef, getProjectScopedRef, getRefScopedDb, getSchemaDiff, getTenantMainBranch, getTenantScopedRef, hasSchemaDifferences, hasUncommittedChanges, isInRefScope, isProtectedBranchName, isRefWritable, isValidCommitHash, listBranches, listBranchesForAgent, refMiddlewareFactory, resolveRef, syncSchemaFromMain, withRef, writeProtectionMiddlewareFactory };
@@ -1,6 +1,6 @@
1
1
  import { createAgentsManageDatabaseClient } from "../db/manage/manage-client.js";
2
- import { doltCheckout, doltListBranches } from "./branch.js";
3
2
  import { syncSchemaFromMain } from "./schema-sync.js";
3
+ import { doltCheckout, doltListBranches } from "./branch.js";
4
4
 
5
5
  //#region src/dolt/migrate-all-branches.ts
6
6
  const ansi = {
@@ -1,9 +1,11 @@
1
1
  import { ResolvedRef } from "../validation/dolt-schemas.js";
2
2
  import { AgentsManageDatabaseClient } from "../db/manage/manage-client.js";
3
3
 
4
- //#region src/dolt/ref.d.ts
4
+ //#region src/dolt/ref-helpers.d.ts
5
5
  type RefType = 'commit' | 'tag' | 'branch';
6
6
  declare const isValidCommitHash: (ref: string) => boolean;
7
+ declare const getProjectScopedRef: (tenantId: string, projectId: string, ref: string) => string;
8
+ declare const getTenantScopedRef: (tenantId: string, ref: string) => string;
7
9
  declare const resolveRef: (db: AgentsManageDatabaseClient) => (ref: string) => Promise<ResolvedRef | null>;
8
10
  declare const isRefWritable: (resolvedRef: ResolvedRef) => boolean;
9
11
  declare const checkoutRef: (db: AgentsManageDatabaseClient) => (resolvedRef: ResolvedRef) => Promise<void>;
@@ -12,5 +14,6 @@ declare const getCurrentBranchOrCommit: (db: AgentsManageDatabaseClient) => () =
12
14
  hash: string;
13
15
  type: RefType;
14
16
  }>;
17
+ declare const getProjectMainResolvedRef: (db: AgentsManageDatabaseClient) => (tenantId: string, projectId: string) => Promise<ResolvedRef>;
15
18
  //#endregion
16
- export { RefType, checkoutRef, getCurrentBranchOrCommit, isRefWritable, isValidCommitHash, resolveRef };
19
+ export { RefType, checkoutRef, getCurrentBranchOrCommit, getProjectMainResolvedRef, getProjectScopedRef, getTenantScopedRef, isRefWritable, isValidCommitHash, resolveRef };
@@ -1,12 +1,18 @@
1
1
  import { doltHashOf, doltListTags } from "./commit.js";
2
- import { doltListBranches } from "./branch.js";
3
2
  import { checkoutBranch } from "./branches-api.js";
3
+ import { doltListBranches } from "./branch.js";
4
4
  import { sql } from "drizzle-orm";
5
5
 
6
- //#region src/dolt/ref.ts
6
+ //#region src/dolt/ref-helpers.ts
7
7
  const isValidCommitHash = (ref) => {
8
8
  return /^[0-9a-v]{32}$/.test(ref);
9
9
  };
10
+ const getProjectScopedRef = (tenantId, projectId, ref) => {
11
+ return `${tenantId}_${projectId}_${ref}`;
12
+ };
13
+ const getTenantScopedRef = (tenantId, ref) => {
14
+ return `${tenantId}_${ref}`;
15
+ };
10
16
  const resolveRef = (db) => async (ref) => {
11
17
  if (isValidCommitHash(ref)) return {
12
18
  type: "commit",
@@ -48,6 +54,12 @@ const getCurrentBranchOrCommit = (db) => async () => {
48
54
  type: "commit"
49
55
  };
50
56
  };
57
+ const getProjectMainResolvedRef = (db) => async (tenantId, projectId) => {
58
+ const projectMain = `${tenantId}_${projectId}_main`;
59
+ const resolvedRef = await resolveRef(db)(projectMain);
60
+ if (!resolvedRef) throw new Error(`Project main branch not found: ${projectMain}`);
61
+ return resolvedRef;
62
+ };
51
63
 
52
64
  //#endregion
53
- export { checkoutRef, getCurrentBranchOrCommit, isRefWritable, isValidCommitHash, resolveRef };
65
+ export { checkoutRef, getCurrentBranchOrCommit, getProjectMainResolvedRef, getProjectScopedRef, getTenantScopedRef, isRefWritable, isValidCommitHash, resolveRef };
@@ -0,0 +1,82 @@
1
+ import { ResolvedRef } from "../validation/dolt-schemas.js";
2
+ import { AgentsManageDatabaseClient } from "../db/manage/manage-client.js";
3
+ import { Context, Next } from "hono";
4
+
5
+ //#region src/dolt/ref-middleware.d.ts
6
+ type RefContext = {
7
+ resolvedRef?: ResolvedRef;
8
+ };
9
+ interface RefMiddlewareOptions {
10
+ /**
11
+ * Extract tenantId from the request context.
12
+ * Default implementation extracts from path using /tenants/{tenantId} pattern.
13
+ */
14
+ extractTenantId?: (c: Context) => string | undefined;
15
+ /**
16
+ * Extract projectId from the request context.
17
+ * Default implementation extracts from path using /tenants/{tenantId}/projects/{projectId} pattern.
18
+ */
19
+ extractProjectId?: (c: Context) => string | undefined;
20
+ /**
21
+ * Whether to allow extracting projectId from request body for POST/PUT/PATCH.
22
+ * Default: true
23
+ */
24
+ allowProjectIdFromBody?: boolean;
25
+ /**
26
+ * Custom path patterns that should skip ref validation.
27
+ * Default: []
28
+ */
29
+ skipRefValidationPaths?: RegExp[];
30
+ }
31
+ /**
32
+ * Creates a ref resolution middleware factory.
33
+ *
34
+ * This middleware:
35
+ * 1. Extracts tenantId and projectId from the request
36
+ * 2. Resolves the `ref` query parameter to a ResolvedRef
37
+ * 3. Creates branches if needed (tenant_main, project_main)
38
+ * 4. Sets `resolvedRef` in the Hono context for downstream handlers
39
+ *
40
+ * @param db - The Doltgres database client to use for ref resolution
41
+ * @param options - Optional configuration for extraction and validation
42
+ * @returns Hono middleware function
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * import { createRefMiddleware } from '@inkeep/agents-core';
47
+ * import { manageDbClient } from './db';
48
+ *
49
+ * const refMiddleware = createRefMiddleware(manageDbClient);
50
+ * app.use('/tenants/*', refMiddleware);
51
+ * ```
52
+ */
53
+ declare const createRefMiddleware: (db: AgentsManageDatabaseClient, options?: RefMiddlewareOptions) => (c: Context, next: Next) => Promise<void>;
54
+ /**
55
+ * Creates a write protection middleware that prevents write operations on immutable refs.
56
+ *
57
+ * This middleware checks if the resolved ref is writable (branches are writable,
58
+ * tags and commits are not) and rejects write operations on immutable refs.
59
+ *
60
+ * @returns Hono middleware function
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * import { createRefMiddleware, createWriteProtectionMiddleware } from '@inkeep/agents-core';
65
+ *
66
+ * const refMiddleware = createRefMiddleware(db);
67
+ * const writeProtection = createWriteProtectionMiddleware();
68
+ *
69
+ * app.use('/tenants/*', refMiddleware, writeProtection);
70
+ * ```
71
+ */
72
+ declare const createWriteProtectionMiddleware: () => (c: Context, next: Next) => Promise<void>;
73
+ /**
74
+ * @deprecated Use createRefMiddleware instead. This is kept for backwards compatibility.
75
+ */
76
+ declare const refMiddlewareFactory: (db: AgentsManageDatabaseClient, options?: RefMiddlewareOptions) => (c: Context, next: Next) => Promise<void>;
77
+ /**
78
+ * @deprecated Use createWriteProtectionMiddleware instead. This is kept for backwards compatibility.
79
+ */
80
+ declare const writeProtectionMiddlewareFactory: () => (c: Context, next: Next) => Promise<void>;
81
+ //#endregion
82
+ export { RefContext, RefMiddlewareOptions, createRefMiddleware, createWriteProtectionMiddleware, refMiddlewareFactory, writeProtectionMiddlewareFactory };
@@ -0,0 +1,217 @@
1
+ import { getLogger } from "../utils/logger.js";
2
+ import { createApiError } from "../utils/error.js";
3
+ import { isRefWritable, resolveRef } from "./ref-helpers.js";
4
+ import { ensureBranchExists } from "./branch.js";
5
+
6
+ //#region src/dolt/ref-middleware.ts
7
+ const logger = getLogger("ref-middleware");
8
+ /**
9
+ * Default tenant ID extractor - extracts from /tenants/{tenantId} path pattern
10
+ */
11
+ const defaultExtractTenantId = (c) => {
12
+ return c.req.path.match(/^\/tenants\/([^/]+)/)?.[1];
13
+ };
14
+ /**
15
+ * Default project ID extractor - extracts from /tenants/{tenantId}/projects/{projectId} or
16
+ * /tenants/{tenantId}/project-full/{projectId} path patterns
17
+ */
18
+ const defaultExtractProjectId = (c) => {
19
+ return c.req.path.match(/^\/tenants\/[^/]+\/(?:projects|project-full)(?:\/([^/]+))?/)?.[1];
20
+ };
21
+ /**
22
+ * Creates a ref resolution middleware factory.
23
+ *
24
+ * This middleware:
25
+ * 1. Extracts tenantId and projectId from the request
26
+ * 2. Resolves the `ref` query parameter to a ResolvedRef
27
+ * 3. Creates branches if needed (tenant_main, project_main)
28
+ * 4. Sets `resolvedRef` in the Hono context for downstream handlers
29
+ *
30
+ * @param db - The Doltgres database client to use for ref resolution
31
+ * @param options - Optional configuration for extraction and validation
32
+ * @returns Hono middleware function
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * import { createRefMiddleware } from '@inkeep/agents-core';
37
+ * import { manageDbClient } from './db';
38
+ *
39
+ * const refMiddleware = createRefMiddleware(manageDbClient);
40
+ * app.use('/tenants/*', refMiddleware);
41
+ * ```
42
+ */
43
+ const createRefMiddleware = (db, options = {}) => {
44
+ const { extractTenantId = defaultExtractTenantId, extractProjectId = defaultExtractProjectId, allowProjectIdFromBody = true } = options;
45
+ return async (c, next) => {
46
+ const ref = c.req.query("ref");
47
+ const pathSplit = c.req.path.split("/");
48
+ const tenantId = extractTenantId(c);
49
+ let projectId = extractProjectId(c);
50
+ if (!projectId && allowProjectIdFromBody && [
51
+ "POST",
52
+ "PUT",
53
+ "PATCH"
54
+ ].includes(c.req.method)) try {
55
+ const body = await c.req.json();
56
+ if (body && typeof body.projectId === "string") {
57
+ projectId = body.projectId;
58
+ logger.debug({ projectId }, "Extracted projectId from request body");
59
+ }
60
+ } catch {
61
+ logger.debug({}, "Could not extract projectId from body");
62
+ }
63
+ if (!tenantId) throw createApiError({
64
+ code: "bad_request",
65
+ message: "Missing tenantId"
66
+ });
67
+ if (process.env.ENVIRONMENT === "test") {
68
+ const defaultRef = {
69
+ type: "branch",
70
+ name: projectId ? `${tenantId}_${projectId}_main` : `${tenantId}_main`,
71
+ hash: "test-hash"
72
+ };
73
+ c.set("resolvedRef", defaultRef);
74
+ await next();
75
+ return;
76
+ }
77
+ if (pathSplit.length < 4 && ref !== "main" && ref !== void 0) throw createApiError({
78
+ code: "bad_request",
79
+ message: "Ref is not supported for this path"
80
+ });
81
+ let resolvedRef;
82
+ if (projectId) resolvedRef = await resolveProjectRef(db, c, tenantId, projectId, ref);
83
+ else resolvedRef = await resolveTenantRef(db, tenantId, ref);
84
+ logger.info({
85
+ resolvedRef,
86
+ projectId,
87
+ tenantId
88
+ }, "Resolved ref");
89
+ c.set("resolvedRef", resolvedRef);
90
+ await next();
91
+ };
92
+ };
93
+ /**
94
+ * Resolve ref for project-scoped requests
95
+ */
96
+ async function resolveProjectRef(db, c, tenantId, projectId, ref) {
97
+ const projectMain = `${tenantId}_${projectId}_main`;
98
+ const projectScopedRef = `${tenantId}_${projectId}_${ref}`;
99
+ if (ref && ref !== "main") {
100
+ let refResult$1 = await resolveRef(db)(projectScopedRef);
101
+ if (!refResult$1) refResult$1 = await resolveRef(db)(ref);
102
+ if (!refResult$1) throw createApiError({
103
+ code: "not_found",
104
+ message: `Unknown ref: ${ref}`
105
+ });
106
+ return refResult$1;
107
+ }
108
+ let refResult = null;
109
+ try {
110
+ refResult = await resolveRef(db)(projectMain);
111
+ } catch (error) {
112
+ logger.warn({
113
+ error,
114
+ projectMain
115
+ }, "Failed to resolve project main branch");
116
+ refResult = null;
117
+ }
118
+ if (!refResult) {
119
+ if (c.req.method === "PUT") {
120
+ const tenantMain = `${tenantId}_main`;
121
+ let tenantRefResult = await resolveRef(db)(tenantMain);
122
+ if (!tenantRefResult) {
123
+ await ensureBranchExists(db, tenantMain);
124
+ tenantRefResult = await resolveRef(db)(tenantMain);
125
+ }
126
+ if (tenantRefResult) return tenantRefResult;
127
+ throw createApiError({
128
+ code: "internal_server_error",
129
+ message: `Failed to create tenant main branch for upsert`
130
+ });
131
+ }
132
+ throw createApiError({
133
+ code: "not_found",
134
+ message: `Project not found: ${projectId}`
135
+ });
136
+ }
137
+ return refResult;
138
+ }
139
+ /**
140
+ * Resolve ref for tenant-level requests
141
+ */
142
+ async function resolveTenantRef(db, tenantId, ref) {
143
+ const tenantMain = `${tenantId}_main`;
144
+ if (ref && ref !== "main") {
145
+ const tenantScopedRef = `${tenantId}_${ref}`;
146
+ let refResult$1 = await resolveRef(db)(tenantScopedRef);
147
+ if (!refResult$1) refResult$1 = await resolveRef(db)(ref);
148
+ if (!refResult$1) throw createApiError({
149
+ code: "not_found",
150
+ message: `Unknown ref: ${ref}`
151
+ });
152
+ return refResult$1;
153
+ }
154
+ let refResult = await resolveRef(db)(tenantMain);
155
+ if (!refResult) {
156
+ await ensureBranchExists(db, tenantMain);
157
+ refResult = await resolveRef(db)(tenantMain);
158
+ if (!refResult) throw createApiError({
159
+ code: "internal_server_error",
160
+ message: `Failed to create tenant main branch: ${tenantMain}`
161
+ });
162
+ }
163
+ return refResult;
164
+ }
165
+ /**
166
+ * Creates a write protection middleware that prevents write operations on immutable refs.
167
+ *
168
+ * This middleware checks if the resolved ref is writable (branches are writable,
169
+ * tags and commits are not) and rejects write operations on immutable refs.
170
+ *
171
+ * @returns Hono middleware function
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * import { createRefMiddleware, createWriteProtectionMiddleware } from '@inkeep/agents-core';
176
+ *
177
+ * const refMiddleware = createRefMiddleware(db);
178
+ * const writeProtection = createWriteProtectionMiddleware();
179
+ *
180
+ * app.use('/tenants/*', refMiddleware, writeProtection);
181
+ * ```
182
+ */
183
+ const createWriteProtectionMiddleware = () => {
184
+ return async (c, next) => {
185
+ if (process.env.ENVIRONMENT === "test") {
186
+ await next();
187
+ return;
188
+ }
189
+ const resolvedRef = c.get("resolvedRef");
190
+ if (!resolvedRef) {
191
+ await next();
192
+ return;
193
+ }
194
+ const method = c.req.method;
195
+ if ([
196
+ "POST",
197
+ "PUT",
198
+ "PATCH",
199
+ "DELETE"
200
+ ].includes(method) && !isRefWritable(resolvedRef)) throw createApiError({
201
+ code: "bad_request",
202
+ message: `Cannot perform write operation on ${resolvedRef.type}. Tags and commits are immutable. Write to a branch instead.`
203
+ });
204
+ await next();
205
+ };
206
+ };
207
+ /**
208
+ * @deprecated Use createRefMiddleware instead. This is kept for backwards compatibility.
209
+ */
210
+ const refMiddlewareFactory = createRefMiddleware;
211
+ /**
212
+ * @deprecated Use createWriteProtectionMiddleware instead. This is kept for backwards compatibility.
213
+ */
214
+ const writeProtectionMiddlewareFactory = createWriteProtectionMiddleware;
215
+
216
+ //#endregion
217
+ export { createRefMiddleware, createWriteProtectionMiddleware, refMiddlewareFactory, writeProtectionMiddlewareFactory };