@inkeep/agents-core 0.63.3 → 0.64.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/api-client/eval-api-client.d.ts +2 -12
- package/dist/api-client/eval-api-client.js +0 -15
- package/dist/api-client/index.d.ts +2 -2
- package/dist/auth/auth.js +28 -9
- package/dist/auth/entitlement-constants.d.ts +11 -0
- package/dist/auth/entitlement-constants.js +10 -0
- package/dist/auth/entitlement-lock.d.ts +6 -0
- package/dist/auth/entitlement-lock.js +13 -0
- package/dist/auth/entitlements.d.ts +11 -0
- package/dist/auth/entitlements.js +55 -0
- package/dist/auth/init.js +2 -4
- package/dist/auth/permissions.d.ts +9 -9
- package/dist/client-exports.d.ts +6 -4
- package/dist/client-exports.js +4 -2
- package/dist/constants/models.d.ts +2 -1
- package/dist/constants/models.js +6 -1
- package/dist/constants/otel-attributes.d.ts +2 -0
- package/dist/constants/otel-attributes.js +2 -0
- package/dist/data-access/index.d.ts +5 -4
- package/dist/data-access/index.js +4 -3
- package/dist/data-access/manage/agents.d.ts +83 -41
- package/dist/data-access/manage/artifactComponents.d.ts +8 -8
- package/dist/data-access/manage/contextConfigs.d.ts +8 -8
- package/dist/data-access/manage/dataComponents.d.ts +4 -4
- package/dist/data-access/manage/evalConfig.d.ts +49 -3
- package/dist/data-access/manage/evalConfig.js +61 -3
- package/dist/data-access/manage/functionTools.d.ts +10 -10
- package/dist/data-access/manage/projectLifecycle.d.ts +1 -1
- package/dist/data-access/manage/skills.d.ts +12 -12
- package/dist/data-access/manage/subAgentExternalAgentRelations.d.ts +24 -18
- package/dist/data-access/manage/subAgentRelations.d.ts +32 -26
- package/dist/data-access/manage/subAgentTeamAgentRelations.d.ts +30 -18
- package/dist/data-access/manage/subAgents.d.ts +51 -15
- package/dist/data-access/manage/tools.d.ts +21 -21
- package/dist/data-access/manage/tools.js +41 -4
- package/dist/data-access/runtime/apiKeys.d.ts +12 -12
- package/dist/data-access/runtime/apps.d.ts +40 -49
- package/dist/data-access/runtime/cascade-delete.d.ts +1 -1
- package/dist/data-access/runtime/conversations.d.ts +25 -25
- package/dist/data-access/runtime/entitlements.d.ts +13 -0
- package/dist/data-access/runtime/entitlements.js +33 -0
- package/dist/data-access/runtime/ledgerArtifacts.d.ts +1 -1
- package/dist/data-access/runtime/messages.d.ts +13 -13
- package/dist/data-access/runtime/scheduledTriggerInvocations.d.ts +47 -2
- package/dist/data-access/runtime/scheduledTriggerInvocations.js +34 -1
- package/dist/data-access/runtime/tasks.d.ts +7 -7
- package/dist/data-access/runtime/workflowExecutions.d.ts +1 -1
- package/dist/data-reconciliation/types.d.ts +1 -1
- package/dist/db/clean.d.ts +1 -1
- package/dist/db/manage/manage-schema.d.ts +674 -596
- package/dist/db/manage/manage-schema.js +154 -134
- package/dist/db/runtime/runtime-schema.d.ts +499 -392
- package/dist/db/runtime/runtime-schema.js +20 -3
- package/dist/dolt/backfill-skill-files.d.ts +41 -0
- package/dist/dolt/backfill-skill-files.js +209 -0
- package/dist/dolt/run-sql-file-on-all-branches.d.ts +29 -0
- package/dist/dolt/run-sql-file-on-all-branches.js +177 -0
- package/dist/index.d.ts +20 -16
- package/dist/index.js +12 -8
- package/dist/middleware/create-protected-route.d.ts +3 -0
- package/dist/middleware/create-protected-route.js +7 -2
- package/dist/middleware/entitlement-meta.d.ts +9 -0
- package/dist/middleware/entitlement-meta.js +11 -0
- package/dist/middleware/index.d.ts +2 -1
- package/dist/middleware/index.js +2 -1
- package/dist/types/entities.d.ts +8 -3
- package/dist/types/index.d.ts +3 -3
- package/dist/types/utility.d.ts +5 -6
- package/dist/utils/error.d.ts +54 -51
- package/dist/utils/error.js +3 -0
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +2 -2
- package/dist/utils/mcp-client.d.ts +1 -1
- package/dist/utils/mcp-client.js +1 -1
- package/dist/utils/model-factory.js +24 -9
- package/dist/utils/usage-cost-middleware.d.ts +2 -1
- package/dist/utils/usage-cost-middleware.js +22 -5
- package/dist/validation/index.d.ts +2 -2
- package/dist/validation/index.js +2 -2
- package/dist/validation/schemas/skills.d.ts +45 -45
- package/dist/validation/schemas.d.ts +3504 -2569
- package/dist/validation/schemas.js +22 -24
- package/drizzle/manage/0016_complex_klaw.sql +2 -0
- package/drizzle/manage/0017_brief_doctor_strange.sql +29 -0
- package/drizzle/manage/meta/0016_snapshot.json +3530 -0
- package/drizzle/manage/meta/0017_snapshot.json +3748 -0
- package/drizzle/manage/meta/_journal.json +14 -0
- package/drizzle/runtime/0029_burly_satana.sql +13 -0
- package/drizzle/runtime/0030_set-allow-anonymous-for-existing-apps.sql +56 -0
- package/drizzle/runtime/meta/0029_snapshot.json +4756 -0
- package/drizzle/runtime/meta/_journal.json +14 -0
- package/package.json +3 -1
- /package/drizzle/runtime/meta/{0023_snapshot.json → 0025_snapshot.json} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { __exportAll } from "../../_virtual/rolldown_runtime.js";
|
|
2
2
|
import { account, deviceCode, invitation, member, organization, session, ssoProvider, user, verification } from "../../auth/auth-schema.js";
|
|
3
3
|
import { USAGE_GENERATION_TYPES } from "../../constants/otel-attributes.js";
|
|
4
|
-
import { relations } from "drizzle-orm";
|
|
5
|
-
import { boolean, foreignKey, index, integer, jsonb, pgTable, primaryKey, text, timestamp, unique, uniqueIndex, varchar } from "drizzle-orm/pg-core";
|
|
4
|
+
import { relations, sql } from "drizzle-orm";
|
|
5
|
+
import { boolean, check, foreignKey, index, integer, jsonb, pgTable, primaryKey, text, timestamp, unique, uniqueIndex, varchar } from "drizzle-orm/pg-core";
|
|
6
6
|
|
|
7
7
|
//#region src/db/runtime/runtime-schema.ts
|
|
8
8
|
var runtime_schema_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -24,6 +24,7 @@ var runtime_schema_exports = /* @__PURE__ */ __exportAll({
|
|
|
24
24
|
member: () => member,
|
|
25
25
|
messages: () => messages,
|
|
26
26
|
messagesRelations: () => messagesRelations,
|
|
27
|
+
orgEntitlement: () => orgEntitlement,
|
|
27
28
|
organization: () => organization,
|
|
28
29
|
projectMetadata: () => projectMetadata,
|
|
29
30
|
scheduledTriggerInvocations: () => scheduledTriggerInvocations,
|
|
@@ -870,6 +871,22 @@ const workAppSlackMcpToolAccessConfig = pgTable("work_app_slack_mcp_tool_access_
|
|
|
870
871
|
name: "work_app_slack_mcp_tool_access_config_tenant_fk"
|
|
871
872
|
}).onDelete("cascade")
|
|
872
873
|
]);
|
|
874
|
+
const orgEntitlement = pgTable("org_entitlement", {
|
|
875
|
+
id: varchar("id", { length: 256 }).primaryKey(),
|
|
876
|
+
organizationId: varchar("organization_id", { length: 256 }).notNull(),
|
|
877
|
+
resourceType: text("resource_type").notNull(),
|
|
878
|
+
maxValue: integer("max_value").notNull(),
|
|
879
|
+
...timestamps
|
|
880
|
+
}, (table) => [
|
|
881
|
+
unique("org_entitlement_org_resource_unique").on(table.organizationId, table.resourceType),
|
|
882
|
+
index("org_entitlement_org_idx").on(table.organizationId),
|
|
883
|
+
foreignKey({
|
|
884
|
+
columns: [table.organizationId],
|
|
885
|
+
foreignColumns: [organization.id],
|
|
886
|
+
name: "org_entitlement_organization_fk"
|
|
887
|
+
}).onDelete("cascade"),
|
|
888
|
+
check("org_entitlement_resource_type_format", sql`resource_type ~ '^[a-z]+:[a-z][a-z0-9_]*$'`)
|
|
889
|
+
]);
|
|
873
890
|
|
|
874
891
|
//#endregion
|
|
875
|
-
export { USAGE_GENERATION_TYPES, account, apiKeys, apps, contextCache, conversations, conversationsRelations, datasetRun, datasetRunConversationRelations, deviceCode, evaluationResult, evaluationRun, invitation, ledgerArtifacts, ledgerArtifactsRelations, member, messages, messagesRelations, organization, projectMetadata, runtime_schema_exports, scheduledTriggerInvocations, scheduledTriggers, schedulerState, session, ssoProvider, taskRelations, taskRelationsRelations, tasks, tasksRelations, triggerInvocations, user, userProfile, userProfileRelations, verification, workAppGitHubInstallations, workAppGitHubInstallationsRelations, workAppGitHubMcpToolAccessMode, workAppGitHubMcpToolRepositoryAccess, workAppGitHubMcpToolRepositoryAccessRelations, workAppGitHubProjectAccessMode, workAppGitHubProjectRepositoryAccess, workAppGitHubProjectRepositoryAccessRelations, workAppGitHubRepositories, workAppGitHubRepositoriesRelations, workAppSlackChannelAgentConfigs, workAppSlackMcpToolAccessConfig, workAppSlackUserMappings, workAppSlackWorkspaces, workflowExecutions };
|
|
892
|
+
export { USAGE_GENERATION_TYPES, account, apiKeys, apps, contextCache, conversations, conversationsRelations, datasetRun, datasetRunConversationRelations, deviceCode, evaluationResult, evaluationRun, invitation, ledgerArtifacts, ledgerArtifactsRelations, member, messages, messagesRelations, orgEntitlement, organization, projectMetadata, runtime_schema_exports, scheduledTriggerInvocations, scheduledTriggers, schedulerState, session, ssoProvider, taskRelations, taskRelationsRelations, tasks, tasksRelations, triggerInvocations, user, userProfile, userProfileRelations, verification, workAppGitHubInstallations, workAppGitHubInstallationsRelations, workAppGitHubMcpToolAccessMode, workAppGitHubMcpToolRepositoryAccess, workAppGitHubMcpToolRepositoryAccessRelations, workAppGitHubProjectAccessMode, workAppGitHubProjectRepositoryAccess, workAppGitHubProjectRepositoryAccessRelations, workAppGitHubRepositories, workAppGitHubRepositoriesRelations, workAppSlackChannelAgentConfigs, workAppSlackMcpToolAccessConfig, workAppSlackUserMappings, workAppSlackWorkspaces, workflowExecutions };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/dolt/backfill-skill-files.d.ts
|
|
2
|
+
type SkillBackfillSource = {
|
|
3
|
+
tenantId: string;
|
|
4
|
+
projectId: string;
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
content: string;
|
|
9
|
+
metadata: Record<string, string> | null;
|
|
10
|
+
createdAt: string;
|
|
11
|
+
updatedAt: string;
|
|
12
|
+
};
|
|
13
|
+
type ExistingSkillEntryFile = {
|
|
14
|
+
tenantId: string;
|
|
15
|
+
projectId: string;
|
|
16
|
+
skillId: string;
|
|
17
|
+
};
|
|
18
|
+
type BackfillSkillFilesArgs = {
|
|
19
|
+
apply: boolean;
|
|
20
|
+
branchNames: string[];
|
|
21
|
+
continueOnError: boolean;
|
|
22
|
+
help: boolean;
|
|
23
|
+
includeMain: boolean;
|
|
24
|
+
};
|
|
25
|
+
declare function buildLegacySkillFileId(skill: Pick<SkillBackfillSource, 'tenantId' | 'projectId' | 'id'>): string;
|
|
26
|
+
declare function buildMissingSkillFileRows(sourceSkills: SkillBackfillSource[], existingSkillEntryFiles: ExistingSkillEntryFile[]): {
|
|
27
|
+
tenantId: string;
|
|
28
|
+
id: string;
|
|
29
|
+
projectId: string;
|
|
30
|
+
skillId: string;
|
|
31
|
+
filePath: string;
|
|
32
|
+
content: string;
|
|
33
|
+
createdAt: string;
|
|
34
|
+
updatedAt: string;
|
|
35
|
+
}[];
|
|
36
|
+
declare function parseBackfillSkillFilesArgs(argv: string[]): BackfillSkillFilesArgs;
|
|
37
|
+
declare function getBackfillSkillFilesUsage(): string;
|
|
38
|
+
declare function backfillSkillFilesAcrossAllBranches(options: Omit<BackfillSkillFilesArgs, 'help'>): Promise<void>;
|
|
39
|
+
declare function main(argv?: string[]): Promise<void>;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { BackfillSkillFilesArgs, backfillSkillFilesAcrossAllBranches, buildLegacySkillFileId, buildMissingSkillFileRows, getBackfillSkillFilesUsage, main, parseBackfillSkillFilesArgs };
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { manage_schema_exports, skillFiles, skills } from "../db/manage/manage-schema.js";
|
|
2
|
+
import { loadEnvironmentFiles } from "../env.js";
|
|
3
|
+
import { createAgentsManageDatabasePool } from "../db/manage/manage-client.js";
|
|
4
|
+
import { doltReset } from "./commit.js";
|
|
5
|
+
import { doltListBranches } from "./branch.js";
|
|
6
|
+
import { confirmMigration } from "../db/utils.js";
|
|
7
|
+
import { eq } from "drizzle-orm";
|
|
8
|
+
import { stringify } from "yaml";
|
|
9
|
+
import { drizzle } from "drizzle-orm/node-postgres";
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
|
|
12
|
+
//#region src/dolt/backfill-skill-files.ts
|
|
13
|
+
const DEFAULT_AUTHOR = {
|
|
14
|
+
name: "migration-script",
|
|
15
|
+
email: "migration@inkeep.com"
|
|
16
|
+
};
|
|
17
|
+
const DEFAULT_COMMIT_MESSAGE = "Backfill legacy SKILL.md skill files";
|
|
18
|
+
const SKILL_ENTRY_FILE_PATH = "SKILL.md";
|
|
19
|
+
function serializeSkillEntryFile(skill) {
|
|
20
|
+
return [
|
|
21
|
+
"---",
|
|
22
|
+
stringify({
|
|
23
|
+
name: skill.name,
|
|
24
|
+
description: skill.description,
|
|
25
|
+
metadata: skill.metadata ?? void 0
|
|
26
|
+
}).trimEnd(),
|
|
27
|
+
"---",
|
|
28
|
+
"",
|
|
29
|
+
skill.content
|
|
30
|
+
].join("\n");
|
|
31
|
+
}
|
|
32
|
+
function buildLegacySkillFileId(skill) {
|
|
33
|
+
return `legacy-${createHash("md5").update(`${skill.tenantId}:${skill.projectId}:${skill.id}:${SKILL_ENTRY_FILE_PATH}`).digest("hex")}`;
|
|
34
|
+
}
|
|
35
|
+
function buildMissingSkillFileRows(sourceSkills, existingSkillEntryFiles) {
|
|
36
|
+
const existingKeys = new Set(existingSkillEntryFiles.map((file) => `${file.tenantId}:${file.projectId}:${file.skillId}:${SKILL_ENTRY_FILE_PATH}`));
|
|
37
|
+
return sourceSkills.filter((skill) => !existingKeys.has(`${skill.tenantId}:${skill.projectId}:${skill.id}:${SKILL_ENTRY_FILE_PATH}`)).map((skill) => ({
|
|
38
|
+
tenantId: skill.tenantId,
|
|
39
|
+
id: buildLegacySkillFileId(skill),
|
|
40
|
+
projectId: skill.projectId,
|
|
41
|
+
skillId: skill.id,
|
|
42
|
+
filePath: SKILL_ENTRY_FILE_PATH,
|
|
43
|
+
content: serializeSkillEntryFile(skill),
|
|
44
|
+
createdAt: skill.createdAt,
|
|
45
|
+
updatedAt: skill.updatedAt
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
function readNextArg(argv, index, flag) {
|
|
49
|
+
const value = argv[index + 1];
|
|
50
|
+
if (!value || value.startsWith("--")) throw new Error(`Missing value for ${flag}`);
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
function parseBackfillSkillFilesArgs(argv) {
|
|
54
|
+
const parsed = {
|
|
55
|
+
apply: false,
|
|
56
|
+
branchNames: [],
|
|
57
|
+
continueOnError: false,
|
|
58
|
+
help: false,
|
|
59
|
+
includeMain: true
|
|
60
|
+
};
|
|
61
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
62
|
+
const arg = argv[index];
|
|
63
|
+
switch (arg) {
|
|
64
|
+
case "--apply":
|
|
65
|
+
parsed.apply = true;
|
|
66
|
+
break;
|
|
67
|
+
case "--branch":
|
|
68
|
+
parsed.branchNames.push(readNextArg(argv, index, arg));
|
|
69
|
+
index += 1;
|
|
70
|
+
break;
|
|
71
|
+
case "--continue-on-error":
|
|
72
|
+
parsed.continueOnError = true;
|
|
73
|
+
break;
|
|
74
|
+
case "--help":
|
|
75
|
+
case "-h":
|
|
76
|
+
parsed.help = true;
|
|
77
|
+
break;
|
|
78
|
+
case "--skip-main":
|
|
79
|
+
parsed.includeMain = false;
|
|
80
|
+
break;
|
|
81
|
+
default: throw new Error(`Unknown argument: ${arg}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return parsed;
|
|
85
|
+
}
|
|
86
|
+
function getBackfillSkillFilesUsage() {
|
|
87
|
+
return [
|
|
88
|
+
"Backfill legacy SKILL.md files from skills rows across Dolt branches.",
|
|
89
|
+
"",
|
|
90
|
+
"Usage:",
|
|
91
|
+
" tsx packages/agents-core/scripts/backfill-skill-files.ts [options]",
|
|
92
|
+
"",
|
|
93
|
+
"Options:",
|
|
94
|
+
" --apply Persist and commit changes. Default is dry-run.",
|
|
95
|
+
" --branch <name> Limit execution to a branch. Repeatable.",
|
|
96
|
+
" --skip-main Exclude main.",
|
|
97
|
+
" --continue-on-error Continue processing remaining branches after failures.",
|
|
98
|
+
" --help, -h Show this help text."
|
|
99
|
+
].join("\n");
|
|
100
|
+
}
|
|
101
|
+
async function tableExists(connection, tableName) {
|
|
102
|
+
return (await connection.query(`SELECT 1
|
|
103
|
+
FROM information_schema.tables
|
|
104
|
+
WHERE table_schema = 'public'
|
|
105
|
+
AND table_name = $1
|
|
106
|
+
LIMIT 1`, [tableName])).rows.length > 0;
|
|
107
|
+
}
|
|
108
|
+
async function backfillSkillFilesAcrossAllBranches(options) {
|
|
109
|
+
loadEnvironmentFiles();
|
|
110
|
+
const connectionString = process.env.INKEEP_AGENTS_MANAGE_DATABASE_URL;
|
|
111
|
+
await confirmMigration(connectionString);
|
|
112
|
+
const pool = createAgentsManageDatabasePool({
|
|
113
|
+
connectionString,
|
|
114
|
+
poolSize: 2
|
|
115
|
+
});
|
|
116
|
+
try {
|
|
117
|
+
const targetBranches = (await doltListBranches(drizzle(pool, { schema: manage_schema_exports }))()).filter((branch) => {
|
|
118
|
+
if (!options.includeMain && branch.name === "main") return false;
|
|
119
|
+
if (options.branchNames.length > 0 && !options.branchNames.includes(branch.name)) return false;
|
|
120
|
+
return true;
|
|
121
|
+
});
|
|
122
|
+
if (targetBranches.length === 0) {
|
|
123
|
+
console.log("No matching branches found.");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
console.log(`${options.apply ? "Applying" : "Dry-running"} SKILL.md backfill on ${targetBranches.length} branch(es)\n`);
|
|
127
|
+
let changedBranches = 0;
|
|
128
|
+
let noopBranches = 0;
|
|
129
|
+
let skippedBranches = 0;
|
|
130
|
+
let failedBranches = 0;
|
|
131
|
+
let insertedRows = 0;
|
|
132
|
+
for (const branch of targetBranches) {
|
|
133
|
+
const connection = await pool.connect();
|
|
134
|
+
const branchDb = drizzle(connection, { schema: manage_schema_exports });
|
|
135
|
+
try {
|
|
136
|
+
await connection.query("SELECT DOLT_CHECKOUT($1)", [branch.name]);
|
|
137
|
+
const hasSkillsTable = await tableExists(connection, "skills");
|
|
138
|
+
const hasSkillFilesTable = await tableExists(connection, "skill_files");
|
|
139
|
+
if (!hasSkillsTable || !hasSkillFilesTable) {
|
|
140
|
+
skippedBranches += 1;
|
|
141
|
+
console.log(`Branch "${branch.name}": skipped (missing skills or skill_files table)`);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const missingRows = buildMissingSkillFileRows(await branchDb.select({
|
|
145
|
+
tenantId: skills.tenantId,
|
|
146
|
+
projectId: skills.projectId,
|
|
147
|
+
id: skills.id,
|
|
148
|
+
name: skills.name,
|
|
149
|
+
description: skills.description,
|
|
150
|
+
content: skills.content,
|
|
151
|
+
metadata: skills.metadata,
|
|
152
|
+
createdAt: skills.createdAt,
|
|
153
|
+
updatedAt: skills.updatedAt
|
|
154
|
+
}).from(skills), await branchDb.select({
|
|
155
|
+
tenantId: skillFiles.tenantId,
|
|
156
|
+
projectId: skillFiles.projectId,
|
|
157
|
+
skillId: skillFiles.skillId
|
|
158
|
+
}).from(skillFiles).where(eq(skillFiles.filePath, SKILL_ENTRY_FILE_PATH)));
|
|
159
|
+
if (missingRows.length === 0) {
|
|
160
|
+
noopBranches += 1;
|
|
161
|
+
console.log(`Branch "${branch.name}": no changes`);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (options.apply) {
|
|
165
|
+
await branchDb.insert(skillFiles).values(missingRows).onConflictDoNothing();
|
|
166
|
+
await connection.query("SELECT DOLT_COMMIT('-a', '-m', $1, '--author', $2)", [DEFAULT_COMMIT_MESSAGE, `${DEFAULT_AUTHOR.name} <${DEFAULT_AUTHOR.email}>`]);
|
|
167
|
+
console.log(`Branch "${branch.name}": inserted ${missingRows.length} SKILL.md file(s)`);
|
|
168
|
+
} else console.log(`Branch "${branch.name}": would insert ${missingRows.length} SKILL.md file(s)`);
|
|
169
|
+
changedBranches += 1;
|
|
170
|
+
insertedRows += missingRows.length;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
failedBranches += 1;
|
|
173
|
+
try {
|
|
174
|
+
await doltReset(branchDb)({ hard: true });
|
|
175
|
+
} catch {}
|
|
176
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
177
|
+
console.error(`Branch "${branch.name}": failed`);
|
|
178
|
+
console.error(` ${message}`);
|
|
179
|
+
if (!options.continueOnError) throw error;
|
|
180
|
+
} finally {
|
|
181
|
+
try {
|
|
182
|
+
await connection.query("SELECT DOLT_CHECKOUT('main')");
|
|
183
|
+
} catch {}
|
|
184
|
+
connection.release();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
console.log("");
|
|
188
|
+
console.log(`Summary: ${changedBranches} changed, ${noopBranches} no-op, ${skippedBranches} skipped, ${failedBranches} failed, ${insertedRows} SKILL.md file(s) ${options.apply ? "inserted" : "would be inserted"}`);
|
|
189
|
+
if (failedBranches > 0) process.exitCode = 1;
|
|
190
|
+
} finally {
|
|
191
|
+
await pool.end();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async function main(argv = process.argv.slice(2)) {
|
|
195
|
+
const parsedArgs = parseBackfillSkillFilesArgs(argv);
|
|
196
|
+
if (parsedArgs.help) {
|
|
197
|
+
console.log(getBackfillSkillFilesUsage());
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
await backfillSkillFilesAcrossAllBranches({
|
|
201
|
+
apply: parsedArgs.apply,
|
|
202
|
+
branchNames: parsedArgs.branchNames,
|
|
203
|
+
continueOnError: parsedArgs.continueOnError,
|
|
204
|
+
includeMain: parsedArgs.includeMain
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
//#endregion
|
|
209
|
+
export { backfillSkillFilesAcrossAllBranches, buildLegacySkillFileId, buildMissingSkillFileRows, getBackfillSkillFilesUsage, main, parseBackfillSkillFilesArgs };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/dolt/run-sql-file-on-all-branches.d.ts
|
|
2
|
+
type RunSqlFileOnAllBranchesArgs = {
|
|
3
|
+
apply: boolean;
|
|
4
|
+
branchNames: string[];
|
|
5
|
+
continueOnError: boolean;
|
|
6
|
+
filePath?: string;
|
|
7
|
+
help: boolean;
|
|
8
|
+
includeMain: boolean;
|
|
9
|
+
};
|
|
10
|
+
declare function buildDefaultCommitMessage(sqlFilePath: string): string;
|
|
11
|
+
declare function resolveSqlFilePath(inputPath: string, cwd?: string): string;
|
|
12
|
+
declare function parseRunSqlFileOnAllBranchesArgs(argv: string[]): RunSqlFileOnAllBranchesArgs;
|
|
13
|
+
declare function getRunSqlFileOnAllBranchesUsage(): string;
|
|
14
|
+
type RunSqlFileOnAllBranchesOptions = {
|
|
15
|
+
apply: boolean;
|
|
16
|
+
author: {
|
|
17
|
+
email: string;
|
|
18
|
+
name: string;
|
|
19
|
+
};
|
|
20
|
+
branchNames: string[];
|
|
21
|
+
commitMessage: string;
|
|
22
|
+
continueOnError: boolean;
|
|
23
|
+
includeMain: boolean;
|
|
24
|
+
sqlFilePath: string;
|
|
25
|
+
};
|
|
26
|
+
declare function runSqlFileOnAllBranches(options: RunSqlFileOnAllBranchesOptions): Promise<void>;
|
|
27
|
+
declare function main(argv?: string[]): Promise<void>;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { RunSqlFileOnAllBranchesArgs, buildDefaultCommitMessage, getRunSqlFileOnAllBranchesUsage, main, parseRunSqlFileOnAllBranchesArgs, resolveSqlFilePath, runSqlFileOnAllBranches };
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { manage_schema_exports } from "../db/manage/manage-schema.js";
|
|
2
|
+
import { loadEnvironmentFiles } from "../env.js";
|
|
3
|
+
import { createAgentsManageDatabasePool } from "../db/manage/manage-client.js";
|
|
4
|
+
import { doltReset, doltStatus } from "./commit.js";
|
|
5
|
+
import { doltListBranches } from "./branch.js";
|
|
6
|
+
import { confirmMigration } from "../db/utils.js";
|
|
7
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { drizzle } from "drizzle-orm/node-postgres";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
|
|
12
|
+
//#region src/dolt/run-sql-file-on-all-branches.ts
|
|
13
|
+
const DEFAULT_AUTHOR = {
|
|
14
|
+
name: "migration-script",
|
|
15
|
+
email: "migration@inkeep.com"
|
|
16
|
+
};
|
|
17
|
+
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
18
|
+
const repoRoot = path.resolve(packageRoot, "..", "..");
|
|
19
|
+
function buildDefaultCommitMessage(sqlFilePath) {
|
|
20
|
+
return `Apply backfill SQL from ${path.basename(sqlFilePath)}`;
|
|
21
|
+
}
|
|
22
|
+
function resolveSqlFilePath(inputPath, cwd = process.cwd()) {
|
|
23
|
+
const candidates = path.isAbsolute(inputPath) ? [inputPath] : [
|
|
24
|
+
path.resolve(cwd, inputPath),
|
|
25
|
+
path.resolve(packageRoot, inputPath),
|
|
26
|
+
path.resolve(repoRoot, inputPath)
|
|
27
|
+
];
|
|
28
|
+
for (const candidate of candidates) if (existsSync(candidate)) return candidate;
|
|
29
|
+
throw new Error(`SQL file not found: ${inputPath}`);
|
|
30
|
+
}
|
|
31
|
+
function readNextArg(argv, index, flag) {
|
|
32
|
+
const value = argv[index + 1];
|
|
33
|
+
if (!value || value.startsWith("--")) throw new Error(`Missing value for ${flag}`);
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
function parseRunSqlFileOnAllBranchesArgs(argv) {
|
|
37
|
+
const parsed = {
|
|
38
|
+
apply: false,
|
|
39
|
+
branchNames: [],
|
|
40
|
+
continueOnError: false,
|
|
41
|
+
help: false,
|
|
42
|
+
includeMain: true
|
|
43
|
+
};
|
|
44
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
45
|
+
const arg = argv[index];
|
|
46
|
+
switch (arg) {
|
|
47
|
+
case "--apply":
|
|
48
|
+
parsed.apply = true;
|
|
49
|
+
break;
|
|
50
|
+
case "--branch":
|
|
51
|
+
parsed.branchNames.push(readNextArg(argv, index, arg));
|
|
52
|
+
index += 1;
|
|
53
|
+
break;
|
|
54
|
+
case "--continue-on-error":
|
|
55
|
+
parsed.continueOnError = true;
|
|
56
|
+
break;
|
|
57
|
+
case "--file":
|
|
58
|
+
case "-f":
|
|
59
|
+
parsed.filePath = readNextArg(argv, index, arg);
|
|
60
|
+
index += 1;
|
|
61
|
+
break;
|
|
62
|
+
case "--help":
|
|
63
|
+
case "-h":
|
|
64
|
+
parsed.help = true;
|
|
65
|
+
break;
|
|
66
|
+
case "--skip-main":
|
|
67
|
+
parsed.includeMain = false;
|
|
68
|
+
break;
|
|
69
|
+
default: throw new Error(`Unknown argument: ${arg}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (!parsed.help && !parsed.filePath) throw new Error("Missing required argument: --file <path-to-sql>");
|
|
73
|
+
return parsed;
|
|
74
|
+
}
|
|
75
|
+
function getRunSqlFileOnAllBranchesUsage() {
|
|
76
|
+
return [
|
|
77
|
+
"Run a SQL backfill file across Dolt branches.",
|
|
78
|
+
"",
|
|
79
|
+
"Usage:",
|
|
80
|
+
" tsx packages/agents-core/scripts/run-manage-backfill-on-all-branches.ts --file <path> [options]",
|
|
81
|
+
"",
|
|
82
|
+
"Options:",
|
|
83
|
+
" --apply Persist and commit changes. Default is dry-run.",
|
|
84
|
+
" --file, -f <path> SQL file to execute.",
|
|
85
|
+
" --branch <name> Limit execution to a branch. Repeatable.",
|
|
86
|
+
" --skip-main Exclude main.",
|
|
87
|
+
" --continue-on-error Continue processing remaining branches after failures.",
|
|
88
|
+
" --help, -h Show this help text."
|
|
89
|
+
].join("\n");
|
|
90
|
+
}
|
|
91
|
+
async function runSqlFileOnAllBranches(options) {
|
|
92
|
+
loadEnvironmentFiles();
|
|
93
|
+
const connectionString = process.env.INKEEP_AGENTS_MANAGE_DATABASE_URL;
|
|
94
|
+
await confirmMigration(connectionString);
|
|
95
|
+
const resolvedSqlFilePath = resolveSqlFilePath(options.sqlFilePath);
|
|
96
|
+
const sqlFileContents = readFileSync(resolvedSqlFilePath, "utf8").trim();
|
|
97
|
+
if (!sqlFileContents) throw new Error(`SQL file is empty: ${resolvedSqlFilePath}`);
|
|
98
|
+
const pool = createAgentsManageDatabasePool({
|
|
99
|
+
connectionString,
|
|
100
|
+
poolSize: 2
|
|
101
|
+
});
|
|
102
|
+
try {
|
|
103
|
+
const targetBranches = (await doltListBranches(drizzle(pool, { schema: manage_schema_exports }))()).filter((branch) => {
|
|
104
|
+
if (!options.includeMain && branch.name === "main") return false;
|
|
105
|
+
if (options.branchNames.length > 0 && !options.branchNames.includes(branch.name)) return false;
|
|
106
|
+
return true;
|
|
107
|
+
});
|
|
108
|
+
if (targetBranches.length === 0) {
|
|
109
|
+
console.log("No matching branches found.");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
console.log(`${options.apply ? "Applying" : "Dry-running"} ${path.basename(resolvedSqlFilePath)} on ${targetBranches.length} branch(es)\n`);
|
|
113
|
+
let changedBranches = 0;
|
|
114
|
+
let noopBranches = 0;
|
|
115
|
+
let failedBranches = 0;
|
|
116
|
+
for (const branch of targetBranches) {
|
|
117
|
+
const connection = await pool.connect();
|
|
118
|
+
const branchDb = drizzle(connection, { schema: manage_schema_exports });
|
|
119
|
+
try {
|
|
120
|
+
await connection.query("SELECT DOLT_CHECKOUT($1)", [branch.name]);
|
|
121
|
+
await connection.query(sqlFileContents);
|
|
122
|
+
const status = await doltStatus(branchDb)();
|
|
123
|
+
if (status.length === 0) {
|
|
124
|
+
noopBranches += 1;
|
|
125
|
+
console.log(`Branch "${branch.name}": no changes`);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (options.apply) {
|
|
129
|
+
await connection.query("SELECT DOLT_COMMIT('-a', '-m', $1, '--author', $2)", [options.commitMessage, `${options.author.name} <${options.author.email}>`]);
|
|
130
|
+
console.log(`Branch "${branch.name}": applied and committed`);
|
|
131
|
+
} else {
|
|
132
|
+
await doltReset(branchDb)({ hard: true });
|
|
133
|
+
console.log(`Branch "${branch.name}": would change (${status.length} tracked change(s))`);
|
|
134
|
+
}
|
|
135
|
+
changedBranches += 1;
|
|
136
|
+
} catch (error) {
|
|
137
|
+
failedBranches += 1;
|
|
138
|
+
try {
|
|
139
|
+
await doltReset(branchDb)({ hard: true });
|
|
140
|
+
} catch {}
|
|
141
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
142
|
+
console.error(`Branch "${branch.name}": failed`);
|
|
143
|
+
console.error(` ${message}`);
|
|
144
|
+
if (!options.continueOnError) throw error;
|
|
145
|
+
} finally {
|
|
146
|
+
try {
|
|
147
|
+
await connection.query("SELECT DOLT_CHECKOUT('main')");
|
|
148
|
+
} catch {}
|
|
149
|
+
connection.release();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
console.log("");
|
|
153
|
+
console.log(`Summary: ${changedBranches} changed, ${noopBranches} no-op, ${failedBranches} failed`);
|
|
154
|
+
if (failedBranches > 0) process.exitCode = 1;
|
|
155
|
+
} finally {
|
|
156
|
+
await pool.end();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function main(argv = process.argv.slice(2)) {
|
|
160
|
+
const parsedArgs = parseRunSqlFileOnAllBranchesArgs(argv);
|
|
161
|
+
if (parsedArgs.help) {
|
|
162
|
+
console.log(getRunSqlFileOnAllBranchesUsage());
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
await runSqlFileOnAllBranches({
|
|
166
|
+
apply: parsedArgs.apply,
|
|
167
|
+
author: DEFAULT_AUTHOR,
|
|
168
|
+
branchNames: parsedArgs.branchNames,
|
|
169
|
+
commitMessage: buildDefaultCommitMessage(parsedArgs.filePath ?? "backfill.sql"),
|
|
170
|
+
continueOnError: parsedArgs.continueOnError,
|
|
171
|
+
includeMain: parsedArgs.includeMain,
|
|
172
|
+
sqlFilePath: parsedArgs.filePath ?? ""
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
//#endregion
|
|
177
|
+
export { buildDefaultCommitMessage, getRunSqlFileOnAllBranchesUsage, main, parseRunSqlFileOnAllBranchesArgs, resolveSqlFilePath, runSqlFileOnAllBranches };
|