terse-cli 0.1.16 → 0.1.18
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/README.md +4 -4
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +6 -9
- package/dist/api.js.map +1 -1
- package/dist/assertProjectRoot.d.ts +3 -2
- package/dist/assertProjectRoot.d.ts.map +1 -1
- package/dist/assertProjectRoot.js +6 -9
- package/dist/assertProjectRoot.js.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +4 -4
- package/dist/auth.js.map +1 -1
- package/dist/deploy.d.ts +2 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +19 -23
- package/dist/deploy.js.map +1 -1
- package/dist/generate.d.ts +2 -1
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +59 -33
- package/dist/generate.js.map +1 -1
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +2 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +30 -58
- package/dist/init.js.map +1 -1
- package/dist/integrate.d.ts.map +1 -1
- package/dist/integrate.js +8 -12
- package/dist/integrate.js.map +1 -1
- package/dist/integrationApi.d.ts +2 -2
- package/dist/integrationApi.d.ts.map +1 -1
- package/dist/integrationApi.js.map +1 -1
- package/dist/loadJob.d.ts +4 -3
- package/dist/loadJob.d.ts.map +1 -1
- package/dist/loadJob.js +8 -56
- package/dist/loadJob.js.map +1 -1
- package/dist/providers/LanguageProvider.d.ts +31 -0
- package/dist/providers/LanguageProvider.d.ts.map +1 -0
- package/dist/providers/LanguageProvider.js +2 -0
- package/dist/providers/LanguageProvider.js.map +1 -0
- package/dist/providers/codegenTypes.d.ts +119 -0
- package/dist/providers/codegenTypes.d.ts.map +1 -0
- package/dist/providers/codegenTypes.js +2 -0
- package/dist/providers/codegenTypes.js.map +1 -0
- package/dist/providers/python/PythonProvider.d.ts +33 -0
- package/dist/providers/python/PythonProvider.d.ts.map +1 -0
- package/dist/providers/python/PythonProvider.js +362 -0
- package/dist/providers/python/PythonProvider.js.map +1 -0
- package/dist/providers/python/preparePythonCodegenData.d.ts +89 -0
- package/dist/providers/python/preparePythonCodegenData.d.ts.map +1 -0
- package/dist/providers/python/preparePythonCodegenData.js +359 -0
- package/dist/providers/python/preparePythonCodegenData.js.map +1 -0
- package/dist/providers/python/pythonTemplateEngine.d.ts +3 -0
- package/dist/providers/python/pythonTemplateEngine.d.ts.map +1 -0
- package/dist/providers/python/pythonTemplateEngine.js +30 -0
- package/dist/providers/python/pythonTemplateEngine.js.map +1 -0
- package/dist/providers/resolveProvider.d.ts +8 -0
- package/dist/providers/resolveProvider.d.ts.map +1 -0
- package/dist/providers/resolveProvider.js +47 -0
- package/dist/providers/resolveProvider.js.map +1 -0
- package/dist/providers/shared/sessionStream.d.ts +24 -0
- package/dist/providers/shared/sessionStream.d.ts.map +1 -0
- package/dist/providers/shared/sessionStream.js +157 -0
- package/dist/providers/shared/sessionStream.js.map +1 -0
- package/dist/providers/shared/shellUtils.d.ts +13 -0
- package/dist/providers/shared/shellUtils.d.ts.map +1 -0
- package/dist/providers/shared/shellUtils.js +69 -0
- package/dist/providers/shared/shellUtils.js.map +1 -0
- package/dist/providers/templateUtils.d.ts +7 -0
- package/dist/providers/templateUtils.d.ts.map +1 -0
- package/dist/providers/templateUtils.js +30 -0
- package/dist/providers/templateUtils.js.map +1 -0
- package/dist/providers/typescript/TypeScriptProvider.d.ts +33 -0
- package/dist/providers/typescript/TypeScriptProvider.d.ts.map +1 -0
- package/dist/providers/typescript/TypeScriptProvider.js +160 -0
- package/dist/providers/typescript/TypeScriptProvider.js.map +1 -0
- package/dist/providers/typescript/prepareCodegenData.d.ts +144 -0
- package/dist/providers/typescript/prepareCodegenData.d.ts.map +1 -0
- package/dist/providers/typescript/prepareCodegenData.js +751 -0
- package/dist/providers/typescript/prepareCodegenData.js.map +1 -0
- package/dist/providers/typescript/templateEngine.d.ts +3 -0
- package/dist/providers/typescript/templateEngine.d.ts.map +1 -0
- package/dist/providers/typescript/templateEngine.js +37 -0
- package/dist/providers/typescript/templateEngine.js.map +1 -0
- package/dist/run.d.ts +2 -11
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +7 -194
- package/dist/run.js.map +1 -1
- package/dist/shared/ToolDisplayUtils.d.ts.map +1 -1
- package/dist/shared/ToolDisplayUtils.js +13 -1
- package/dist/shared/ToolDisplayUtils.js.map +1 -1
- package/dist/shared/types.d.ts +912 -107
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/test.d.ts +2 -1
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +12 -12
- package/dist/test.js.map +1 -1
- package/dist/util.d.ts +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js.map +1 -1
- package/package.json +13 -9
- package/templates/python/codegen/generated.hbs +7 -0
- package/templates/python/codegen/partials/attio-list-objects-method.hbs +8 -0
- package/templates/python/codegen/partials/attio-object-types.hbs +23 -0
- package/templates/python/codegen/partials/attio-query-records-method.hbs +45 -0
- package/templates/python/codegen/partials/attio-section.hbs +110 -0
- package/templates/python/codegen/partials/attio-upsert-record-method.hbs +51 -0
- package/templates/python/codegen/partials/deterministic-tools-section.hbs +308 -0
- package/templates/python/codegen/partials/file-header.hbs +32 -0
- package/templates/python/codegen/partials/schedule-section.hbs +9 -0
- package/templates/python/codegen/partials/slack-section.hbs +178 -0
- package/templates/python/codegen/partials/snowflake-section.hbs +26 -0
- package/templates/python/codegen/partials/tool-name-types.hbs +18 -0
- package/templates/python/init/.python-version.hbs +1 -0
- package/templates/python/init/README.md.hbs +40 -0
- package/templates/python/init/gitignore.hbs +3 -0
- package/templates/python/init/pyproject.toml.hbs +16 -0
- package/templates/python/init/src/main.py.hbs +21 -0
- package/templates/typescript/codegen/generated.hbs +17 -0
- package/templates/typescript/codegen/partials/atlassian-section.hbs +32 -0
- package/templates/typescript/codegen/partials/attio-section.hbs +38 -0
- package/templates/typescript/codegen/partials/datadog-section.hbs +11 -0
- package/templates/typescript/codegen/partials/figma-section.hbs +13 -0
- package/templates/typescript/codegen/partials/github-section.hbs +62 -0
- package/templates/typescript/codegen/partials/gmail-section.hbs +21 -0
- package/templates/typescript/codegen/partials/header.hbs +12 -0
- package/templates/typescript/codegen/partials/launchdarkly-section.hbs +11 -0
- package/templates/typescript/codegen/partials/linear-section.hbs +27 -0
- package/templates/typescript/codegen/partials/notion-section.hbs +15 -0
- package/templates/typescript/codegen/partials/posthog-section.hbs +11 -0
- package/templates/typescript/codegen/partials/resource-class.hbs +9 -0
- package/templates/typescript/codegen/partials/slack-section.hbs +22 -0
- package/templates/typescript/codegen/partials/snowflake-section.hbs +9 -0
- package/templates/typescript/codegen/partials/system-section.hbs +18 -0
- package/templates/typescript/codegen/partials/tools-section.hbs +69 -0
- package/templates/typescript/codegen/partials/workos-section.hbs +53 -0
- package/templates/typescript/init/env.example.hbs +1 -0
- package/templates/{package.json.tmpl → typescript/init/package.json.hbs} +1 -1
- package/templates/{src/index.ts.tmpl → typescript/init/src/index.ts.hbs} +1 -3
- /package/templates/{env.example.tmpl → python/init/env.example.hbs} +0 -0
- /package/templates/{.claude/settings.json.tmpl → typescript/init/.claude/settings.json.hbs} +0 -0
- /package/templates/{gitignore.tmpl → typescript/init/gitignore.hbs} +0 -0
- /package/templates/{tsconfig.json.tmpl → typescript/init/tsconfig.json.hbs} +0 -0
|
@@ -0,0 +1,751 @@
|
|
|
1
|
+
import { toolsWithIntegrationId } from "terse-types";
|
|
2
|
+
export function toPascalCase(value) {
|
|
3
|
+
return value
|
|
4
|
+
.replace(/[^a-zA-Z0-9]+/g, " ")
|
|
5
|
+
.trim()
|
|
6
|
+
.split(/\s+/)
|
|
7
|
+
.filter(Boolean)
|
|
8
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
9
|
+
.join("");
|
|
10
|
+
}
|
|
11
|
+
export function escapeString(value) {
|
|
12
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
13
|
+
}
|
|
14
|
+
export function toGeneratedIdentifier(raw, fallback) {
|
|
15
|
+
let name = toPascalCase(raw || fallback);
|
|
16
|
+
if (!name)
|
|
17
|
+
name = fallback;
|
|
18
|
+
if (/^\d/.test(name))
|
|
19
|
+
name = `_${name}`;
|
|
20
|
+
return name;
|
|
21
|
+
}
|
|
22
|
+
function toCamelCase(value) {
|
|
23
|
+
const pascal = toPascalCase(value);
|
|
24
|
+
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
25
|
+
}
|
|
26
|
+
function toolNameToInterfaceName(name) {
|
|
27
|
+
return (name
|
|
28
|
+
.split("_")
|
|
29
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
30
|
+
.join("") + "Params");
|
|
31
|
+
}
|
|
32
|
+
function buildResourceClassContext(className, fields, staticNameField, items) {
|
|
33
|
+
const constructorParams = fields.map(field => `public readonly ${field.classField}: ${field.type}`).join(", ");
|
|
34
|
+
const entries = [];
|
|
35
|
+
const usedNames = new Set();
|
|
36
|
+
for (const item of items) {
|
|
37
|
+
const source = item;
|
|
38
|
+
let name = toPascalCase(String(source[staticNameField] || "Unknown"));
|
|
39
|
+
if (!name || /^\d/.test(name))
|
|
40
|
+
name = `_${name}`;
|
|
41
|
+
while (usedNames.has(name))
|
|
42
|
+
name += "_";
|
|
43
|
+
usedNames.add(name);
|
|
44
|
+
const argsText = fields
|
|
45
|
+
.map(field => {
|
|
46
|
+
const value = source[field.sourceField];
|
|
47
|
+
if (typeof value === "number")
|
|
48
|
+
return String(value);
|
|
49
|
+
return `"${escapeString(String(value ?? ""))}"`;
|
|
50
|
+
})
|
|
51
|
+
.join(", ");
|
|
52
|
+
entries.push({
|
|
53
|
+
staticName: name,
|
|
54
|
+
argsText
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
className,
|
|
59
|
+
constructorParams,
|
|
60
|
+
items: entries
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function sectionData(imports, data) {
|
|
64
|
+
return { imports: new Set(imports), data };
|
|
65
|
+
}
|
|
66
|
+
function isProbablyAttioMultiValue(attr) {
|
|
67
|
+
const slug = (attr.api_slug || "").toLowerCase();
|
|
68
|
+
const type = (attr.type || "").toLowerCase();
|
|
69
|
+
return (type.includes("multi") ||
|
|
70
|
+
type.includes("array") ||
|
|
71
|
+
type.includes("list") ||
|
|
72
|
+
slug === "email_addresses" ||
|
|
73
|
+
slug === "domains" ||
|
|
74
|
+
slug === "phone_numbers" ||
|
|
75
|
+
slug === "social_profiles" ||
|
|
76
|
+
slug === "links" ||
|
|
77
|
+
slug === "tags" ||
|
|
78
|
+
slug.endsWith("_addresses") ||
|
|
79
|
+
slug.endsWith("_ids"));
|
|
80
|
+
}
|
|
81
|
+
export function attioAttributeBaseType(attr) {
|
|
82
|
+
const slug = (attr.api_slug || "").toLowerCase();
|
|
83
|
+
const type = (attr.type || "").toLowerCase();
|
|
84
|
+
if (type.includes("checkbox") || type.includes("boolean"))
|
|
85
|
+
return "boolean";
|
|
86
|
+
if (type.includes("number") || type.includes("currency") || type.includes("rating") || type.includes("percent")) {
|
|
87
|
+
return "number";
|
|
88
|
+
}
|
|
89
|
+
if (type.includes("date") || type.includes("time"))
|
|
90
|
+
return "string";
|
|
91
|
+
if (type.includes("email") ||
|
|
92
|
+
type.includes("domain") ||
|
|
93
|
+
type.includes("phone") ||
|
|
94
|
+
type.includes("url") ||
|
|
95
|
+
type.includes("select") ||
|
|
96
|
+
type.includes("status") ||
|
|
97
|
+
type.includes("text") ||
|
|
98
|
+
type.includes("string") ||
|
|
99
|
+
type.includes("name")) {
|
|
100
|
+
return "string";
|
|
101
|
+
}
|
|
102
|
+
if (type.includes("location") || type.includes("address") || type.includes("reference") || type.includes("record") || type.includes("actor")) {
|
|
103
|
+
return "Record<string, unknown>";
|
|
104
|
+
}
|
|
105
|
+
if (slug === "email_addresses" || slug === "domains" || slug === "phone_numbers" || slug === "name") {
|
|
106
|
+
return "string";
|
|
107
|
+
}
|
|
108
|
+
return "unknown";
|
|
109
|
+
}
|
|
110
|
+
function attioAttributeInputTsType(attr) {
|
|
111
|
+
const baseType = attioAttributeBaseType(attr);
|
|
112
|
+
if (!isProbablyAttioMultiValue(attr))
|
|
113
|
+
return baseType;
|
|
114
|
+
return baseType.includes("|") ? `(${baseType})[]` : `${baseType}[]`;
|
|
115
|
+
}
|
|
116
|
+
function attioAttributeRecordTsType(attr) {
|
|
117
|
+
const baseType = attioAttributeBaseType(attr);
|
|
118
|
+
if (!isProbablyAttioMultiValue(attr))
|
|
119
|
+
return baseType;
|
|
120
|
+
return baseType.includes("|") ? `(${baseType})[]` : `${baseType}[]`;
|
|
121
|
+
}
|
|
122
|
+
function renderAttioObjectValueShape(attributes, mode) {
|
|
123
|
+
if (attributes.length === 0)
|
|
124
|
+
return "Record<string, unknown>";
|
|
125
|
+
const lines = attributes.map(attr => {
|
|
126
|
+
const valueType = mode === "input" ? attioAttributeInputTsType(attr) : attioAttributeRecordTsType(attr);
|
|
127
|
+
return ` "${escapeString(attr.api_slug || "")}"?: ${valueType}`;
|
|
128
|
+
});
|
|
129
|
+
return `{\n${lines.join("\n")}\n}`;
|
|
130
|
+
}
|
|
131
|
+
function toolIntegrationToIntegrationType(toolIntegration) {
|
|
132
|
+
switch (toolIntegration) {
|
|
133
|
+
case "jira":
|
|
134
|
+
case "confluence":
|
|
135
|
+
return "atlassian";
|
|
136
|
+
default:
|
|
137
|
+
return toolIntegration;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function renderStringLiteralUnion(values) {
|
|
141
|
+
if (values.length === 0)
|
|
142
|
+
return "never";
|
|
143
|
+
return values.map(value => `"${escapeString(value)}"`).join(" | ");
|
|
144
|
+
}
|
|
145
|
+
export function buildSkillToolTypeForIntegration(tools, integrationType) {
|
|
146
|
+
const toolNames = tools
|
|
147
|
+
.filter(tool => toolIntegrationToIntegrationType(tool.integration.toLowerCase()) === integrationType)
|
|
148
|
+
.filter(tool => !tool.isReadOnly || tool.supportsApproval)
|
|
149
|
+
.map(tool => tool.name)
|
|
150
|
+
.sort();
|
|
151
|
+
return renderStringLiteralUnion(toolNames);
|
|
152
|
+
}
|
|
153
|
+
function prepareGitHubSection(instances, tools) {
|
|
154
|
+
if (instances.length === 0)
|
|
155
|
+
return sectionData([]);
|
|
156
|
+
const inst = instances[0];
|
|
157
|
+
const imports = ["GitHubConfig", "GitHubEventType", "TypedTrigger", "TypedSkill", "GithubPRInputEvent", "GithubPushInputEvent", "GithubInputEvent"];
|
|
158
|
+
const skillToolType = buildSkillToolTypeForIntegration(tools, "github");
|
|
159
|
+
const repositoriesWithFullName = inst.repositories.map(repo => {
|
|
160
|
+
const owner = repo.owner || "UnknownOwner";
|
|
161
|
+
const fullName = repo.owner && repo.name ? `${repo.owner}/${repo.name}` : repo.name;
|
|
162
|
+
return { ...repo, owner, fullName };
|
|
163
|
+
});
|
|
164
|
+
const ownerEntries = new Map();
|
|
165
|
+
const usedOwnerNames = new Set();
|
|
166
|
+
for (const repo of repositoriesWithFullName) {
|
|
167
|
+
if (!ownerEntries.has(repo.owner)) {
|
|
168
|
+
let ownerStaticName = toGeneratedIdentifier(repo.owner, "UnknownOwner");
|
|
169
|
+
while (usedOwnerNames.has(ownerStaticName))
|
|
170
|
+
ownerStaticName += "_";
|
|
171
|
+
usedOwnerNames.add(ownerStaticName);
|
|
172
|
+
ownerEntries.set(repo.owner, { staticName: ownerStaticName, repos: [] });
|
|
173
|
+
}
|
|
174
|
+
ownerEntries.get(repo.owner).repos.push(repo);
|
|
175
|
+
}
|
|
176
|
+
const owners = Array.from(ownerEntries.entries()).map(([name, data]) => ({
|
|
177
|
+
name,
|
|
178
|
+
staticName: data.staticName
|
|
179
|
+
}));
|
|
180
|
+
const repoGroups = Array.from(ownerEntries.values()).map(group => {
|
|
181
|
+
const usedRepoNames = new Set();
|
|
182
|
+
return {
|
|
183
|
+
ownerStaticName: group.staticName,
|
|
184
|
+
repos: group.repos.map(repo => {
|
|
185
|
+
let staticName = toGeneratedIdentifier(repo.name, "Repos");
|
|
186
|
+
while (usedRepoNames.has(staticName))
|
|
187
|
+
staticName += "_";
|
|
188
|
+
usedRepoNames.add(staticName);
|
|
189
|
+
return {
|
|
190
|
+
id: repo.id,
|
|
191
|
+
name: repo.name,
|
|
192
|
+
fullName: repo.fullName,
|
|
193
|
+
staticName
|
|
194
|
+
};
|
|
195
|
+
})
|
|
196
|
+
};
|
|
197
|
+
});
|
|
198
|
+
return sectionData(imports, {
|
|
199
|
+
id: inst.integration.id,
|
|
200
|
+
skillToolType,
|
|
201
|
+
owners,
|
|
202
|
+
repoGroups
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function prepareGmailSection(instances, tools) {
|
|
206
|
+
if (instances.length === 0)
|
|
207
|
+
return sectionData([]);
|
|
208
|
+
return sectionData(["GmailConfig", "GmailOutputConfig", "GmailDraftOutputConfig", "TypedSkill", "GmailEventType"], {
|
|
209
|
+
id: instances[0].id,
|
|
210
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "gmail")
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
function prepareSlackSection(instances, tools) {
|
|
214
|
+
if (instances.length === 0)
|
|
215
|
+
return sectionData([]);
|
|
216
|
+
const inst = instances[0];
|
|
217
|
+
return sectionData(["SlackConfig", "SlackOutputConfig", "TypedSkill", "SlackEventType", "TypedTrigger", "SlackMessageEvent"], {
|
|
218
|
+
id: inst.id,
|
|
219
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "slack"),
|
|
220
|
+
channelClass: buildResourceClassContext("SlackChannel", [
|
|
221
|
+
{ classField: "channelId", type: "string", sourceField: "id" },
|
|
222
|
+
{ classField: "name", type: "string", sourceField: "name" }
|
|
223
|
+
], "name", inst.channels)
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
function prepareFigmaSection(instances) {
|
|
227
|
+
if (instances.length === 0)
|
|
228
|
+
return sectionData([]);
|
|
229
|
+
return sectionData(["FigmaConfig", "FigmaEventType"], { id: instances[0].id });
|
|
230
|
+
}
|
|
231
|
+
function prepareLinearSection(instances, tools) {
|
|
232
|
+
if (instances.length === 0)
|
|
233
|
+
return sectionData([]);
|
|
234
|
+
const inst = instances[0];
|
|
235
|
+
return sectionData(["LinearInputConfig", "LinearOutputConfig", "TypedSkill", "LinearEventType"], {
|
|
236
|
+
id: inst.id,
|
|
237
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "linear"),
|
|
238
|
+
teamClass: buildResourceClassContext("LinearTeam", [
|
|
239
|
+
{ classField: "teamId", type: "string", sourceField: "id" },
|
|
240
|
+
{ classField: "name", type: "string", sourceField: "name" },
|
|
241
|
+
{ classField: "key", type: "string", sourceField: "key" }
|
|
242
|
+
], "name", inst.teams)
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
function prepareAtlassianSection(instances, tools) {
|
|
246
|
+
if (instances.length === 0)
|
|
247
|
+
return sectionData([]);
|
|
248
|
+
const inst = instances[0];
|
|
249
|
+
return sectionData(["JiraConfig", "ConfluenceConfig", "TypedSkill", "JiraEventType"], {
|
|
250
|
+
id: inst.id,
|
|
251
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "atlassian"),
|
|
252
|
+
jiraProjectClass: buildResourceClassContext("JiraProject", [
|
|
253
|
+
{ classField: "projectKey", type: "string", sourceField: "key" },
|
|
254
|
+
{ classField: "projectId", type: "string", sourceField: "id" },
|
|
255
|
+
{ classField: "name", type: "string", sourceField: "name" }
|
|
256
|
+
], "name", inst.jiraProjects),
|
|
257
|
+
confluencePageClass: buildResourceClassContext("ConfluencePage", [
|
|
258
|
+
{ classField: "pageId", type: "string", sourceField: "id" },
|
|
259
|
+
{ classField: "title", type: "string", sourceField: "title" },
|
|
260
|
+
{ classField: "spaceId", type: "string", sourceField: "spaceId" },
|
|
261
|
+
{ classField: "spaceName", type: "string", sourceField: "spaceName" }
|
|
262
|
+
], "title", inst.confluencePages)
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
function prepareNotionSection(instances, tools) {
|
|
266
|
+
if (instances.length === 0)
|
|
267
|
+
return sectionData([]);
|
|
268
|
+
const inst = instances[0];
|
|
269
|
+
return sectionData(["NotionConfig", "TypedSkill"], {
|
|
270
|
+
id: inst.id,
|
|
271
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "notion"),
|
|
272
|
+
databaseClass: buildResourceClassContext("NotionDatabase", [
|
|
273
|
+
{ classField: "databaseId", type: "string", sourceField: "id" },
|
|
274
|
+
{ classField: "title", type: "string", sourceField: "title" }
|
|
275
|
+
], "title", inst.databases),
|
|
276
|
+
pageClass: buildResourceClassContext("NotionPage", [
|
|
277
|
+
{ classField: "pageId", type: "string", sourceField: "id" },
|
|
278
|
+
{ classField: "title", type: "string", sourceField: "title" }
|
|
279
|
+
], "title", inst.pages)
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function preparePosthogSection(instances, tools) {
|
|
283
|
+
if (instances.length === 0)
|
|
284
|
+
return sectionData([]);
|
|
285
|
+
const inst = instances[0];
|
|
286
|
+
return sectionData(["PosthogConfig", "TypedSkill"], {
|
|
287
|
+
id: inst.id,
|
|
288
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "posthog"),
|
|
289
|
+
projectClass: buildResourceClassContext("PosthogProject", [
|
|
290
|
+
{ classField: "projectId", type: "string", sourceField: "id" },
|
|
291
|
+
{ classField: "name", type: "string", sourceField: "name" }
|
|
292
|
+
], "name", inst.projects)
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
function prepareDatadogSection(instances, tools) {
|
|
296
|
+
if (instances.length === 0)
|
|
297
|
+
return sectionData([]);
|
|
298
|
+
const inst = instances[0];
|
|
299
|
+
return sectionData(["DatadogConfig", "TypedSkill"], {
|
|
300
|
+
id: inst.id,
|
|
301
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "datadog"),
|
|
302
|
+
indexClass: buildResourceClassContext("DatadogIndex", [{ classField: "name", type: "string", sourceField: "name" }], "name", inst.indexes)
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
function prepareLaunchDarklySection(instances, tools) {
|
|
306
|
+
if (instances.length === 0)
|
|
307
|
+
return sectionData([]);
|
|
308
|
+
const inst = instances[0];
|
|
309
|
+
return sectionData(["LaunchDarklyConfig", "TypedSkill"], {
|
|
310
|
+
id: inst.id,
|
|
311
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "launchdarkly"),
|
|
312
|
+
projectClass: buildResourceClassContext("LaunchDarklyProject", [
|
|
313
|
+
{ classField: "projectKey", type: "string", sourceField: "key" },
|
|
314
|
+
{ classField: "name", type: "string", sourceField: "name" }
|
|
315
|
+
], "name", inst.projects)
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
function prepareWorkOSSection(instances, tools) {
|
|
319
|
+
if (instances.length === 0)
|
|
320
|
+
return sectionData([]);
|
|
321
|
+
return sectionData([
|
|
322
|
+
"WorkOSInputConfig",
|
|
323
|
+
"WorkOSOutputConfig",
|
|
324
|
+
"WorkOSEventType",
|
|
325
|
+
"TypedSkill",
|
|
326
|
+
"TypedTrigger",
|
|
327
|
+
"WorkOSInputEvent",
|
|
328
|
+
"WorkOSUserInputEvent",
|
|
329
|
+
"WorkOSMembershipInputEvent",
|
|
330
|
+
"WorkOSInvitationInputEvent",
|
|
331
|
+
"WorkOSOrganizationInputEvent"
|
|
332
|
+
], {
|
|
333
|
+
id: instances[0].id,
|
|
334
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "workos")
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
function buildGeneratedAttioObjects(instances) {
|
|
338
|
+
const objects = instances[0]?.objects ?? [];
|
|
339
|
+
const usedNames = new Set();
|
|
340
|
+
return objects.map(object => {
|
|
341
|
+
let staticName = toGeneratedIdentifier(object.singular_noun || object.api_slug || "Object", "AttioObject");
|
|
342
|
+
while (usedNames.has(staticName))
|
|
343
|
+
staticName += "_";
|
|
344
|
+
usedNames.add(staticName);
|
|
345
|
+
const attributes = (object.attributes || []).filter((attr) => !!attr.api_slug);
|
|
346
|
+
const attributeSource = attributes.length === 0
|
|
347
|
+
? "[]"
|
|
348
|
+
: `[\n${attributes
|
|
349
|
+
.map(attr => {
|
|
350
|
+
const fields = [
|
|
351
|
+
`apiSlug: "${escapeString(attr.api_slug)}"`,
|
|
352
|
+
attr.title ? `title: "${escapeString(attr.title)}"` : undefined,
|
|
353
|
+
attr.type ? `type: "${escapeString(attr.type)}"` : undefined,
|
|
354
|
+
attr.is_required !== undefined ? `isRequired: ${attr.is_required ? "true" : "false"}` : undefined,
|
|
355
|
+
attr.is_unique !== undefined ? `isUnique: ${attr.is_unique ? "true" : "false"}` : undefined
|
|
356
|
+
]
|
|
357
|
+
.filter(Boolean)
|
|
358
|
+
.join(", ");
|
|
359
|
+
return ` { ${fields} }`;
|
|
360
|
+
})
|
|
361
|
+
.join(",\n")}\n ]`;
|
|
362
|
+
return {
|
|
363
|
+
staticName,
|
|
364
|
+
apiSlug: object.api_slug,
|
|
365
|
+
singularNoun: object.singular_noun,
|
|
366
|
+
attributeSource,
|
|
367
|
+
recordValuesType: renderAttioObjectValueShape(attributes, "record"),
|
|
368
|
+
inputValuesType: renderAttioObjectValueShape(attributes, "input"),
|
|
369
|
+
attributes
|
|
370
|
+
};
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
function prepareAttioSection(instances, tools) {
|
|
374
|
+
if (instances.length === 0)
|
|
375
|
+
return sectionData([]);
|
|
376
|
+
return sectionData(["AttioOutputConfig", "TypedSkill"], {
|
|
377
|
+
id: instances[0].id,
|
|
378
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "attio"),
|
|
379
|
+
objects: buildGeneratedAttioObjects(instances)
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
function prepareSnowflakeSection(instances, tools) {
|
|
383
|
+
if (instances.length === 0)
|
|
384
|
+
return sectionData([]);
|
|
385
|
+
return sectionData(["SnowflakeOutputConfig", "TypedSkill"], {
|
|
386
|
+
id: instances[0].id,
|
|
387
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "snowflake")
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
function prepareToolsSection(tools, input) {
|
|
391
|
+
if (tools.length === 0)
|
|
392
|
+
return sectionData([]);
|
|
393
|
+
const imports = new Set(["TerseAgent", "ToolInputByName", "ToolOutputByName"]);
|
|
394
|
+
const attioPreludeLines = [];
|
|
395
|
+
const instanceMap = new Map();
|
|
396
|
+
instanceMap.set("slack", input.slack.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
397
|
+
instanceMap.set("github", input.github.map(inst => ({ id: inst.integration.id, displayName: inst.integration.account_name || "" })));
|
|
398
|
+
instanceMap.set("gmail", input.gmail.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
399
|
+
instanceMap.set("figma", input.figma.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
400
|
+
instanceMap.set("linear", input.linear.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
401
|
+
instanceMap.set("jira", input.atlassian.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
402
|
+
instanceMap.set("confluence", input.atlassian.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
403
|
+
instanceMap.set("atlassian", input.atlassian.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
404
|
+
instanceMap.set("notion", input.notion.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
405
|
+
instanceMap.set("posthog", input.posthog.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
406
|
+
instanceMap.set("datadog", input.datadog.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
407
|
+
instanceMap.set("launchdarkly", input.launchdarkly.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
408
|
+
instanceMap.set("workos", input.workos.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
409
|
+
instanceMap.set("attio", input.attio.map(inst => ({ id: inst.id, displayName: inst.displayName })));
|
|
410
|
+
instanceMap.set("snowflake", input.snowflake.map(inst => ({ id: inst.id, displayName: inst.name })));
|
|
411
|
+
const byIntegration = new Map();
|
|
412
|
+
for (const tool of tools) {
|
|
413
|
+
const key = tool.integration.toLowerCase();
|
|
414
|
+
if (!byIntegration.has(key))
|
|
415
|
+
byIntegration.set(key, []);
|
|
416
|
+
byIntegration.get(key).push(tool);
|
|
417
|
+
}
|
|
418
|
+
const hasAutoFillId = (tool) => toolsWithIntegrationId.has(tool.name);
|
|
419
|
+
const normalizeGitHubReposParams = (toolName) => {
|
|
420
|
+
switch (toolName) {
|
|
421
|
+
case "readGitHubFile":
|
|
422
|
+
case "listGitHubPullRequests":
|
|
423
|
+
case "listGitHubDirectory":
|
|
424
|
+
case "listGitHubCommits":
|
|
425
|
+
case "summarizeGitHubPullRequestDiff":
|
|
426
|
+
return "{ ...params, repository: __normalizeGitHubRepos((params as any).repository) }";
|
|
427
|
+
case "searchGitHubCode":
|
|
428
|
+
case "grepGitHubCode":
|
|
429
|
+
return "{ ...params, repositoryNames: __normalizeGitHubReposNames((params as any).repositoryNames) }";
|
|
430
|
+
default:
|
|
431
|
+
return "params";
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
const isAttioTool = (tool) => tool.integration.toLowerCase() === "attio";
|
|
435
|
+
const attioGeneratedObjects = buildGeneratedAttioObjects(input.attio);
|
|
436
|
+
if (tools.some(isAttioTool)) {
|
|
437
|
+
attioPreludeLines.push("type __AttioPrimitive = string | number | boolean | null");
|
|
438
|
+
attioPreludeLines.push("type __AttioStructuredValue = Record<string, unknown>");
|
|
439
|
+
attioPreludeLines.push("type __AttioValue = __AttioPrimitive | __AttioStructuredValue | (__AttioPrimitive | __AttioStructuredValue)[]");
|
|
440
|
+
attioPreludeLines.push("type __AttioFilterShorthand<T> = T extends (infer U)[] ? U | T : T");
|
|
441
|
+
attioPreludeLines.push("type __AttioFilterValue<T> = __AttioFilterShorthand<T> | { $eq?: __AttioFilterShorthand<T>; $contains?: string; $starts_with?: string; $ends_with?: string } | Record<string, unknown>");
|
|
442
|
+
attioPreludeLines.push("type __AttioFilterExpression<TValues extends Record<string, unknown>> = Partial<{ [K in keyof TValues]: __AttioFilterValue<TValues[K]> }> & { $and?: Array<__AttioFilterExpression<TValues>>; $or?: Array<__AttioFilterExpression<TValues>> }");
|
|
443
|
+
attioPreludeLines.push('type __AttioRecordBase = NonNullable<NonNullable<ToolOutputByName["attio_upsert_record"]["records"]>[number]>');
|
|
444
|
+
attioPreludeLines.push('type __AttioRecordWithValues<TValues extends Record<string, unknown>> = Omit<__AttioRecordBase, "values"> & TValues & { values: TValues; attributes: TValues }');
|
|
445
|
+
attioPreludeLines.push("");
|
|
446
|
+
if (attioGeneratedObjects.length > 0) {
|
|
447
|
+
attioPreludeLines.push("export type GeneratedAttioObject =");
|
|
448
|
+
for (const object of attioGeneratedObjects) {
|
|
449
|
+
attioPreludeLines.push(` | typeof AttioObject.${object.staticName}`);
|
|
450
|
+
}
|
|
451
|
+
attioPreludeLines.push("");
|
|
452
|
+
attioPreludeLines.push("export type AttioInputValuesByObject = {");
|
|
453
|
+
for (const object of attioGeneratedObjects) {
|
|
454
|
+
const inputShape = object.attributes.length === 0 ? "Record<string, __AttioValue>" : renderAttioObjectValueShape(object.attributes, "input");
|
|
455
|
+
attioPreludeLines.push(` "${escapeString(object.apiSlug)}": ${inputShape}`);
|
|
456
|
+
}
|
|
457
|
+
attioPreludeLines.push("}");
|
|
458
|
+
attioPreludeLines.push("");
|
|
459
|
+
attioPreludeLines.push("export type AttioRecordValuesByObject = {");
|
|
460
|
+
for (const object of attioGeneratedObjects) {
|
|
461
|
+
const recordShape = object.attributes.length === 0 ? "Record<string, __AttioValue>" : renderAttioObjectValueShape(object.attributes, "record");
|
|
462
|
+
attioPreludeLines.push(` "${escapeString(object.apiSlug)}": ${recordShape}`);
|
|
463
|
+
}
|
|
464
|
+
attioPreludeLines.push("}");
|
|
465
|
+
attioPreludeLines.push("");
|
|
466
|
+
attioPreludeLines.push("export type AttioFilterByObject = {");
|
|
467
|
+
for (const object of attioGeneratedObjects) {
|
|
468
|
+
attioPreludeLines.push(` "${escapeString(object.apiSlug)}": __AttioFilterExpression<AttioRecordValuesByObject["${escapeString(object.apiSlug)}"]>`);
|
|
469
|
+
}
|
|
470
|
+
attioPreludeLines.push("}");
|
|
471
|
+
attioPreludeLines.push("");
|
|
472
|
+
attioPreludeLines.push("export type AttioRecordByObject = {");
|
|
473
|
+
for (const object of attioGeneratedObjects) {
|
|
474
|
+
attioPreludeLines.push(` "${escapeString(object.apiSlug)}": __AttioRecordWithValues<AttioRecordValuesByObject["${escapeString(object.apiSlug)}"]>`);
|
|
475
|
+
}
|
|
476
|
+
attioPreludeLines.push("}");
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
attioPreludeLines.push("export type GeneratedAttioObject = AttioObject<string, Record<string, __AttioValue>, Record<string, __AttioValue>>");
|
|
480
|
+
attioPreludeLines.push("export type AttioInputValuesByObject = Record<string, Record<string, __AttioValue>>");
|
|
481
|
+
attioPreludeLines.push("export type AttioRecordValuesByObject = Record<string, Record<string, __AttioValue>>");
|
|
482
|
+
attioPreludeLines.push("export type AttioFilterByObject = Record<string, __AttioFilterExpression<Record<string, __AttioValue>>>");
|
|
483
|
+
attioPreludeLines.push("export type AttioRecordByObject = Record<string, __AttioRecordWithValues<Record<string, __AttioValue>>>");
|
|
484
|
+
}
|
|
485
|
+
attioPreludeLines.push("");
|
|
486
|
+
attioPreludeLines.push('export type AttioValuesFor<TObject extends GeneratedAttioObject = GeneratedAttioObject> = TObject extends { __inputValues: infer TInputValues } ? TInputValues : AttioInputValuesByObject[TObject["apiSlug"]]');
|
|
487
|
+
attioPreludeLines.push('export type AttioRecordValuesFor<TObject extends GeneratedAttioObject = GeneratedAttioObject> = TObject extends { __recordValues: infer TRecordValues } ? TRecordValues : AttioRecordValuesByObject[TObject["apiSlug"]]');
|
|
488
|
+
attioPreludeLines.push("export type AttioAttributeSlug<TObject extends GeneratedAttioObject = GeneratedAttioObject> = Extract<keyof AttioValuesFor<TObject>, string>");
|
|
489
|
+
attioPreludeLines.push("export type AttioFilterFor<TObject extends GeneratedAttioObject = GeneratedAttioObject> = __AttioFilterExpression<AttioRecordValuesFor<TObject>>");
|
|
490
|
+
attioPreludeLines.push("export type AttioRecordFor<TObject extends GeneratedAttioObject = GeneratedAttioObject> = __AttioRecordWithValues<AttioRecordValuesFor<TObject>>");
|
|
491
|
+
attioPreludeLines.push("export type AttioQueryRecordsParams<TObject extends GeneratedAttioObject = GeneratedAttioObject> = { object: TObject; filter?: AttioFilterFor<TObject> | null; limit?: number | null }");
|
|
492
|
+
attioPreludeLines.push("export type AttioUpsertRecordParams<TObject extends GeneratedAttioObject = GeneratedAttioObject> = { object: TObject; matchingAttribute: AttioAttributeSlug<TObject>; records: AttioValuesFor<TObject>[] }");
|
|
493
|
+
attioPreludeLines.push("export type AttioListObjectsParams = Record<string, never>");
|
|
494
|
+
attioPreludeLines.push('export type AttioQueryRecordsResult<TObject extends GeneratedAttioObject = GeneratedAttioObject> = Omit<ToolOutputByName["attio_query_records"], "records"> & { records: Array<AttioRecordFor<TObject>> }');
|
|
495
|
+
attioPreludeLines.push('export type AttioUpsertRecordResult<TObject extends GeneratedAttioObject = GeneratedAttioObject> = Omit<ToolOutputByName["attio_upsert_record"], "records"> & { records?: Array<AttioRecordFor<TObject>> }');
|
|
496
|
+
attioPreludeLines.push("");
|
|
497
|
+
attioPreludeLines.push("const __attioMetadataKeys = new Set([");
|
|
498
|
+
attioPreludeLines.push(' "active_from",');
|
|
499
|
+
attioPreludeLines.push(' "active_until",');
|
|
500
|
+
attioPreludeLines.push(' "attribute_type",');
|
|
501
|
+
attioPreludeLines.push(' "created_by_actor",');
|
|
502
|
+
attioPreludeLines.push("])");
|
|
503
|
+
attioPreludeLines.push("");
|
|
504
|
+
attioPreludeLines.push("const __attioMultiValueAttributeSlugsByObject: Record<string, readonly string[]> = {");
|
|
505
|
+
for (const object of attioGeneratedObjects) {
|
|
506
|
+
const multiValueSlugs = object.attributes
|
|
507
|
+
.filter(isProbablyAttioMultiValue)
|
|
508
|
+
.map(attr => `"${escapeString(attr.api_slug)}"`)
|
|
509
|
+
.join(", ");
|
|
510
|
+
attioPreludeLines.push(` "${escapeString(object.apiSlug)}": [${multiValueSlugs}],`);
|
|
511
|
+
}
|
|
512
|
+
attioPreludeLines.push("}");
|
|
513
|
+
attioPreludeLines.push("");
|
|
514
|
+
attioPreludeLines.push("function __normalizeAttioObjectSlug(object: unknown): string {");
|
|
515
|
+
attioPreludeLines.push(' if (object && typeof object === "object" && "apiSlug" in (object as Record<string, unknown>)) {');
|
|
516
|
+
attioPreludeLines.push(" const apiSlug = (object as { apiSlug?: unknown }).apiSlug");
|
|
517
|
+
attioPreludeLines.push(' if (typeof apiSlug === "string" && apiSlug.length > 0) return apiSlug');
|
|
518
|
+
attioPreludeLines.push(" }");
|
|
519
|
+
attioPreludeLines.push(' return typeof object === "string" ? object : ""');
|
|
520
|
+
attioPreludeLines.push("}");
|
|
521
|
+
attioPreludeLines.push("");
|
|
522
|
+
attioPreludeLines.push("function __serializeAttioFilter(filter: unknown): string | null {");
|
|
523
|
+
attioPreludeLines.push(" if (filter === undefined || filter === null) return null");
|
|
524
|
+
attioPreludeLines.push(" return JSON.stringify(filter)");
|
|
525
|
+
attioPreludeLines.push("}");
|
|
526
|
+
attioPreludeLines.push("");
|
|
527
|
+
attioPreludeLines.push("function __serializeAttioRecords(records: unknown): string {");
|
|
528
|
+
attioPreludeLines.push(" if (!Array.isArray(records)) return JSON.stringify([])");
|
|
529
|
+
attioPreludeLines.push(' return JSON.stringify(records.filter((record): record is Record<string, unknown> => typeof record === "object" && record !== null && !Array.isArray(record)))');
|
|
530
|
+
attioPreludeLines.push("}");
|
|
531
|
+
attioPreludeLines.push("");
|
|
532
|
+
attioPreludeLines.push("function __isAttioMultiValueAttribute(objectSlug: string, attributeSlug: string): boolean {");
|
|
533
|
+
attioPreludeLines.push(" return (__attioMultiValueAttributeSlugsByObject[objectSlug] || []).includes(attributeSlug)");
|
|
534
|
+
attioPreludeLines.push("}");
|
|
535
|
+
attioPreludeLines.push("");
|
|
536
|
+
attioPreludeLines.push("function __flattenAttioLeafValue(value: unknown): unknown {");
|
|
537
|
+
attioPreludeLines.push(" if (value === null || value === undefined) return value");
|
|
538
|
+
attioPreludeLines.push(" if (Array.isArray(value)) return value.map(entry => __flattenAttioLeafValue(entry))");
|
|
539
|
+
attioPreludeLines.push(' if (typeof value !== "object") return value');
|
|
540
|
+
attioPreludeLines.push(" const rawObject = value as Record<string, unknown>");
|
|
541
|
+
attioPreludeLines.push(' if (typeof rawObject.full_name === "string") return rawObject.full_name');
|
|
542
|
+
attioPreludeLines.push(' if (typeof rawObject.email_address === "string") return rawObject.email_address');
|
|
543
|
+
attioPreludeLines.push(' if (typeof rawObject.domain === "string") return rawObject.domain');
|
|
544
|
+
attioPreludeLines.push(' if (typeof rawObject.phone_number === "string") return rawObject.phone_number');
|
|
545
|
+
attioPreludeLines.push(' if ("value" in rawObject) return __flattenAttioLeafValue(rawObject.value)');
|
|
546
|
+
attioPreludeLines.push(" const dataEntries = Object.entries(rawObject).filter(([key]) => !__attioMetadataKeys.has(key))");
|
|
547
|
+
attioPreludeLines.push(" if (dataEntries.length === 0) return rawObject");
|
|
548
|
+
attioPreludeLines.push(" if (dataEntries.length === 1) return __flattenAttioLeafValue(dataEntries[0][1])");
|
|
549
|
+
attioPreludeLines.push(" return Object.fromEntries(dataEntries.map(([key, entryValue]) => [key, __flattenAttioLeafValue(entryValue)]))");
|
|
550
|
+
attioPreludeLines.push("}");
|
|
551
|
+
attioPreludeLines.push("");
|
|
552
|
+
attioPreludeLines.push("function __flattenAttioAttributeValue(rawValue: unknown, preferArray: boolean): unknown {");
|
|
553
|
+
attioPreludeLines.push(" if (!Array.isArray(rawValue)) return __flattenAttioLeafValue(rawValue)");
|
|
554
|
+
attioPreludeLines.push(" const flattened = rawValue");
|
|
555
|
+
attioPreludeLines.push(" .map(entry => __flattenAttioLeafValue(entry))");
|
|
556
|
+
attioPreludeLines.push(" .filter(entry => entry !== undefined)");
|
|
557
|
+
attioPreludeLines.push(" return preferArray ? flattened : flattened[0]");
|
|
558
|
+
attioPreludeLines.push("}");
|
|
559
|
+
attioPreludeLines.push("");
|
|
560
|
+
attioPreludeLines.push("function __getAttioRecordValues<TValues extends Record<string, unknown>>(objectSlug: string, record: unknown): TValues {");
|
|
561
|
+
attioPreludeLines.push(' const rawValues = record && typeof record === "object" ? (record as { values?: unknown }).values : undefined');
|
|
562
|
+
attioPreludeLines.push(' if (!rawValues || typeof rawValues !== "object" || Array.isArray(rawValues)) return {} as TValues');
|
|
563
|
+
attioPreludeLines.push(" const flattenedValues: Record<string, unknown> = {}");
|
|
564
|
+
attioPreludeLines.push(" for (const [attributeSlug, rawValue] of Object.entries(rawValues)) {");
|
|
565
|
+
attioPreludeLines.push(" flattenedValues[attributeSlug] = __flattenAttioAttributeValue(rawValue, __isAttioMultiValueAttribute(objectSlug, attributeSlug))");
|
|
566
|
+
attioPreludeLines.push(" }");
|
|
567
|
+
attioPreludeLines.push(" return flattenedValues as TValues");
|
|
568
|
+
attioPreludeLines.push("}");
|
|
569
|
+
attioPreludeLines.push("");
|
|
570
|
+
attioPreludeLines.push("function __enhanceAttioRecord<TObject extends GeneratedAttioObject>(object: TObject, record: unknown): __AttioRecordWithValues<AttioRecordValuesFor<TObject>> | undefined {");
|
|
571
|
+
attioPreludeLines.push(' if (!record || typeof record !== "object") return undefined');
|
|
572
|
+
attioPreludeLines.push(" const values = __getAttioRecordValues<AttioRecordValuesFor<TObject>>(__normalizeAttioObjectSlug(object), record)");
|
|
573
|
+
attioPreludeLines.push(" return { ...values, ...(record as __AttioRecordBase), values, attributes: values } as __AttioRecordWithValues<AttioRecordValuesFor<TObject>>");
|
|
574
|
+
attioPreludeLines.push("}");
|
|
575
|
+
attioPreludeLines.push("");
|
|
576
|
+
attioPreludeLines.push('function __enhanceAttioQueryResult<TObject extends GeneratedAttioObject>(object: TObject, result: ToolOutputByName["attio_query_records"]): AttioQueryRecordsResult<TObject> {');
|
|
577
|
+
attioPreludeLines.push(" return {");
|
|
578
|
+
attioPreludeLines.push(" ...result,");
|
|
579
|
+
attioPreludeLines.push(" records: (result.records || []).map(record => __enhanceAttioRecord(object, record)).filter(Boolean) as Array<AttioRecordFor<TObject>>,");
|
|
580
|
+
attioPreludeLines.push(" }");
|
|
581
|
+
attioPreludeLines.push("}");
|
|
582
|
+
attioPreludeLines.push("");
|
|
583
|
+
attioPreludeLines.push('function __enhanceAttioUpsertResult<TObject extends GeneratedAttioObject>(object: TObject, result: ToolOutputByName["attio_upsert_record"]): AttioUpsertRecordResult<TObject> {');
|
|
584
|
+
attioPreludeLines.push(" return {");
|
|
585
|
+
attioPreludeLines.push(" ...result,");
|
|
586
|
+
attioPreludeLines.push(" records: (result.records || []).map(record => __enhanceAttioRecord(object, record)).filter(Boolean) as Array<AttioRecordFor<TObject>>,");
|
|
587
|
+
attioPreludeLines.push(" }");
|
|
588
|
+
attioPreludeLines.push("}");
|
|
589
|
+
attioPreludeLines.push("");
|
|
590
|
+
}
|
|
591
|
+
const paramTypes = [];
|
|
592
|
+
for (const tool of tools) {
|
|
593
|
+
if (isAttioTool(tool))
|
|
594
|
+
continue;
|
|
595
|
+
const key = `"${escapeString(tool.name)}"`;
|
|
596
|
+
const tsType = hasAutoFillId(tool) ? `Omit<ToolInputByName[${key}], "integrationId">` : `ToolInputByName[${key}]`;
|
|
597
|
+
paramTypes.push({
|
|
598
|
+
description: tool.description || undefined,
|
|
599
|
+
typeName: toolNameToInterfaceName(tool.name),
|
|
600
|
+
tsType
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
const rawGroups = [];
|
|
604
|
+
for (const [integration, integrationTools] of byIntegration.entries()) {
|
|
605
|
+
const needsAutoFill = integrationTools.some(hasAutoFillId);
|
|
606
|
+
if (needsAutoFill) {
|
|
607
|
+
const instances = instanceMap.get(integration) || [];
|
|
608
|
+
if (instances.length === 0)
|
|
609
|
+
continue;
|
|
610
|
+
rawGroups.push({ key: integration, integration, tools: integrationTools, integrationId: instances[0].id });
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
rawGroups.push({ key: integration, integration, tools: integrationTools });
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
rawGroups.sort((a, b) => a.key.localeCompare(b.key));
|
|
617
|
+
const githubRepoMappings = [];
|
|
618
|
+
if (rawGroups.some(group => group.integration === "github")) {
|
|
619
|
+
const githubRepoFullNames = Array.from(new Set(input.github.flatMap(inst => inst.repositories.map(repo => (repo.owner && repo.name ? `${repo.owner}/${repo.name}` : repo.name).trim()).filter(Boolean))));
|
|
620
|
+
const nameToFullName = new Map();
|
|
621
|
+
const ambiguousNames = new Set();
|
|
622
|
+
for (const fullName of githubRepoFullNames) {
|
|
623
|
+
const [, repoName = fullName] = fullName.split("/", 2);
|
|
624
|
+
if (nameToFullName.has(repoName) && nameToFullName.get(repoName) !== fullName) {
|
|
625
|
+
ambiguousNames.add(repoName);
|
|
626
|
+
nameToFullName.delete(repoName);
|
|
627
|
+
}
|
|
628
|
+
else if (!ambiguousNames.has(repoName)) {
|
|
629
|
+
nameToFullName.set(repoName, fullName);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
for (const [name, fullName] of Array.from(nameToFullName.entries()).sort((a, b) => a[0].localeCompare(b[0]))) {
|
|
633
|
+
githubRepoMappings.push({ name, fullName });
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
const groups = rawGroups.map(group => ({
|
|
637
|
+
key: group.key,
|
|
638
|
+
integrationType: toolIntegrationToIntegrationType(group.integration),
|
|
639
|
+
methods: group.tools.map(tool => {
|
|
640
|
+
const methodName = toCamelCase(tool.displayName);
|
|
641
|
+
const paramsType = toolNameToInterfaceName(tool.name);
|
|
642
|
+
const normalizedParamsExpr = group.integration === "github" ? normalizeGitHubReposParams(tool.name) : "params";
|
|
643
|
+
let generatedSignature;
|
|
644
|
+
if (group.integration === "attio" && tool.name === "attio_query_records") {
|
|
645
|
+
generatedSignature = `${methodName}<TObject extends GeneratedAttioObject>(params: AttioQueryRecordsParams<TObject>): Promise<AttioQueryRecordsResult<TObject>>`;
|
|
646
|
+
}
|
|
647
|
+
else if (group.integration === "attio" && tool.name === "attio_upsert_record") {
|
|
648
|
+
generatedSignature = `${methodName}<TObject extends GeneratedAttioObject>(params: AttioUpsertRecordParams<TObject>): Promise<AttioUpsertRecordResult<TObject>>`;
|
|
649
|
+
}
|
|
650
|
+
else if (group.integration === "attio" && tool.name === "attio_list_objects") {
|
|
651
|
+
generatedSignature = `${methodName}(params?: AttioListObjectsParams): Promise<ToolOutputByName["${escapeString(tool.name)}"]>`;
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
generatedSignature = `${methodName}(params: ${paramsType}): Promise<ToolOutputByName["${escapeString(tool.name)}"]>`;
|
|
655
|
+
}
|
|
656
|
+
let runtimeLines;
|
|
657
|
+
if (group.integration === "attio" && tool.name === "attio_query_records" && group.integrationId) {
|
|
658
|
+
runtimeLines = [
|
|
659
|
+
`${methodName}: <TObject extends GeneratedAttioObject>(params: AttioQueryRecordsParams<TObject>) =>`,
|
|
660
|
+
` agent.executeTool<ToolOutputByName["${escapeString(tool.name)}"]>("${escapeString(tool.name)}", { objectSlug: __normalizeAttioObjectSlug(params.object), filter: __serializeAttioFilter(params.filter), limit: params.limit ?? null, integrationId: "${escapeString(group.integrationId)}" }).then(result => __enhanceAttioQueryResult(params.object, result)),`
|
|
661
|
+
];
|
|
662
|
+
}
|
|
663
|
+
else if (group.integration === "attio" && tool.name === "attio_upsert_record" && group.integrationId) {
|
|
664
|
+
runtimeLines = [
|
|
665
|
+
`${methodName}: <TObject extends GeneratedAttioObject>(params: AttioUpsertRecordParams<TObject>) =>`,
|
|
666
|
+
` agent.executeTool<ToolOutputByName["${escapeString(tool.name)}"]>("${escapeString(tool.name)}", { objectSlug: __normalizeAttioObjectSlug(params.object), matchingAttribute: params.matchingAttribute, records: __serializeAttioRecords(params.records), integrationId: "${escapeString(group.integrationId)}" }).then(result => __enhanceAttioUpsertResult(params.object, result)),`
|
|
667
|
+
];
|
|
668
|
+
}
|
|
669
|
+
else if (group.integration === "attio" && tool.name === "attio_list_objects" && group.integrationId) {
|
|
670
|
+
runtimeLines = [
|
|
671
|
+
`${methodName}: (params: AttioListObjectsParams = {}) =>`,
|
|
672
|
+
` agent.executeTool<ToolOutputByName["${escapeString(tool.name)}"]>("${escapeString(tool.name)}", { ...params, integrationId: "${escapeString(group.integrationId)}" }),`
|
|
673
|
+
];
|
|
674
|
+
}
|
|
675
|
+
else if (group.integrationId && hasAutoFillId(tool)) {
|
|
676
|
+
runtimeLines = [
|
|
677
|
+
`${methodName}: (params: ${paramsType}) =>`,
|
|
678
|
+
` agent.executeTool<ToolOutputByName["${escapeString(tool.name)}"]>("${escapeString(tool.name)}", { ...(${normalizedParamsExpr}), integrationId: "${escapeString(group.integrationId)}" }),`
|
|
679
|
+
];
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
runtimeLines = [
|
|
683
|
+
`${methodName}: (params: ${paramsType}) =>`,
|
|
684
|
+
` agent.executeTool<ToolOutputByName["${escapeString(tool.name)}"]>("${escapeString(tool.name)}", ${normalizedParamsExpr}),`
|
|
685
|
+
];
|
|
686
|
+
}
|
|
687
|
+
return {
|
|
688
|
+
description: tool.description || undefined,
|
|
689
|
+
generatedSignature,
|
|
690
|
+
runtimeLines
|
|
691
|
+
};
|
|
692
|
+
})
|
|
693
|
+
}));
|
|
694
|
+
return {
|
|
695
|
+
imports,
|
|
696
|
+
data: {
|
|
697
|
+
attioPreludeLines,
|
|
698
|
+
paramTypes,
|
|
699
|
+
githubRepoMappings,
|
|
700
|
+
groups
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
function prepareSystemSection(tools) {
|
|
705
|
+
return sectionData(["TimeTriggerConfig", "TerseConfig", "TypedSkill"], {
|
|
706
|
+
skillToolType: buildSkillToolTypeForIntegration(tools, "terse")
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
export function prepareTemplateContext(input) {
|
|
710
|
+
const allImports = new Set();
|
|
711
|
+
const github = prepareGitHubSection(input.github, input.tools);
|
|
712
|
+
const gmail = prepareGmailSection(input.gmail, input.tools);
|
|
713
|
+
const slack = prepareSlackSection(input.slack, input.tools);
|
|
714
|
+
const figma = prepareFigmaSection(input.figma);
|
|
715
|
+
const linear = prepareLinearSection(input.linear, input.tools);
|
|
716
|
+
const atlassian = prepareAtlassianSection(input.atlassian, input.tools);
|
|
717
|
+
const notion = prepareNotionSection(input.notion, input.tools);
|
|
718
|
+
const posthog = preparePosthogSection(input.posthog, input.tools);
|
|
719
|
+
const datadog = prepareDatadogSection(input.datadog, input.tools);
|
|
720
|
+
const launchdarkly = prepareLaunchDarklySection(input.launchdarkly, input.tools);
|
|
721
|
+
const workos = prepareWorkOSSection(input.workos, input.tools);
|
|
722
|
+
const attio = prepareAttioSection(input.attio, input.tools);
|
|
723
|
+
const snowflake = prepareSnowflakeSection(input.snowflake, input.tools);
|
|
724
|
+
const tools = prepareToolsSection(input.tools, input);
|
|
725
|
+
const system = prepareSystemSection(input.tools);
|
|
726
|
+
const sections = [github, gmail, slack, figma, linear, atlassian, notion, posthog, datadog, launchdarkly, workos, attio, snowflake, tools, system];
|
|
727
|
+
for (const section of sections) {
|
|
728
|
+
section.imports.forEach(value => allImports.add(value));
|
|
729
|
+
}
|
|
730
|
+
const imports = [...allImports].sort();
|
|
731
|
+
return {
|
|
732
|
+
imports,
|
|
733
|
+
useMultilineImports: imports.length > 3,
|
|
734
|
+
github: github.data,
|
|
735
|
+
gmail: gmail.data,
|
|
736
|
+
slack: slack.data,
|
|
737
|
+
figma: figma.data,
|
|
738
|
+
linear: linear.data,
|
|
739
|
+
atlassian: atlassian.data,
|
|
740
|
+
notion: notion.data,
|
|
741
|
+
posthog: posthog.data,
|
|
742
|
+
datadog: datadog.data,
|
|
743
|
+
launchdarkly: launchdarkly.data,
|
|
744
|
+
workos: workos.data,
|
|
745
|
+
attio: attio.data,
|
|
746
|
+
snowflake: snowflake.data,
|
|
747
|
+
tools: tools.data,
|
|
748
|
+
system: system.data
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
//# sourceMappingURL=prepareCodegenData.js.map
|