@inkeep/agents-cli 0.51.0 → 0.52.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/agents-cli/package.js +6 -0
- package/dist/commands/config.js +1 -1
- package/dist/commands/dev.js +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/pull-v3/component-parser.js +4 -10
- package/dist/commands/pull-v4/agent-generator.js +274 -0
- package/dist/commands/pull-v4/artifact-component-generator.js +69 -0
- package/dist/commands/pull-v4/context-config-generator.js +264 -0
- package/dist/commands/pull-v4/credential-generator.js +30 -0
- package/dist/commands/pull-v4/data-component-generator.js +50 -0
- package/dist/commands/pull-v4/environment-generator.js +123 -0
- package/dist/commands/pull-v4/external-agent-generator.js +56 -0
- package/dist/commands/pull-v4/function-tool-generator.js +48 -0
- package/dist/commands/pull-v4/introspect/index.js +365 -0
- package/dist/commands/pull-v4/introspect/test-helpers.js +143 -0
- package/dist/commands/pull-v4/introspect-generator.js +691 -0
- package/dist/commands/pull-v4/mcp-tool-generator.js +91 -0
- package/dist/commands/pull-v4/module-merge.js +379 -0
- package/dist/commands/pull-v4/project-generator.js +101 -0
- package/dist/commands/pull-v4/status-component-generator.js +35 -0
- package/dist/commands/pull-v4/sub-agent-generator.js +168 -0
- package/dist/commands/pull-v4/trigger-generator.js +58 -0
- package/dist/commands/pull-v4/utils.js +219 -0
- package/dist/commands/push.js +1 -1
- package/dist/commands/update.js +2 -2
- package/dist/index.js +18 -44
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/array.js +18 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/base.js +180 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/character.js +8 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/css.js +12 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/json.js +60 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/line.js +37 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/sentence.js +31 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/word.js +118 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/index.js +11 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/patch/create.js +141 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/util/string.js +63 -0
- package/dist/utils/ci-environment.js +1 -1
- package/dist/utils/config.js +1 -1
- package/dist/utils/environment-loader.js +1 -1
- package/dist/utils/file-finder.js +1 -1
- package/dist/utils/mcp-runner.js +1 -1
- package/dist/utils/profile-config.js +1 -1
- package/dist/utils/profiles/profile-manager.js +1 -1
- package/dist/utils/project-directory.js +1 -1
- package/dist/utils/project-loader.js +1 -1
- package/dist/utils/version-check.js +6 -15
- package/package.json +5 -4
- package/dist/commands/pull-v3/component-updater.js +0 -768
- package/dist/commands/pull-v3/components/agent-generator.js +0 -255
- package/dist/commands/pull-v3/components/artifact-component-generator.js +0 -143
- package/dist/commands/pull-v3/components/context-config-generator.js +0 -190
- package/dist/commands/pull-v3/components/credential-generator.js +0 -89
- package/dist/commands/pull-v3/components/data-component-generator.js +0 -102
- package/dist/commands/pull-v3/components/environment-generator.js +0 -173
- package/dist/commands/pull-v3/components/external-agent-generator.js +0 -75
- package/dist/commands/pull-v3/components/function-tool-generator.js +0 -92
- package/dist/commands/pull-v3/components/mcp-tool-generator.js +0 -86
- package/dist/commands/pull-v3/components/project-generator.js +0 -157
- package/dist/commands/pull-v3/components/status-component-generator.js +0 -92
- package/dist/commands/pull-v3/components/sub-agent-generator.js +0 -295
- package/dist/commands/pull-v3/components/trigger-generator.js +0 -185
- package/dist/commands/pull-v3/index.js +0 -510
- package/dist/commands/pull-v3/introspect-generator.js +0 -286
- package/dist/commands/pull-v3/llm-content-merger.js +0 -192
- package/dist/commands/pull-v3/new-component-generator.js +0 -279
- package/dist/commands/pull-v3/project-index-generator.js +0 -32
- package/dist/commands/pull-v3/project-validator.js +0 -358
- package/dist/utils/url.js +0 -26
|
@@ -0,0 +1,691 @@
|
|
|
1
|
+
import { collectTemplateVariableNames, createInMemoryProject, isPlainObject, toCamelCase } from "./utils.js";
|
|
2
|
+
import { buildComponentRegistryFromParsing } from "../pull-v3/component-parser.js";
|
|
3
|
+
import { generateAgentDefinition } from "./agent-generator.js";
|
|
4
|
+
import { generateArtifactComponentDefinition } from "./artifact-component-generator.js";
|
|
5
|
+
import { generateContextConfigDefinition } from "./context-config-generator.js";
|
|
6
|
+
import { generateCredentialDefinition } from "./credential-generator.js";
|
|
7
|
+
import { generateDataComponentDefinition } from "./data-component-generator.js";
|
|
8
|
+
import { mergeGeneratedModule } from "./module-merge.js";
|
|
9
|
+
import { generateProjectDefinition } from "./project-generator.js";
|
|
10
|
+
import { generateStatusComponentDefinition } from "./status-component-generator.js";
|
|
11
|
+
import { generateSubAgentDefinition } from "./sub-agent-generator.js";
|
|
12
|
+
import { generateTriggerDefinition } from "./trigger-generator.js";
|
|
13
|
+
import { dirname, join } from "node:path";
|
|
14
|
+
import { Node, SyntaxKind } from "ts-morph";
|
|
15
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
|
|
17
|
+
//#region src/commands/pull-v4/introspect-generator.ts
|
|
18
|
+
async function introspectGenerate({ project, paths, writeMode = "merge", failOnUnsupportedComponents = false, debug = false }) {
|
|
19
|
+
validateProject(project);
|
|
20
|
+
const skippedAgents = [];
|
|
21
|
+
const context = {
|
|
22
|
+
project,
|
|
23
|
+
paths,
|
|
24
|
+
completeAgentIds: collectCompleteAgentIds(project, skippedAgents),
|
|
25
|
+
existingComponentRegistry: writeMode === "merge" ? buildComponentRegistryFromParsing(paths.projectRoot, debug) : void 0
|
|
26
|
+
};
|
|
27
|
+
const tasks = createGenerationTasks();
|
|
28
|
+
const failures = [];
|
|
29
|
+
const generatedFiles = [];
|
|
30
|
+
for (const task of tasks) {
|
|
31
|
+
const records = task.collect(context);
|
|
32
|
+
for (const record of records) {
|
|
33
|
+
const sourceFile = task.generate(record.payload);
|
|
34
|
+
writeTypeScriptFile(record.filePath, sourceFile.getFullText(), writeMode);
|
|
35
|
+
generatedFiles.push(record.filePath);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const unsupportedCounts = collectUnsupportedComponentCounts(project);
|
|
39
|
+
if (failOnUnsupportedComponents && hasUnsupportedComponents(unsupportedCounts)) failures.push(formatUnsupportedComponentsError(unsupportedCounts));
|
|
40
|
+
if (failures.length > 0) throw new Error(`Inkeep Pull failed:\n${failures.join("\n")}`);
|
|
41
|
+
if (debug) {
|
|
42
|
+
console.log(`Generated ${generatedFiles.length} files`);
|
|
43
|
+
if (skippedAgents.length > 0) console.log(`Skipped ${skippedAgents.length} agent(s): ${skippedAgents.map((agent) => `${agent.id} (${agent.reason})`).join(", ")}`);
|
|
44
|
+
if (hasUnsupportedComponents(unsupportedCounts)) console.log(formatUnsupportedComponentsWarning(unsupportedCounts));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function createGenerationTasks() {
|
|
48
|
+
return [
|
|
49
|
+
{
|
|
50
|
+
type: "credential",
|
|
51
|
+
collect: collectCredentialRecords,
|
|
52
|
+
generate: generateCredentialDefinition
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: "artifact-component",
|
|
56
|
+
collect: collectArtifactComponentRecords,
|
|
57
|
+
generate: generateArtifactComponentDefinition
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: "data-component",
|
|
61
|
+
collect: collectDataComponentRecords,
|
|
62
|
+
generate: generateDataComponentDefinition
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: "context-config",
|
|
66
|
+
collect: collectContextConfigRecords,
|
|
67
|
+
generate: generateContextConfigDefinition
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: "trigger",
|
|
71
|
+
collect: collectTriggerRecords,
|
|
72
|
+
generate: generateTriggerDefinition
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: "sub-agent",
|
|
76
|
+
collect: collectSubAgentRecords,
|
|
77
|
+
generate: generateSubAgentDefinition
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: "status-component",
|
|
81
|
+
collect: collectStatusComponentRecords,
|
|
82
|
+
generate: generateStatusComponentDefinition
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
type: "agent",
|
|
86
|
+
collect: collectAgentRecords,
|
|
87
|
+
generate: generateAgentDefinition
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
type: "project",
|
|
91
|
+
collect: collectProjectRecord,
|
|
92
|
+
generate: generateProjectDefinition
|
|
93
|
+
}
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
function collectCredentialRecords(context) {
|
|
97
|
+
if (!context.project.credentialReferences) return [];
|
|
98
|
+
return Object.entries(context.project.credentialReferences).map(([credentialId, credentialData]) => ({
|
|
99
|
+
id: credentialId,
|
|
100
|
+
filePath: resolveRecordFilePath(context, "credentials", credentialId, join(context.paths.credentialsDir, `${credentialId}.ts`)),
|
|
101
|
+
payload: {
|
|
102
|
+
credentialId,
|
|
103
|
+
...credentialData
|
|
104
|
+
}
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
function collectArtifactComponentRecords(context) {
|
|
108
|
+
if (!context.project.artifactComponents) return [];
|
|
109
|
+
return Object.entries(context.project.artifactComponents).map(([artifactComponentId, artifactComponentData]) => ({
|
|
110
|
+
id: artifactComponentId,
|
|
111
|
+
filePath: resolveRecordFilePath(context, "artifactComponents", artifactComponentId, join(context.paths.artifactComponentsDir, `${artifactComponentId}.ts`)),
|
|
112
|
+
payload: {
|
|
113
|
+
artifactComponentId,
|
|
114
|
+
...artifactComponentData
|
|
115
|
+
}
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
function collectDataComponentRecords(context) {
|
|
119
|
+
if (!context.project.dataComponents) return [];
|
|
120
|
+
return Object.entries(context.project.dataComponents).map(([dataComponentId, dataComponent]) => ({
|
|
121
|
+
id: dataComponentId,
|
|
122
|
+
filePath: resolveRecordFilePath(context, "dataComponents", dataComponentId, join(context.paths.dataComponentsDir, `${dataComponentId}.ts`)),
|
|
123
|
+
payload: {
|
|
124
|
+
dataComponentId,
|
|
125
|
+
...dataComponent
|
|
126
|
+
}
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
function collectContextConfigRecords(context) {
|
|
130
|
+
if (!context.project.agents) return [];
|
|
131
|
+
const contextConfigRecordsById = /* @__PURE__ */ new Map();
|
|
132
|
+
for (const agentId of context.completeAgentIds) {
|
|
133
|
+
const agentData = context.project.agents[agentId];
|
|
134
|
+
const contextConfig = agentData ? asRecord(agentData.contextConfig) : void 0;
|
|
135
|
+
if (!agentData || !contextConfig) continue;
|
|
136
|
+
const normalizedContextConfig = applyPromptHeaderTemplateSchema(contextConfig, collectHeaderTemplateVariablesFromAgentPrompts(agentData));
|
|
137
|
+
const contextConfigId = typeof normalizedContextConfig.id === "string" ? normalizedContextConfig.id : "";
|
|
138
|
+
if (!contextConfigId) continue;
|
|
139
|
+
if (!contextConfigRecordsById.has(contextConfigId)) {
|
|
140
|
+
const contextConfigFilePath = resolveRecordFilePath(context, "contextConfigs", contextConfigId, join(context.paths.contextConfigsDir, `${contextConfigId}.ts`));
|
|
141
|
+
const credentialReferenceOverrides = collectContextConfigCredentialReferenceOverrides(context, normalizedContextConfig);
|
|
142
|
+
const headersReferenceOverride = collectContextConfigHeadersReferenceOverride(context, contextConfigId, contextConfigFilePath);
|
|
143
|
+
contextConfigRecordsById.set(contextConfigId, {
|
|
144
|
+
id: contextConfigId,
|
|
145
|
+
filePath: contextConfigFilePath,
|
|
146
|
+
payload: {
|
|
147
|
+
contextConfigId,
|
|
148
|
+
...normalizedContextConfig,
|
|
149
|
+
...headersReferenceOverride && { headers: headersReferenceOverride },
|
|
150
|
+
...credentialReferenceOverrides && { referenceOverrides: { credentialReferences: credentialReferenceOverrides } }
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return [...contextConfigRecordsById.values()];
|
|
156
|
+
}
|
|
157
|
+
function collectContextConfigCredentialReferenceOverrides(context, contextConfigData) {
|
|
158
|
+
const registry = context.existingComponentRegistry;
|
|
159
|
+
if (!registry) return;
|
|
160
|
+
const contextVariables = asRecord(contextConfigData.contextVariables);
|
|
161
|
+
if (!contextVariables) return;
|
|
162
|
+
const overrides = {};
|
|
163
|
+
for (const contextVariable of Object.values(contextVariables)) {
|
|
164
|
+
const contextVariableRecord = asRecord(contextVariable);
|
|
165
|
+
const credentialReferenceId = contextVariableRecord && typeof contextVariableRecord.credentialReferenceId === "string" ? contextVariableRecord.credentialReferenceId : void 0;
|
|
166
|
+
if (!credentialReferenceId) continue;
|
|
167
|
+
const existingCredential = registry.get(credentialReferenceId, "credentials");
|
|
168
|
+
if (existingCredential?.name) overrides[credentialReferenceId] = existingCredential.name;
|
|
169
|
+
}
|
|
170
|
+
return Object.keys(overrides).length ? overrides : void 0;
|
|
171
|
+
}
|
|
172
|
+
function collectContextConfigHeadersReferenceOverride(context, contextConfigId, filePath) {
|
|
173
|
+
if (!context.existingComponentRegistry || !existsSync(filePath)) return;
|
|
174
|
+
const sourceFile = createInMemoryProject().createSourceFile("existing-context-config.ts", readFileSync(filePath, "utf8"), { overwrite: true });
|
|
175
|
+
for (const declaration of sourceFile.getVariableDeclarations()) {
|
|
176
|
+
const initializer = declaration.getInitializer();
|
|
177
|
+
if (!initializer || !Node.isCallExpression(initializer)) continue;
|
|
178
|
+
const expression = initializer.getExpression();
|
|
179
|
+
if (!Node.isIdentifier(expression) || expression.getText() !== "contextConfig") continue;
|
|
180
|
+
const [configArg] = initializer.getArguments();
|
|
181
|
+
if (!configArg || !Node.isObjectLiteralExpression(configArg)) continue;
|
|
182
|
+
const idProperty = configArg.getProperty("id");
|
|
183
|
+
if (!idProperty || !Node.isPropertyAssignment(idProperty)) continue;
|
|
184
|
+
const idInitializer = idProperty.getInitializer();
|
|
185
|
+
if (!idInitializer || !Node.isStringLiteral(idInitializer)) continue;
|
|
186
|
+
if (idInitializer.getLiteralValue() !== contextConfigId) continue;
|
|
187
|
+
const headersProperty = configArg.getProperty("headers");
|
|
188
|
+
if (!headersProperty) return;
|
|
189
|
+
if (Node.isShorthandPropertyAssignment(headersProperty)) return headersProperty.getName();
|
|
190
|
+
if (!Node.isPropertyAssignment(headersProperty)) return;
|
|
191
|
+
const headersInitializer = headersProperty.getInitializer();
|
|
192
|
+
if (!headersInitializer) return;
|
|
193
|
+
if (Node.isIdentifier(headersInitializer)) return headersInitializer.getText();
|
|
194
|
+
if (Node.isAsExpression(headersInitializer)) {
|
|
195
|
+
const valueExpression = headersInitializer.getExpression();
|
|
196
|
+
if (Node.isIdentifier(valueExpression)) return valueExpression.getText();
|
|
197
|
+
}
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function collectTriggerRecords(context) {
|
|
202
|
+
if (!context.project.agents) return [];
|
|
203
|
+
const records = [];
|
|
204
|
+
for (const agentId of context.completeAgentIds) {
|
|
205
|
+
const agentData = context.project.agents[agentId];
|
|
206
|
+
if (!agentData?.triggers) continue;
|
|
207
|
+
for (const [triggerId, triggerData] of Object.entries(agentData.triggers)) records.push({
|
|
208
|
+
id: triggerId,
|
|
209
|
+
filePath: resolveRecordFilePath(context, "triggers", triggerId, join(context.paths.agentsDir, "triggers", `${triggerId}.ts`)),
|
|
210
|
+
payload: {
|
|
211
|
+
triggerId,
|
|
212
|
+
...triggerData
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return records;
|
|
217
|
+
}
|
|
218
|
+
function collectAgentRecords(context) {
|
|
219
|
+
if (!context.project.agents) return [];
|
|
220
|
+
const records = [];
|
|
221
|
+
for (const agentId of context.completeAgentIds) {
|
|
222
|
+
const agentData = context.project.agents[agentId];
|
|
223
|
+
if (!agentData) continue;
|
|
224
|
+
const agentFilePath = resolveRecordFilePath(context, "agents", agentId, join(context.paths.agentsDir, `${agentId}.ts`));
|
|
225
|
+
const existingAgent = context.existingComponentRegistry?.get(agentId, "agents");
|
|
226
|
+
const subAgentReferences = collectSubAgentReferenceOverrides(context, agentData, agentFilePath);
|
|
227
|
+
const statusUpdates = asRecord(agentData.statusUpdates);
|
|
228
|
+
const contextTemplateReferences = collectContextTemplateReferences(context, agentData, agentFilePath, [typeof agentData.prompt === "string" ? agentData.prompt : void 0, typeof statusUpdates?.prompt === "string" ? statusUpdates.prompt : void 0]);
|
|
229
|
+
records.push({
|
|
230
|
+
id: agentId,
|
|
231
|
+
filePath: agentFilePath,
|
|
232
|
+
payload: {
|
|
233
|
+
agentId,
|
|
234
|
+
...agentData,
|
|
235
|
+
...existingAgent?.name?.length && { agentVariableName: existingAgent.name },
|
|
236
|
+
...Object.keys(subAgentReferences).length > 0 ? { subAgentReferences } : {},
|
|
237
|
+
...contextTemplateReferences && { contextConfigReference: contextTemplateReferences.contextConfigReference },
|
|
238
|
+
...contextTemplateReferences?.contextConfigHeadersReference && { contextConfigHeadersReference: contextTemplateReferences.contextConfigHeadersReference }
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
return records;
|
|
243
|
+
}
|
|
244
|
+
function collectSubAgentRecords(context) {
|
|
245
|
+
if (!context.project.agents) return [];
|
|
246
|
+
const records = [];
|
|
247
|
+
for (const agentId of context.completeAgentIds) {
|
|
248
|
+
const agentData = context.project.agents[agentId];
|
|
249
|
+
const subAgents = asRecord(agentData?.subAgents);
|
|
250
|
+
if (!subAgents) continue;
|
|
251
|
+
for (const [subAgentId, subAgentData] of Object.entries(subAgents)) {
|
|
252
|
+
const payload = asRecord(subAgentData);
|
|
253
|
+
if (!payload) continue;
|
|
254
|
+
const referenceOverrides = collectSubAgentDependencyReferenceOverrides(context, payload);
|
|
255
|
+
const subAgentFilePath = resolveRecordFilePath(context, "subAgents", subAgentId, join(context.paths.agentsDir, "sub-agents", `${subAgentId}.ts`));
|
|
256
|
+
const contextTemplateReferences = collectContextTemplateReferences(context, agentData, subAgentFilePath, [typeof payload.prompt === "string" ? payload.prompt : void 0]);
|
|
257
|
+
records.push({
|
|
258
|
+
id: subAgentId,
|
|
259
|
+
filePath: subAgentFilePath,
|
|
260
|
+
payload: {
|
|
261
|
+
subAgentId,
|
|
262
|
+
...payload,
|
|
263
|
+
...referenceOverrides && { referenceOverrides },
|
|
264
|
+
...contextTemplateReferences && {
|
|
265
|
+
contextConfigId: contextTemplateReferences.contextConfigId,
|
|
266
|
+
contextConfigReference: contextTemplateReferences.contextConfigReference
|
|
267
|
+
},
|
|
268
|
+
...contextTemplateReferences?.contextConfigHeadersReference && { contextConfigHeadersReference: contextTemplateReferences.contextConfigHeadersReference }
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return records;
|
|
274
|
+
}
|
|
275
|
+
function collectStatusComponentRecords(context) {
|
|
276
|
+
if (!context.project.agents) return [];
|
|
277
|
+
const statusComponentRecordsById = /* @__PURE__ */ new Map();
|
|
278
|
+
for (const agentId of context.completeAgentIds) {
|
|
279
|
+
const agentData = context.project.agents[agentId];
|
|
280
|
+
const statusUpdates = asRecord(agentData?.statusUpdates);
|
|
281
|
+
const statusComponents = Array.isArray(statusUpdates?.statusComponents) ? statusUpdates.statusComponents : [];
|
|
282
|
+
for (const statusComponentData of statusComponents) {
|
|
283
|
+
const payload = asRecord(statusComponentData);
|
|
284
|
+
if (!payload) continue;
|
|
285
|
+
const statusComponentId = resolveStatusComponentId(payload);
|
|
286
|
+
if (!statusComponentId || statusComponentRecordsById.has(statusComponentId)) continue;
|
|
287
|
+
statusComponentRecordsById.set(statusComponentId, {
|
|
288
|
+
id: statusComponentId,
|
|
289
|
+
filePath: resolveRecordFilePath(context, "statusComponents", statusComponentId, join(context.paths.statusComponentsDir, `${statusComponentId}.ts`)),
|
|
290
|
+
payload: {
|
|
291
|
+
statusComponentId,
|
|
292
|
+
...payload
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return [...statusComponentRecordsById.values()];
|
|
298
|
+
}
|
|
299
|
+
function collectProjectRecord(context) {
|
|
300
|
+
const referenceOverrides = collectProjectReferenceOverrides(context);
|
|
301
|
+
return [{
|
|
302
|
+
id: context.project.id,
|
|
303
|
+
filePath: resolveRecordFilePath(context, "project", context.project.id, join(context.paths.projectRoot, "index.ts")),
|
|
304
|
+
payload: {
|
|
305
|
+
projectId: context.project.id,
|
|
306
|
+
name: context.project.name,
|
|
307
|
+
description: context.project.description,
|
|
308
|
+
models: context.project.models,
|
|
309
|
+
stopWhen: context.project.stopWhen,
|
|
310
|
+
skills: getObjectKeys(context.project.skills),
|
|
311
|
+
agents: [...context.completeAgentIds],
|
|
312
|
+
tools: getObjectKeys(context.project.tools),
|
|
313
|
+
externalAgents: getObjectKeys(context.project.externalAgents),
|
|
314
|
+
dataComponents: getObjectKeys(context.project.dataComponents),
|
|
315
|
+
artifactComponents: getObjectKeys(context.project.artifactComponents),
|
|
316
|
+
credentialReferences: getObjectKeys(context.project.credentialReferences),
|
|
317
|
+
...referenceOverrides && { referenceOverrides }
|
|
318
|
+
}
|
|
319
|
+
}];
|
|
320
|
+
}
|
|
321
|
+
function validateProject(project) {
|
|
322
|
+
if (!project || typeof project !== "object") throw new Error("Project data is required");
|
|
323
|
+
if (!project.id) throw new Error("Project id is required");
|
|
324
|
+
if (!project.name) throw new Error("Project name is required");
|
|
325
|
+
}
|
|
326
|
+
function collectCompleteAgentIds(project, skippedAgents) {
|
|
327
|
+
const completeAgentIds = /* @__PURE__ */ new Set();
|
|
328
|
+
for (const [agentId, agentData] of Object.entries(project.agents ?? {})) {
|
|
329
|
+
const completeness = isAgentComplete(agentData);
|
|
330
|
+
if (!completeness.complete) {
|
|
331
|
+
skippedAgents.push({
|
|
332
|
+
id: agentId,
|
|
333
|
+
reason: completeness.reason ?? "incomplete"
|
|
334
|
+
});
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
completeAgentIds.add(agentId);
|
|
338
|
+
}
|
|
339
|
+
return completeAgentIds;
|
|
340
|
+
}
|
|
341
|
+
function isAgentComplete(agentData) {
|
|
342
|
+
const data = asRecord(agentData);
|
|
343
|
+
if (!data) return {
|
|
344
|
+
complete: false,
|
|
345
|
+
reason: "invalid agent object"
|
|
346
|
+
};
|
|
347
|
+
if (!data.name || typeof data.name !== "string") return {
|
|
348
|
+
complete: false,
|
|
349
|
+
reason: "missing name"
|
|
350
|
+
};
|
|
351
|
+
if (!data.defaultSubAgentId || typeof data.defaultSubAgentId !== "string") return {
|
|
352
|
+
complete: false,
|
|
353
|
+
reason: "missing defaultSubAgentId"
|
|
354
|
+
};
|
|
355
|
+
if (!asRecord(data.subAgents) || !Object.keys(data.subAgents).length) return {
|
|
356
|
+
complete: false,
|
|
357
|
+
reason: "no sub-agents defined"
|
|
358
|
+
};
|
|
359
|
+
return { complete: true };
|
|
360
|
+
}
|
|
361
|
+
function collectUnsupportedComponentCounts(project) {
|
|
362
|
+
return {
|
|
363
|
+
tools: getObjectKeys(project.tools).length,
|
|
364
|
+
functionTools: getObjectKeys(project.functionTools).length,
|
|
365
|
+
functions: getObjectKeys(project.functions).length,
|
|
366
|
+
externalAgents: getObjectKeys(project.externalAgents).length
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function hasUnsupportedComponents(counts) {
|
|
370
|
+
return Object.values(counts).some((value) => value > 0);
|
|
371
|
+
}
|
|
372
|
+
function formatUnsupportedComponentsError(counts) {
|
|
373
|
+
return `Unsupported components for v4 introspect: ${formatUnsupportedCounts(counts)}`;
|
|
374
|
+
}
|
|
375
|
+
function formatUnsupportedComponentsWarning(counts) {
|
|
376
|
+
return `Skipped unsupported components for v4 introspect: ${formatUnsupportedCounts(counts)}`;
|
|
377
|
+
}
|
|
378
|
+
function formatUnsupportedCounts(counts) {
|
|
379
|
+
return Object.entries(counts).filter(([, value]) => value > 0).map(([name, value]) => `${name}=${value}`).join(", ");
|
|
380
|
+
}
|
|
381
|
+
function getObjectKeys(value) {
|
|
382
|
+
const record = asRecord(value);
|
|
383
|
+
if (!record) return [];
|
|
384
|
+
return Object.keys(record);
|
|
385
|
+
}
|
|
386
|
+
function resolveStatusComponentId(statusComponentData) {
|
|
387
|
+
if (typeof statusComponentData.id === "string") return statusComponentData.id;
|
|
388
|
+
if (typeof statusComponentData.type === "string") return statusComponentData.type;
|
|
389
|
+
if (typeof statusComponentData.name === "string") return statusComponentData.name;
|
|
390
|
+
}
|
|
391
|
+
function asRecord(value) {
|
|
392
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
393
|
+
return value;
|
|
394
|
+
}
|
|
395
|
+
function collectSubAgentReferenceOverrides(context, agentData, agentFilePath) {
|
|
396
|
+
const subAgentIds = new Set(extractReferenceIds(agentData.subAgents));
|
|
397
|
+
if (typeof agentData.defaultSubAgentId === "string" && agentData.defaultSubAgentId.length > 0) subAgentIds.add(agentData.defaultSubAgentId);
|
|
398
|
+
if (!subAgentIds.size) return {};
|
|
399
|
+
const overrides = {};
|
|
400
|
+
for (const subAgentId of subAgentIds) {
|
|
401
|
+
const existingSubAgent = context.existingComponentRegistry?.get(subAgentId, "subAgents");
|
|
402
|
+
if (!existingSubAgent?.name) continue;
|
|
403
|
+
overrides[subAgentId] = normalizeFilePath(resolveProjectFilePath(context.paths.projectRoot, existingSubAgent.filePath)) === normalizeFilePath(agentFilePath) ? {
|
|
404
|
+
name: existingSubAgent.name,
|
|
405
|
+
local: true
|
|
406
|
+
} : { name: existingSubAgent.name };
|
|
407
|
+
}
|
|
408
|
+
return overrides;
|
|
409
|
+
}
|
|
410
|
+
function collectAgentContextConfigReferenceOverride(context, agentData, agentFilePath) {
|
|
411
|
+
const contextConfigId = extractContextConfigData(agentData)?.id;
|
|
412
|
+
if (!contextConfigId) return;
|
|
413
|
+
const existingContextConfig = context.existingComponentRegistry?.get(contextConfigId, "contextConfigs");
|
|
414
|
+
if (!existingContextConfig?.name) return;
|
|
415
|
+
return normalizeFilePath(resolveProjectFilePath(context.paths.projectRoot, existingContextConfig.filePath)) === normalizeFilePath(agentFilePath) ? {
|
|
416
|
+
name: existingContextConfig.name,
|
|
417
|
+
local: true
|
|
418
|
+
} : { name: existingContextConfig.name };
|
|
419
|
+
}
|
|
420
|
+
function collectContextTemplateReferences(context, agentData, targetFilePath, promptValues) {
|
|
421
|
+
const contextConfig = extractContextConfigData(agentData);
|
|
422
|
+
const contextConfigId = contextConfig?.id;
|
|
423
|
+
if (!contextConfigId) return;
|
|
424
|
+
const contextConfigFilePath = resolveRecordFilePath(context, "contextConfigs", contextConfigId, join(context.paths.contextConfigsDir, `${contextConfigId}.ts`));
|
|
425
|
+
const isLocal = normalizeFilePath(contextConfigFilePath) === normalizeFilePath(targetFilePath);
|
|
426
|
+
const contextConfigReference = collectAgentContextConfigReferenceOverride(context, agentData, targetFilePath) ?? (isLocal ? {
|
|
427
|
+
name: toCamelCase(contextConfigId),
|
|
428
|
+
local: true
|
|
429
|
+
} : { name: toCamelCase(contextConfigId) });
|
|
430
|
+
const hasHeadersTemplateVariables = collectTemplateVariablesFromValues(promptValues).some((variableName) => variableName.startsWith("headers."));
|
|
431
|
+
let headersReferenceName = collectContextConfigHeadersReferenceOverride(context, contextConfigId, contextConfigFilePath) ?? inferHeadersReferenceFromContextConfig(contextConfig, contextConfigId);
|
|
432
|
+
if (!headersReferenceName && hasHeadersTemplateVariables) headersReferenceName = `${toCamelCase(contextConfigId)}Headers`;
|
|
433
|
+
return {
|
|
434
|
+
contextConfigId,
|
|
435
|
+
contextConfigReference,
|
|
436
|
+
...headersReferenceName && { contextConfigHeadersReference: isLocal ? {
|
|
437
|
+
name: headersReferenceName,
|
|
438
|
+
local: true
|
|
439
|
+
} : { name: headersReferenceName } }
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
function extractContextConfigData(agentData) {
|
|
443
|
+
const contextConfig = typeof agentData.contextConfig === "string" ? { id: agentData.contextConfig } : asRecord(agentData.contextConfig);
|
|
444
|
+
const contextConfigId = contextConfig && typeof contextConfig.id === "string" ? contextConfig.id : void 0;
|
|
445
|
+
if (!contextConfigId || !contextConfig) return;
|
|
446
|
+
return {
|
|
447
|
+
id: contextConfigId,
|
|
448
|
+
value: contextConfig
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
function inferHeadersReferenceFromContextConfig(contextConfig, contextConfigId) {
|
|
452
|
+
const headers = contextConfig.value.headers;
|
|
453
|
+
if (typeof headers === "string" && headers.length > 0) return toCamelCase(headers);
|
|
454
|
+
const headersRecord = asRecord(headers);
|
|
455
|
+
if (headersRecord) {
|
|
456
|
+
if (typeof headersRecord.id === "string" && headersRecord.id.length > 0) return toCamelCase(headersRecord.id);
|
|
457
|
+
if (typeof headersRecord.name === "string" && headersRecord.name.length > 0) return toCamelCase(headersRecord.name);
|
|
458
|
+
}
|
|
459
|
+
if (isPlainObject(contextConfig.value.headersSchema)) return `${toCamelCase(contextConfigId)}Headers`;
|
|
460
|
+
}
|
|
461
|
+
function collectTemplateVariablesFromValues(values) {
|
|
462
|
+
const variables = [];
|
|
463
|
+
for (const value of values) {
|
|
464
|
+
if (typeof value !== "string") continue;
|
|
465
|
+
variables.push(...collectTemplateVariableNames(value));
|
|
466
|
+
}
|
|
467
|
+
return variables;
|
|
468
|
+
}
|
|
469
|
+
function collectHeaderTemplateVariablesFromAgentPrompts(agentData) {
|
|
470
|
+
const variables = /* @__PURE__ */ new Set();
|
|
471
|
+
addHeaderTemplateVariablesFromString(typeof agentData.prompt === "string" ? agentData.prompt : void 0, variables);
|
|
472
|
+
const statusUpdates = asRecord(agentData.statusUpdates);
|
|
473
|
+
addHeaderTemplateVariablesFromString(typeof statusUpdates?.prompt === "string" ? statusUpdates.prompt : void 0, variables);
|
|
474
|
+
const subAgents = asRecord(agentData.subAgents);
|
|
475
|
+
if (!subAgents) return variables;
|
|
476
|
+
for (const subAgentData of Object.values(subAgents)) {
|
|
477
|
+
const subAgent = asRecord(subAgentData);
|
|
478
|
+
addHeaderTemplateVariablesFromString(typeof subAgent?.prompt === "string" ? subAgent.prompt : void 0, variables);
|
|
479
|
+
}
|
|
480
|
+
return variables;
|
|
481
|
+
}
|
|
482
|
+
function addHeaderTemplateVariablesFromString(value, variables) {
|
|
483
|
+
if (typeof value !== "string") return;
|
|
484
|
+
for (const variableName of collectTemplateVariableNames(value)) {
|
|
485
|
+
if (!variableName.startsWith("headers.")) continue;
|
|
486
|
+
const headerPath = variableName.slice(8);
|
|
487
|
+
if (headerPath) variables.add(headerPath);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
function applyPromptHeaderTemplateSchema(contextConfig, headerTemplateVariables) {
|
|
491
|
+
if (!headerTemplateVariables.size) return contextConfig;
|
|
492
|
+
if (typeof contextConfig.headers === "string" || isPlainObject(contextConfig.headers) || isPlainObject(contextConfig.headersSchema)) return contextConfig;
|
|
493
|
+
const variableNames = [...headerTemplateVariables].sort();
|
|
494
|
+
const properties = Object.fromEntries(variableNames.map((variableName) => [variableName, { type: "string" }]));
|
|
495
|
+
return {
|
|
496
|
+
...contextConfig,
|
|
497
|
+
headersSchema: {
|
|
498
|
+
type: "object",
|
|
499
|
+
properties,
|
|
500
|
+
required: variableNames,
|
|
501
|
+
additionalProperties: false
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
function collectSubAgentDependencyReferenceOverrides(context, subAgentData) {
|
|
506
|
+
const registry = context.existingComponentRegistry;
|
|
507
|
+
if (!registry) return;
|
|
508
|
+
const overrides = {};
|
|
509
|
+
const canUse = Array.isArray(subAgentData.canUse) ? subAgentData.canUse : [];
|
|
510
|
+
for (const item of canUse) {
|
|
511
|
+
if (typeof item === "string") {
|
|
512
|
+
assignComponentReferenceOverride(registry, overrides, "tools", item, "tools");
|
|
513
|
+
assignComponentReferenceOverride(registry, overrides, "tools", item, "functionTools");
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
516
|
+
const canUseRecord = asRecord(item);
|
|
517
|
+
if (!canUseRecord || typeof canUseRecord.toolId !== "string") continue;
|
|
518
|
+
assignComponentReferenceOverride(registry, overrides, "tools", canUseRecord.toolId, "tools");
|
|
519
|
+
assignComponentReferenceOverride(registry, overrides, "tools", canUseRecord.toolId, "functionTools");
|
|
520
|
+
}
|
|
521
|
+
const canDelegateTo = Array.isArray(subAgentData.canDelegateTo) ? subAgentData.canDelegateTo : [];
|
|
522
|
+
for (const item of canDelegateTo) {
|
|
523
|
+
if (typeof item === "string") {
|
|
524
|
+
assignFirstMatchingComponentReferenceOverride(registry, overrides, item, [
|
|
525
|
+
["subAgents", "subAgents"],
|
|
526
|
+
["agents", "agents"],
|
|
527
|
+
["externalAgents", "externalAgents"]
|
|
528
|
+
]);
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
const canDelegateRecord = asRecord(item);
|
|
532
|
+
if (!canDelegateRecord) continue;
|
|
533
|
+
if (typeof canDelegateRecord.subAgentId === "string") {
|
|
534
|
+
assignComponentReferenceOverride(registry, overrides, "subAgents", canDelegateRecord.subAgentId, "subAgents");
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
if (typeof canDelegateRecord.agentId === "string") {
|
|
538
|
+
assignComponentReferenceOverride(registry, overrides, "agents", canDelegateRecord.agentId, "agents");
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
if (typeof canDelegateRecord.externalAgentId === "string") assignComponentReferenceOverride(registry, overrides, "externalAgents", canDelegateRecord.externalAgentId, "externalAgents");
|
|
542
|
+
}
|
|
543
|
+
const canTransferTo = extractReferenceIds(subAgentData.canTransferTo);
|
|
544
|
+
for (const transferTargetId of canTransferTo) assignFirstMatchingComponentReferenceOverride(registry, overrides, transferTargetId, [
|
|
545
|
+
["subAgents", "subAgents"],
|
|
546
|
+
["agents", "agents"],
|
|
547
|
+
["externalAgents", "externalAgents"]
|
|
548
|
+
]);
|
|
549
|
+
const dataComponentIds = extractReferenceIds(subAgentData.dataComponents);
|
|
550
|
+
for (const dataComponentId of dataComponentIds) assignComponentReferenceOverride(registry, overrides, "dataComponents", dataComponentId, "dataComponents");
|
|
551
|
+
const artifactComponentIds = extractReferenceIds(subAgentData.artifactComponents);
|
|
552
|
+
for (const artifactComponentId of artifactComponentIds) assignComponentReferenceOverride(registry, overrides, "artifactComponents", artifactComponentId, "artifactComponents");
|
|
553
|
+
return Object.keys(overrides).length > 0 ? overrides : void 0;
|
|
554
|
+
}
|
|
555
|
+
function assignFirstMatchingComponentReferenceOverride(registry, overrides, componentId, candidates) {
|
|
556
|
+
for (const [overrideType, componentType] of candidates) {
|
|
557
|
+
const component = registry.get(componentId, componentType);
|
|
558
|
+
if (!component?.name) continue;
|
|
559
|
+
assignReferenceOverride(overrides, overrideType, componentId, component.name);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
function assignComponentReferenceOverride(registry, overrides, overrideType, componentId, componentType) {
|
|
564
|
+
const component = registry.get(componentId, componentType);
|
|
565
|
+
if (!component?.name) return;
|
|
566
|
+
assignReferenceOverride(overrides, overrideType, componentId, component.name);
|
|
567
|
+
}
|
|
568
|
+
function assignReferenceOverride(overrides, overrideType, componentId, referenceName) {
|
|
569
|
+
const overrideMap = overrides[overrideType] ?? {};
|
|
570
|
+
overrideMap[componentId] = referenceName;
|
|
571
|
+
overrides[overrideType] = overrideMap;
|
|
572
|
+
}
|
|
573
|
+
function collectProjectReferenceOverrides(context) {
|
|
574
|
+
const registry = context.existingComponentRegistry;
|
|
575
|
+
if (!registry) return;
|
|
576
|
+
const overrides = {};
|
|
577
|
+
for (const agentId of context.completeAgentIds) assignComponentReferenceOverrideForProject(registry, overrides, "agents", agentId, "agents");
|
|
578
|
+
const toolIds = getObjectKeys(context.project.tools);
|
|
579
|
+
for (const toolId of toolIds) {
|
|
580
|
+
if (assignComponentReferenceOverrideForProject(registry, overrides, "tools", toolId, "functionTools")) continue;
|
|
581
|
+
assignComponentReferenceOverrideForProject(registry, overrides, "tools", toolId, "tools");
|
|
582
|
+
}
|
|
583
|
+
const externalAgentIds = getObjectKeys(context.project.externalAgents);
|
|
584
|
+
for (const externalAgentId of externalAgentIds) assignComponentReferenceOverrideForProject(registry, overrides, "externalAgents", externalAgentId, "externalAgents");
|
|
585
|
+
const dataComponentIds = getObjectKeys(context.project.dataComponents);
|
|
586
|
+
for (const dataComponentId of dataComponentIds) assignComponentReferenceOverrideForProject(registry, overrides, "dataComponents", dataComponentId, "dataComponents");
|
|
587
|
+
const artifactComponentIds = getObjectKeys(context.project.artifactComponents);
|
|
588
|
+
for (const artifactComponentId of artifactComponentIds) assignComponentReferenceOverrideForProject(registry, overrides, "artifactComponents", artifactComponentId, "artifactComponents");
|
|
589
|
+
const credentialIds = getObjectKeys(context.project.credentialReferences);
|
|
590
|
+
for (const credentialId of credentialIds) assignComponentReferenceOverrideForProject(registry, overrides, "credentialReferences", credentialId, "credentials");
|
|
591
|
+
return Object.keys(overrides).length > 0 ? overrides : void 0;
|
|
592
|
+
}
|
|
593
|
+
function assignComponentReferenceOverrideForProject(registry, overrides, overrideType, componentId, componentType) {
|
|
594
|
+
const component = registry.get(componentId, componentType);
|
|
595
|
+
if (!component?.name) return false;
|
|
596
|
+
const overrideMap = overrides[overrideType] ?? {};
|
|
597
|
+
overrideMap[componentId] = component.name;
|
|
598
|
+
overrides[overrideType] = overrideMap;
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
function extractReferenceIds(value) {
|
|
602
|
+
if (Array.isArray(value)) return value.map((item) => {
|
|
603
|
+
if (typeof item === "string") return item;
|
|
604
|
+
const record$1 = asRecord(item);
|
|
605
|
+
if (record$1 && typeof record$1.id === "string") return record$1.id;
|
|
606
|
+
}).filter((id) => !!id);
|
|
607
|
+
const record = asRecord(value);
|
|
608
|
+
if (!record) return [];
|
|
609
|
+
return Object.keys(record);
|
|
610
|
+
}
|
|
611
|
+
function resolveRecordFilePath(context, componentType, componentId, fallbackFilePath) {
|
|
612
|
+
const existingComponent = context.existingComponentRegistry?.get(componentId, componentType);
|
|
613
|
+
if (!existingComponent?.filePath) return fallbackFilePath;
|
|
614
|
+
return resolveProjectFilePath(context.paths.projectRoot, existingComponent.filePath);
|
|
615
|
+
}
|
|
616
|
+
function resolveProjectFilePath(projectRoot, filePath) {
|
|
617
|
+
if (filePath.startsWith("/")) return filePath;
|
|
618
|
+
return join(projectRoot, filePath);
|
|
619
|
+
}
|
|
620
|
+
function normalizeFilePath(filePath) {
|
|
621
|
+
return filePath.replaceAll("\\", "/");
|
|
622
|
+
}
|
|
623
|
+
function writeTypeScriptFile(filePath, content, writeMode) {
|
|
624
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
625
|
+
const processedContent = writeMode === "merge" && existsSync(filePath) ? mergeSafely(readFileSync(filePath, "utf8"), content) : content;
|
|
626
|
+
const sourceFile = createInMemoryProject().createSourceFile("generated.ts", processedContent, { overwrite: true });
|
|
627
|
+
const normalizedSourceFile = moveVariableDeclarationsBeforeUsage(applyObjectShorthand(sourceFile));
|
|
628
|
+
sourceFile.formatText();
|
|
629
|
+
writeFileSync(filePath, `${normalizedSourceFile.getFullText().trimEnd()}\n`);
|
|
630
|
+
}
|
|
631
|
+
function mergeSafely(existingContent, generatedContent) {
|
|
632
|
+
try {
|
|
633
|
+
return mergeGeneratedModule(existingContent, generatedContent);
|
|
634
|
+
} catch (error) {
|
|
635
|
+
console.warn(`Warning: Failed to merge file, using generated content. Manual changes may be lost. Reason: ${error instanceof Error ? error.message : String(error)}`);
|
|
636
|
+
return generatedContent;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
function applyObjectShorthand(sourceFile) {
|
|
640
|
+
for (const objectLiteral of sourceFile.getDescendantsOfKind(SyntaxKind.ObjectLiteralExpression)) for (const property of objectLiteral.getProperties()) {
|
|
641
|
+
if (!Node.isPropertyAssignment(property)) continue;
|
|
642
|
+
const nameNode = property.getNameNode();
|
|
643
|
+
const initializer = property.getInitializer();
|
|
644
|
+
if (!Node.isIdentifier(nameNode) || !initializer || !Node.isIdentifier(initializer)) continue;
|
|
645
|
+
if (nameNode.getText() !== initializer.getText()) continue;
|
|
646
|
+
property.replaceWithText(nameNode.getText());
|
|
647
|
+
}
|
|
648
|
+
return sourceFile;
|
|
649
|
+
}
|
|
650
|
+
function moveVariableDeclarationsBeforeUsage(sourceFile) {
|
|
651
|
+
let moved = true;
|
|
652
|
+
while (moved) {
|
|
653
|
+
moved = false;
|
|
654
|
+
const variableStatements = sourceFile.getVariableStatements();
|
|
655
|
+
for (const variableStatement of variableStatements) {
|
|
656
|
+
const statementStart = variableStatement.getStart();
|
|
657
|
+
const sourceStatements = sourceFile.getStatements();
|
|
658
|
+
const statementIndex = sourceStatements.indexOf(variableStatement);
|
|
659
|
+
if (statementIndex <= 0) continue;
|
|
660
|
+
let targetIndex;
|
|
661
|
+
for (const declaration of variableStatement.getDeclarations()) for (const referenceNode of declaration.findReferencesAsNodes()) {
|
|
662
|
+
if (referenceNode.getSourceFile() !== sourceFile) continue;
|
|
663
|
+
if (referenceNode.getParent() === declaration) continue;
|
|
664
|
+
if (referenceNode.getStart() >= statementStart) continue;
|
|
665
|
+
if (isReferenceInsideFunctionLike(referenceNode)) continue;
|
|
666
|
+
const topLevelStatement = referenceNode.getFirstAncestor((ancestor) => {
|
|
667
|
+
return Node.isStatement(ancestor) && ancestor.getParentIfKind(SyntaxKind.SourceFile);
|
|
668
|
+
});
|
|
669
|
+
if (!topLevelStatement) continue;
|
|
670
|
+
const topLevelStatementIndex = sourceStatements.indexOf(topLevelStatement);
|
|
671
|
+
if (topLevelStatementIndex === -1 || topLevelStatementIndex >= statementIndex) continue;
|
|
672
|
+
targetIndex = targetIndex === void 0 ? topLevelStatementIndex : Math.min(targetIndex, topLevelStatementIndex);
|
|
673
|
+
}
|
|
674
|
+
if (targetIndex === void 0) continue;
|
|
675
|
+
const statementText = variableStatement.getText();
|
|
676
|
+
variableStatement.remove();
|
|
677
|
+
sourceFile.insertStatements(targetIndex, [statementText]);
|
|
678
|
+
moved = true;
|
|
679
|
+
break;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return sourceFile;
|
|
683
|
+
}
|
|
684
|
+
function isReferenceInsideFunctionLike(referenceNode) {
|
|
685
|
+
return Boolean(referenceNode.getFirstAncestor((ancestor) => {
|
|
686
|
+
return Node.isArrowFunction(ancestor) || Node.isFunctionDeclaration(ancestor) || Node.isFunctionExpression(ancestor) || Node.isMethodDeclaration(ancestor) || Node.isGetAccessorDeclaration(ancestor) || Node.isSetAccessorDeclaration(ancestor);
|
|
687
|
+
}));
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
//#endregion
|
|
691
|
+
export { introspectGenerate };
|