@inkeep/agents-core 0.41.2 → 0.42.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/api-client/base-client.d.ts +87 -8
- package/dist/api-client/base-client.js +174 -1
- package/dist/api-client/eval-api-client.d.ts +47 -0
- package/dist/api-client/eval-api-client.js +65 -0
- package/dist/api-client/index.d.ts +4 -0
- package/dist/api-client/index.js +5 -0
- package/dist/api-client/manage-api-client.d.ts +34 -0
- package/dist/api-client/manage-api-client.js +104 -0
- package/dist/auth/auth.d.ts +86 -20
- package/dist/auth/auth.js +55 -1
- package/dist/auth/authz/client.d.ts +81 -0
- package/dist/auth/authz/client.js +189 -0
- package/dist/auth/authz/config.d.ts +76 -0
- package/dist/auth/authz/config.js +76 -0
- package/dist/auth/authz/index.d.ts +5 -0
- package/dist/auth/authz/index.js +6 -0
- package/dist/auth/authz/permissions.d.ts +57 -0
- package/dist/auth/authz/permissions.js +83 -0
- package/dist/auth/authz/sync.d.ts +85 -0
- package/dist/auth/authz/sync.js +237 -0
- package/dist/auth/permissions.d.ts +13 -13
- package/dist/auth/permissions.js +2 -181
- package/dist/client-exports.d.ts +8 -3
- package/dist/client-exports.js +3 -2
- package/dist/constants/context-breakdown.d.ts +61 -0
- package/dist/constants/context-breakdown.js +124 -0
- package/dist/constants/otel-attributes.d.ts +4 -0
- package/dist/constants/otel-attributes.js +4 -0
- package/dist/context/ContextConfig.d.ts +2 -2
- package/dist/context/ContextConfig.js +3 -3
- package/dist/context/TemplateEngine.js +0 -1
- package/dist/context/index.d.ts +1 -5
- package/dist/context/index.js +1 -5
- package/dist/credential-stuffer/CredentialStuffer.d.ts +1 -1
- package/dist/data-access/index.d.ts +34 -26
- package/dist/data-access/index.js +34 -26
- package/dist/data-access/manage/agentFull.d.ts +36 -0
- package/dist/data-access/{agentFull.js → manage/agentFull.js} +205 -7
- package/dist/data-access/{agents.d.ts → manage/agents.d.ts} +23 -22
- package/dist/data-access/{agents.js → manage/agents.js} +52 -7
- package/dist/data-access/{artifactComponents.d.ts → manage/artifactComponents.d.ts} +21 -21
- package/dist/data-access/{artifactComponents.js → manage/artifactComponents.js} +5 -5
- package/dist/data-access/{contextConfigs.d.ts → manage/contextConfigs.d.ts} +14 -14
- package/dist/data-access/{contextConfigs.js → manage/contextConfigs.js} +3 -3
- package/dist/data-access/{credentialReferences.d.ts → manage/credentialReferences.d.ts} +17 -17
- package/dist/data-access/{credentialReferences.js → manage/credentialReferences.js} +2 -2
- package/dist/data-access/{dataComponents.d.ts → manage/dataComponents.d.ts} +20 -20
- package/dist/data-access/{dataComponents.js → manage/dataComponents.js} +7 -7
- package/dist/data-access/manage/evalConfig.d.ts +221 -0
- package/dist/data-access/manage/evalConfig.js +275 -0
- package/dist/data-access/{externalAgents.d.ts → manage/externalAgents.d.ts} +16 -16
- package/dist/data-access/{externalAgents.js → manage/externalAgents.js} +2 -2
- package/dist/data-access/{functionTools.d.ts → manage/functionTools.d.ts} +65 -15
- package/dist/data-access/{functionTools.js → manage/functionTools.js} +90 -8
- package/dist/data-access/{functions.d.ts → manage/functions.d.ts} +9 -9
- package/dist/data-access/{functions.js → manage/functions.js} +3 -3
- package/dist/data-access/manage/projectFull.d.ts +38 -0
- package/dist/data-access/{projectFull.js → manage/projectFull.js} +64 -65
- package/dist/data-access/manage/projectLifecycle.d.ts +119 -0
- package/dist/data-access/manage/projectLifecycle.js +234 -0
- package/dist/data-access/manage/projects.d.ts +75 -0
- package/dist/data-access/{projects.js → manage/projects.js} +15 -16
- package/dist/data-access/{subAgentExternalAgentRelations.d.ts → manage/subAgentExternalAgentRelations.d.ts} +19 -19
- package/dist/data-access/{subAgentExternalAgentRelations.js → manage/subAgentExternalAgentRelations.js} +2 -2
- package/dist/data-access/{subAgentRelations.d.ts → manage/subAgentRelations.d.ts} +29 -29
- package/dist/data-access/{subAgentRelations.js → manage/subAgentRelations.js} +3 -3
- package/dist/data-access/{subAgentTeamAgentRelations.d.ts → manage/subAgentTeamAgentRelations.d.ts} +19 -19
- package/dist/data-access/{subAgentTeamAgentRelations.js → manage/subAgentTeamAgentRelations.js} +2 -2
- package/dist/data-access/{subAgents.d.ts → manage/subAgents.d.ts} +13 -13
- package/dist/data-access/{subAgents.js → manage/subAgents.js} +4 -4
- package/dist/data-access/{tools.d.ts → manage/tools.d.ts} +26 -19
- package/dist/data-access/{tools.js → manage/tools.js} +57 -35
- package/dist/data-access/manage/triggers.d.ts +80 -0
- package/dist/data-access/manage/triggers.js +81 -0
- package/dist/data-access/{apiKeys.d.ts → runtime/apiKeys.d.ts} +17 -17
- package/dist/data-access/{apiKeys.js → runtime/apiKeys.js} +3 -3
- package/dist/data-access/runtime/cascade-delete.d.ts +77 -0
- package/dist/data-access/runtime/cascade-delete.js +111 -0
- package/dist/data-access/{contextCache.d.ts → runtime/contextCache.d.ts} +13 -13
- package/dist/data-access/{contextCache.js → runtime/contextCache.js} +5 -5
- package/dist/data-access/{conversations.d.ts → runtime/conversations.d.ts} +68 -19
- package/dist/data-access/{conversations.js → runtime/conversations.js} +13 -7
- package/dist/data-access/runtime/evalRuns.d.ts +120 -0
- package/dist/data-access/runtime/evalRuns.js +168 -0
- package/dist/data-access/{ledgerArtifacts.d.ts → runtime/ledgerArtifacts.d.ts} +13 -13
- package/dist/data-access/{ledgerArtifacts.js → runtime/ledgerArtifacts.js} +3 -3
- package/dist/data-access/{messages.d.ts → runtime/messages.d.ts} +15 -15
- package/dist/data-access/{messages.js → runtime/messages.js} +2 -2
- package/dist/data-access/{organizations.d.ts → runtime/organizations.d.ts} +16 -7
- package/dist/data-access/{organizations.js → runtime/organizations.js} +15 -3
- package/dist/data-access/runtime/projects.d.ts +62 -0
- package/dist/data-access/runtime/projects.js +90 -0
- package/dist/data-access/runtime/tasks.d.ts +55 -0
- package/dist/data-access/{tasks.js → runtime/tasks.js} +2 -2
- package/dist/data-access/runtime/triggerInvocations.d.ts +62 -0
- package/dist/data-access/runtime/triggerInvocations.js +54 -0
- package/dist/data-access/runtime/users.d.ts +19 -0
- package/dist/data-access/{users.js → runtime/users.js} +2 -2
- package/dist/data-access/validation.d.ts +4 -4
- package/dist/data-access/validation.js +1 -1
- package/dist/db/clean.d.ts +8 -4
- package/dist/db/clean.js +14 -105
- package/dist/db/delete.d.ts +1 -1
- package/dist/db/delete.js +7 -10
- package/dist/db/manage/dolt-cleanup.d.ts +51 -0
- package/dist/db/manage/dolt-cleanup.js +132 -0
- package/dist/db/manage/manage-client.d.ts +26 -0
- package/dist/db/manage/manage-client.js +68 -0
- package/dist/db/{schema.d.ts → manage/manage-schema.d.ts} +1459 -1285
- package/dist/db/{schema.js → manage/manage-schema.js} +433 -341
- package/dist/db/manage/test-manage-client.d.ts +27 -0
- package/dist/db/manage/test-manage-client.js +68 -0
- package/dist/db/runtime/runtime-client.d.ts +20 -0
- package/dist/db/runtime/runtime-client.js +30 -0
- package/dist/db/runtime/runtime-schema.d.ts +2834 -0
- package/dist/db/runtime/runtime-schema.js +483 -0
- package/dist/db/runtime/test-runtime-client.d.ts +27 -0
- package/dist/db/{test-client.js → runtime/test-runtime-client.js} +11 -25
- package/dist/dolt/branch.d.ts +62 -0
- package/dist/dolt/branch.js +82 -0
- package/dist/dolt/branches-api.d.ts +108 -0
- package/dist/dolt/branches-api.js +162 -0
- package/dist/dolt/commit.d.ts +94 -0
- package/dist/dolt/commit.js +103 -0
- package/dist/dolt/diff.d.ts +27 -0
- package/dist/dolt/diff.js +21 -0
- package/dist/dolt/index.d.ts +10 -0
- package/dist/dolt/index.js +11 -0
- package/dist/dolt/merge.d.ts +63 -0
- package/dist/dolt/merge.js +81 -0
- package/dist/dolt/migrate-all-branches.d.ts +4 -0
- package/dist/dolt/migrate-all-branches.js +78 -0
- package/dist/dolt/migrate-dolt.d.ts +1 -0
- package/dist/dolt/migrate-dolt.js +22 -0
- package/dist/dolt/ref-helpers.d.ts +19 -0
- package/dist/dolt/ref-helpers.js +65 -0
- package/dist/dolt/ref-middleware.d.ts +82 -0
- package/dist/dolt/ref-middleware.js +217 -0
- package/dist/dolt/ref-scope.d.ts +101 -0
- package/dist/dolt/ref-scope.js +231 -0
- package/dist/dolt/schema-sync.d.ts +134 -0
- package/dist/dolt/schema-sync.js +246 -0
- package/dist/env.d.ts +6 -4
- package/dist/env.js +3 -2
- package/dist/index.d.ts +71 -44
- package/dist/index.js +74 -47
- package/dist/types/entities.d.ts +81 -2
- package/dist/types/index.d.ts +3 -3
- package/dist/types/utility.d.ts +45 -4
- package/dist/utils/JsonTransformer.d.ts +44 -0
- package/dist/utils/JsonTransformer.js +112 -0
- package/dist/utils/apiKeys.d.ts +5 -1
- package/dist/utils/apiKeys.js +11 -1
- package/dist/utils/colors.d.ts +34 -0
- package/dist/utils/colors.js +49 -0
- package/dist/utils/credential-store-utils.d.ts +1 -1
- package/dist/utils/format-messages.d.ts +1 -1
- package/dist/utils/index.d.ts +7 -3
- package/dist/utils/index.js +7 -3
- package/dist/utils/internal-service-auth.d.ts +79 -0
- package/dist/utils/internal-service-auth.js +140 -0
- package/dist/utils/jwt-helpers.d.ts +56 -0
- package/dist/utils/jwt-helpers.js +90 -0
- package/dist/utils/service-token-auth.d.ts +9 -27
- package/dist/utils/service-token-auth.js +48 -96
- package/dist/utils/template-interpolation.d.ts +22 -0
- package/dist/utils/template-interpolation.js +62 -0
- package/dist/utils/third-party-mcp-servers/composio-client.js +23 -23
- package/dist/utils/trigger-auth.d.ts +62 -0
- package/dist/utils/trigger-auth.js +125 -0
- package/dist/validation/agentFull.js +2 -4
- package/dist/validation/dolt-schemas.d.ts +49 -0
- package/dist/validation/dolt-schemas.js +44 -0
- package/dist/validation/drizzle-schema-helpers.d.ts +4 -26
- package/dist/validation/drizzle-schema-helpers.js +5 -151
- package/dist/validation/index.d.ts +4 -3
- package/dist/validation/index.js +3 -2
- package/dist/validation/schemas.d.ts +17647 -4789
- package/dist/validation/schemas.js +328 -11
- package/drizzle/manage/0000_tearful_rhodey.sql +414 -0
- package/drizzle/manage/0001_broken_wendell_vaughn.sql +19 -0
- package/drizzle/manage/0002_bent_sunfire.sql +1 -0
- package/drizzle/manage/meta/0000_snapshot.json +2987 -0
- package/drizzle/manage/meta/0001_snapshot.json +3115 -0
- package/drizzle/manage/meta/0002_snapshot.json +3115 -0
- package/drizzle/manage/meta/_journal.json +27 -0
- package/drizzle/runtime/0008_silly_preak.sql +127 -0
- package/drizzle/runtime/0009_freezing_leo.sql +17 -0
- package/drizzle/runtime/meta/0008_snapshot.json +2263 -0
- package/drizzle/runtime/meta/0009_snapshot.json +2397 -0
- package/drizzle/{meta → runtime/meta}/_journal.json +14 -0
- package/package.json +48 -15
- package/dist/context/ContextFetcher.d.ts +0 -73
- package/dist/context/ContextFetcher.js +0 -291
- package/dist/context/ContextResolver.d.ts +0 -60
- package/dist/context/ContextResolver.js +0 -278
- package/dist/context/context.d.ts +0 -27
- package/dist/context/context.js +0 -128
- package/dist/context/contextCache.d.ts +0 -58
- package/dist/context/contextCache.js +0 -177
- package/dist/data-access/agentFull.d.ts +0 -33
- package/dist/data-access/projectFull.d.ts +0 -32
- package/dist/data-access/projects.d.ts +0 -71
- package/dist/data-access/tasks.d.ts +0 -45
- package/dist/data-access/users.d.ts +0 -19
- package/dist/db/client.d.ts +0 -20
- package/dist/db/client.js +0 -28
- package/dist/db/test-client.d.ts +0 -31
- package/dist/middleware/contextValidation.d.ts +0 -46
- package/dist/middleware/contextValidation.js +0 -280
- package/dist/middleware/index.d.ts +0 -2
- package/dist/middleware/index.js +0 -3
- package/dist/utils/execution.d.ts +0 -22
- package/dist/utils/execution.js +0 -25
- /package/drizzle/{0000_exotic_mysterio.sql → runtime/0000_exotic_mysterio.sql} +0 -0
- /package/drizzle/{0001_calm_sheva_callister.sql → runtime/0001_calm_sheva_callister.sql} +0 -0
- /package/drizzle/{0002_puzzling_goblin_queen.sql → runtime/0002_puzzling_goblin_queen.sql} +0 -0
- /package/drizzle/{0003_sweet_human_robot.sql → runtime/0003_sweet_human_robot.sql} +0 -0
- /package/drizzle/{0004_cuddly_shooting_star.sql → runtime/0004_cuddly_shooting_star.sql} +0 -0
- /package/drizzle/{0005_reflective_starfox.sql → runtime/0005_reflective_starfox.sql} +0 -0
- /package/drizzle/{0006_stale_thaddeus_ross.sql → runtime/0006_stale_thaddeus_ross.sql} +0 -0
- /package/drizzle/{0007_slim_karma.sql → runtime/0007_slim_karma.sql} +0 -0
- /package/drizzle/{meta → runtime/meta}/0000_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0001_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0003_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0005_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0006_snapshot.json +0 -0
- /package/drizzle/{meta → runtime/meta}/0007_snapshot.json +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { AgentsManageDatabaseClient } from "../db/manage/manage-client.js";
|
|
2
|
+
|
|
3
|
+
//#region src/dolt/merge.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Merge another branch into the current branch
|
|
7
|
+
* Returns merge status and handles conflicts by allowing commit with conflicts
|
|
8
|
+
*/
|
|
9
|
+
declare const doltMerge: (db: AgentsManageDatabaseClient) => (params: {
|
|
10
|
+
fromBranch: string;
|
|
11
|
+
toBranch: string;
|
|
12
|
+
message?: string;
|
|
13
|
+
noFastForward?: boolean;
|
|
14
|
+
author?: {
|
|
15
|
+
name: string;
|
|
16
|
+
email: string;
|
|
17
|
+
};
|
|
18
|
+
}) => Promise<{
|
|
19
|
+
status: "success" | "conflicts";
|
|
20
|
+
from: string;
|
|
21
|
+
to: string;
|
|
22
|
+
toHead?: string;
|
|
23
|
+
hasConflicts: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Abort a merge
|
|
27
|
+
*/
|
|
28
|
+
declare const doltAbortMerge: (db: AgentsManageDatabaseClient) => () => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Get merge status
|
|
31
|
+
*/
|
|
32
|
+
declare const doltMergeStatus: (db: AgentsManageDatabaseClient) => () => Promise<{
|
|
33
|
+
isMerging: boolean;
|
|
34
|
+
source?: string;
|
|
35
|
+
target?: string;
|
|
36
|
+
unmergedTables?: string[];
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Get list of tables with conflicts
|
|
40
|
+
*/
|
|
41
|
+
declare const doltConflicts: (db: AgentsManageDatabaseClient) => () => Promise<{
|
|
42
|
+
table: string;
|
|
43
|
+
numConflicts: number;
|
|
44
|
+
}[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Get detailed conflicts for a specific table
|
|
47
|
+
*/
|
|
48
|
+
declare const doltTableConflicts: (db: AgentsManageDatabaseClient) => (params: {
|
|
49
|
+
tableName: string;
|
|
50
|
+
}) => Promise<any[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Get schema conflicts
|
|
53
|
+
*/
|
|
54
|
+
declare const doltSchemaConflicts: (db: AgentsManageDatabaseClient) => () => Promise<any[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Resolve conflicts for a table using a strategy
|
|
57
|
+
*/
|
|
58
|
+
declare const doltResolveConflicts: (db: AgentsManageDatabaseClient) => (params: {
|
|
59
|
+
tableName: string;
|
|
60
|
+
strategy: "ours" | "theirs";
|
|
61
|
+
}) => Promise<void>;
|
|
62
|
+
//#endregion
|
|
63
|
+
export { doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { doltCheckout } from "./branch.js";
|
|
2
|
+
import { sql } from "drizzle-orm";
|
|
3
|
+
|
|
4
|
+
//#region src/dolt/merge.ts
|
|
5
|
+
/**
|
|
6
|
+
* Merge another branch into the current branch
|
|
7
|
+
* Returns merge status and handles conflicts by allowing commit with conflicts
|
|
8
|
+
*/
|
|
9
|
+
const doltMerge = (db) => async (params) => {
|
|
10
|
+
console.log("merging branch", params.fromBranch, "into", params.toBranch);
|
|
11
|
+
await doltCheckout(db)({ branch: params.toBranch });
|
|
12
|
+
const toHead = (await db.execute(sql`SELECT HASHOF('HEAD') as hash`)).rows[0]?.hash;
|
|
13
|
+
const args = [`'${params.fromBranch}'`];
|
|
14
|
+
if (params.noFastForward) args.push("'--no-ff'");
|
|
15
|
+
if (params.message) args.push("'-m'", `'${params.message.replace(/'/g, "''")}'`);
|
|
16
|
+
if (params.author) args.push("'--author'", `'${params.author.name} <${params.author.email}>'`);
|
|
17
|
+
const firstRow = (await db.execute(sql.raw(`SELECT DOLT_MERGE(${args.join(", ")})`))).rows[0] ?? {};
|
|
18
|
+
const mergeResult = typeof firstRow.conflicts === "number" || typeof firstRow.conflicts === "string" || firstRow.conflicts == null ? firstRow : Object.values(firstRow)[0] ?? {};
|
|
19
|
+
const conflicts = Number(mergeResult.conflicts ?? 0);
|
|
20
|
+
if (Number.isFinite(conflicts) && conflicts > 0) return {
|
|
21
|
+
status: "conflicts",
|
|
22
|
+
from: params.fromBranch,
|
|
23
|
+
to: params.toBranch,
|
|
24
|
+
toHead,
|
|
25
|
+
hasConflicts: true
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
status: "success",
|
|
29
|
+
from: params.fromBranch,
|
|
30
|
+
to: params.toBranch,
|
|
31
|
+
toHead,
|
|
32
|
+
hasConflicts: false
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Abort a merge
|
|
37
|
+
*/
|
|
38
|
+
const doltAbortMerge = (db) => async () => {
|
|
39
|
+
await db.execute(sql.raw(`SELECT DOLT_MERGE('--abort')`));
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Get merge status
|
|
43
|
+
*/
|
|
44
|
+
const doltMergeStatus = (db) => async () => {
|
|
45
|
+
const status = (await db.execute(sql`SELECT * FROM DOLT_MERGE_STATUS`)).rows[0];
|
|
46
|
+
if (!status || !status.is_merging) return { isMerging: false };
|
|
47
|
+
return {
|
|
48
|
+
isMerging: status.is_merging,
|
|
49
|
+
source: status.source,
|
|
50
|
+
target: status.target,
|
|
51
|
+
unmergedTables: status.unmerged_tables ? status.unmerged_tables.split(",") : []
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Get list of tables with conflicts
|
|
56
|
+
*/
|
|
57
|
+
const doltConflicts = (db) => async () => {
|
|
58
|
+
return (await db.execute(sql`SELECT * FROM dolt_conflicts`)).rows;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Get detailed conflicts for a specific table
|
|
62
|
+
*/
|
|
63
|
+
const doltTableConflicts = (db) => async (params) => {
|
|
64
|
+
return (await db.execute(sql.raw(`SELECT * FROM dolt_conflicts_${params.tableName}`))).rows;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Get schema conflicts
|
|
68
|
+
*/
|
|
69
|
+
const doltSchemaConflicts = (db) => async () => {
|
|
70
|
+
return (await db.execute(sql`SELECT * FROM dolt_schema_conflicts`)).rows;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Resolve conflicts for a table using a strategy
|
|
74
|
+
*/
|
|
75
|
+
const doltResolveConflicts = (db) => async (params) => {
|
|
76
|
+
await db.execute(sql`SET dolt_allow_commit_conflicts = 1`);
|
|
77
|
+
await db.execute(sql.raw(`SELECT DOLT_CONFLICTS_RESOLVE('--${params.strategy}', '${params.tableName}')`));
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
export { doltAbortMerge, doltConflicts, doltMerge, doltMergeStatus, doltResolveConflicts, doltSchemaConflicts, doltTableConflicts };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createAgentsManageDatabaseClient } from "../db/manage/manage-client.js";
|
|
2
|
+
import { syncSchemaFromMain } from "./schema-sync.js";
|
|
3
|
+
import { doltCheckout, doltListBranches } from "./branch.js";
|
|
4
|
+
|
|
5
|
+
//#region src/dolt/migrate-all-branches.ts
|
|
6
|
+
const ansi = {
|
|
7
|
+
reset: "\x1B[0m",
|
|
8
|
+
dim: "\x1B[2m",
|
|
9
|
+
bold: "\x1B[1m",
|
|
10
|
+
green: "\x1B[32m",
|
|
11
|
+
red: "\x1B[31m",
|
|
12
|
+
yellow: "\x1B[33m",
|
|
13
|
+
cyan: "\x1B[36m"
|
|
14
|
+
};
|
|
15
|
+
const format = {
|
|
16
|
+
header: (text) => `${ansi.bold}${ansi.cyan}${text}${ansi.reset}`,
|
|
17
|
+
ok: (text) => `${ansi.green}${text}${ansi.reset}`,
|
|
18
|
+
warn: (text) => `${ansi.yellow}${text}${ansi.reset}`,
|
|
19
|
+
err: (text) => `${ansi.red}${text}${ansi.reset}`,
|
|
20
|
+
dim: (text) => `${ansi.dim}${text}${ansi.reset}`,
|
|
21
|
+
bold: (text) => `${ansi.bold}${text}${ansi.reset}`
|
|
22
|
+
};
|
|
23
|
+
const ms = (start, end) => `${Math.max(0, end - start)}ms`;
|
|
24
|
+
const main = async () => {
|
|
25
|
+
const startedAt = Date.now();
|
|
26
|
+
const db = createAgentsManageDatabaseClient({});
|
|
27
|
+
const branches = await doltListBranches(db)();
|
|
28
|
+
const targetBranches = branches.filter((b) => b.name !== "main");
|
|
29
|
+
const nameWidth = Math.max(12, ...targetBranches.map((b) => b.name.length));
|
|
30
|
+
console.log(format.header(`Sync schema from main → ${targetBranches.length} branches`));
|
|
31
|
+
console.log(format.dim(`Started: ${(/* @__PURE__ */ new Date()).toISOString()}`));
|
|
32
|
+
console.log("");
|
|
33
|
+
let syncedCount = 0;
|
|
34
|
+
let upToDateCount = 0;
|
|
35
|
+
let errorCount = 0;
|
|
36
|
+
for (const branch of branches) {
|
|
37
|
+
if (branch.name === "main") continue;
|
|
38
|
+
const branchStartedAt = Date.now();
|
|
39
|
+
const paddedName = branch.name.padEnd(nameWidth, " ");
|
|
40
|
+
console.log(`${format.bold("─".repeat(Math.min(80, nameWidth + 34)))}`);
|
|
41
|
+
console.log(`${format.bold("Branch")} ${format.header(paddedName)}`);
|
|
42
|
+
try {
|
|
43
|
+
process.stdout.write(`${format.dim("Action ")} checkout… `);
|
|
44
|
+
await doltCheckout(db)({ branch: branch.name });
|
|
45
|
+
console.log(format.ok("[OK]"));
|
|
46
|
+
process.stdout.write(`${format.dim("Action ")} sync schema… `);
|
|
47
|
+
const result = await syncSchemaFromMain(db)();
|
|
48
|
+
if (result.synced) {
|
|
49
|
+
syncedCount += 1;
|
|
50
|
+
console.log(format.ok("[SYNCED]"));
|
|
51
|
+
console.log(`${format.dim("Result ")} ${format.ok("Schema updated")} ${format.dim(`(${ms(branchStartedAt, Date.now())})`)}`);
|
|
52
|
+
} else if (result.error) {
|
|
53
|
+
errorCount += 1;
|
|
54
|
+
console.log(format.err("[FAILED]"));
|
|
55
|
+
console.log(`${format.dim("Result ")} ${format.err("Error")} ${format.dim(`(${ms(branchStartedAt, Date.now())})`)}`);
|
|
56
|
+
console.log(`${format.dim("Details")} ${result.error}`);
|
|
57
|
+
} else {
|
|
58
|
+
upToDateCount += 1;
|
|
59
|
+
console.log(format.warn("[NOOP]"));
|
|
60
|
+
console.log(`${format.dim("Result ")} ${format.warn("Already up to date")} ${format.dim(`(${ms(branchStartedAt, Date.now())})`)}`);
|
|
61
|
+
}
|
|
62
|
+
} catch (error) {
|
|
63
|
+
errorCount += 1;
|
|
64
|
+
console.log(format.err("[FAILED]"));
|
|
65
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
66
|
+
console.log(`${format.dim("Result ")} ${format.err("Error")} ${format.dim(`(${ms(branchStartedAt, Date.now())})`)}`);
|
|
67
|
+
console.log(`${format.dim("Details")} ${message}`);
|
|
68
|
+
}
|
|
69
|
+
console.log("");
|
|
70
|
+
}
|
|
71
|
+
console.log(format.bold("─".repeat(80)));
|
|
72
|
+
console.log(`${format.bold("Summary")} ${format.ok(`${syncedCount} synced`)}, ${format.warn(`${upToDateCount} up to date`)}, ${errorCount > 0 ? format.err(`${errorCount} failed`) : format.ok("0 failed")}`);
|
|
73
|
+
console.log(format.dim(`Total: ${ms(startedAt, Date.now())}`));
|
|
74
|
+
};
|
|
75
|
+
main();
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { main };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { loadEnvironmentFiles } from "../env.js";
|
|
2
|
+
import { createAgentsManageDatabaseClient } from "../db/manage/manage-client.js";
|
|
3
|
+
import { doltAddAndCommit, doltStatus } from "./commit.js";
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
|
|
6
|
+
//#region src/dolt/migrate-dolt.ts
|
|
7
|
+
const commitMigrations = async () => {
|
|
8
|
+
loadEnvironmentFiles();
|
|
9
|
+
try {
|
|
10
|
+
execSync("drizzle-kit migrate --config=drizzle.manage.config.ts", { stdio: "inherit" });
|
|
11
|
+
} catch (error) {
|
|
12
|
+
console.error("❌ Error running migrations:", error);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const db = createAgentsManageDatabaseClient({ connectionString: process.env.INKEEP_AGENTS_MANAGE_DATABASE_URL });
|
|
16
|
+
if ((await doltStatus(db)()).length > 0) await doltAddAndCommit(db)({ message: "Applied database migrations" });
|
|
17
|
+
else console.log("ℹ️ No changes to commit - database is up to date\n");
|
|
18
|
+
};
|
|
19
|
+
commitMigrations();
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ResolvedRef } from "../validation/dolt-schemas.js";
|
|
2
|
+
import { AgentsManageDatabaseClient } from "../db/manage/manage-client.js";
|
|
3
|
+
|
|
4
|
+
//#region src/dolt/ref-helpers.d.ts
|
|
5
|
+
type RefType = 'commit' | 'tag' | 'branch';
|
|
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;
|
|
9
|
+
declare const resolveRef: (db: AgentsManageDatabaseClient) => (ref: string) => Promise<ResolvedRef | null>;
|
|
10
|
+
declare const isRefWritable: (resolvedRef: ResolvedRef) => boolean;
|
|
11
|
+
declare const checkoutRef: (db: AgentsManageDatabaseClient) => (resolvedRef: ResolvedRef) => Promise<void>;
|
|
12
|
+
declare const getCurrentBranchOrCommit: (db: AgentsManageDatabaseClient) => () => Promise<{
|
|
13
|
+
ref: string;
|
|
14
|
+
hash: string;
|
|
15
|
+
type: RefType;
|
|
16
|
+
}>;
|
|
17
|
+
declare const getProjectMainResolvedRef: (db: AgentsManageDatabaseClient) => (tenantId: string, projectId: string) => Promise<ResolvedRef>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { RefType, checkoutRef, getCurrentBranchOrCommit, getProjectMainResolvedRef, getProjectScopedRef, getTenantScopedRef, isRefWritable, isValidCommitHash, resolveRef };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { doltHashOf, doltListTags } from "./commit.js";
|
|
2
|
+
import { checkoutBranch } from "./branches-api.js";
|
|
3
|
+
import { doltListBranches } from "./branch.js";
|
|
4
|
+
import { sql } from "drizzle-orm";
|
|
5
|
+
|
|
6
|
+
//#region src/dolt/ref-helpers.ts
|
|
7
|
+
const isValidCommitHash = (ref) => {
|
|
8
|
+
return /^[0-9a-v]{32}$/.test(ref);
|
|
9
|
+
};
|
|
10
|
+
const getProjectScopedRef = (tenantId, projectId, ref) => {
|
|
11
|
+
return `${tenantId}_${projectId}_${ref}`;
|
|
12
|
+
};
|
|
13
|
+
const getTenantScopedRef = (tenantId, ref) => {
|
|
14
|
+
return `${tenantId}_${ref}`;
|
|
15
|
+
};
|
|
16
|
+
const resolveRef = (db) => async (ref) => {
|
|
17
|
+
if (isValidCommitHash(ref)) return {
|
|
18
|
+
type: "commit",
|
|
19
|
+
name: ref,
|
|
20
|
+
hash: ref
|
|
21
|
+
};
|
|
22
|
+
const tag = (await doltListTags(db)()).find((t) => t.tag_name === ref);
|
|
23
|
+
if (tag) return {
|
|
24
|
+
type: "tag",
|
|
25
|
+
name: ref,
|
|
26
|
+
hash: tag.tag_hash
|
|
27
|
+
};
|
|
28
|
+
const branch = (await doltListBranches(db)()).find((b) => b.name === ref);
|
|
29
|
+
if (branch) return {
|
|
30
|
+
type: "branch",
|
|
31
|
+
name: ref,
|
|
32
|
+
hash: branch.hash
|
|
33
|
+
};
|
|
34
|
+
return null;
|
|
35
|
+
};
|
|
36
|
+
const isRefWritable = (resolvedRef) => {
|
|
37
|
+
return resolvedRef.type === "branch";
|
|
38
|
+
};
|
|
39
|
+
const checkoutRef = (db) => async (resolvedRef) => {
|
|
40
|
+
if (resolvedRef.type === "branch") await checkoutBranch(db)({ branchName: resolvedRef.name });
|
|
41
|
+
else await db.execute(sql.raw(`SELECT DOLT_CHECKOUT('${resolvedRef.hash}')`));
|
|
42
|
+
};
|
|
43
|
+
const getCurrentBranchOrCommit = (db) => async () => {
|
|
44
|
+
const branch = (await db.execute(sql`SELECT ACTIVE_BRANCH() as branch`)).rows[0]?.branch;
|
|
45
|
+
if (branch) return {
|
|
46
|
+
ref: branch,
|
|
47
|
+
hash: await doltHashOf(db)({ revision: branch }),
|
|
48
|
+
type: "branch"
|
|
49
|
+
};
|
|
50
|
+
const hash = (await db.execute(sql`SELECT DOLT_HASHOF('HEAD') as hash`)).rows[0]?.hash;
|
|
51
|
+
return {
|
|
52
|
+
ref: hash,
|
|
53
|
+
hash,
|
|
54
|
+
type: "commit"
|
|
55
|
+
};
|
|
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
|
+
};
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
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 };
|