@inkeep/agents-cli 0.0.0-dev-20260117013710 → 0.0.0-dev-20260117173149
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/commands/init.js +6 -6
- package/dist/commands/pull-v3/component-parser.js +0 -2
- package/dist/commands/pull-v3/component-updater.js +122 -64
- package/dist/commands/pull-v3/components/agent-generator.js +3 -3
- package/dist/commands/pull-v3/components/artifact-component-generator.js +7 -7
- package/dist/commands/pull-v3/components/context-config-generator.js +6 -6
- package/dist/commands/pull-v3/components/credential-generator.js +4 -4
- package/dist/commands/pull-v3/components/data-component-generator.js +4 -4
- package/dist/commands/pull-v3/components/environment-generator.js +10 -7
- package/dist/commands/pull-v3/components/function-tool-generator.js +5 -7
- package/dist/commands/pull-v3/components/mcp-tool-generator.js +5 -5
- package/dist/commands/pull-v3/components/project-generator.js +4 -4
- package/dist/commands/pull-v3/components/status-component-generator.js +6 -6
- package/dist/commands/pull-v3/index.js +22 -27
- package/dist/commands/pull-v3/introspect-generator.js +7 -7
- package/dist/commands/pull-v3/llm-content-merger.js +1 -1
- package/dist/commands/pull-v3/new-component-generator.js +5 -16
- package/dist/commands/pull-v3/project-comparator.js +49 -49
- package/dist/commands/pull-v3/project-validator.js +5 -4
- package/dist/commands/pull-v3/targeted-typescript-placeholders.js +2 -2
- package/dist/commands/pull-v3/utils/component-registry.js +4 -7
- package/dist/commands/pull-v3/utils/component-tracker.js +1 -1
- package/dist/commands/pull-v3/utils/generator-utils.js +2 -2
- package/dist/commands/push.js +5 -5
- package/dist/utils/ci-environment.js +1 -1
- package/dist/utils/config.js +1 -1
- package/dist/utils/json-comparison.js +3 -3
- package/dist/utils/profile-config.js +1 -1
- package/dist/utils/profiles/profile-manager.js +1 -1
- package/dist/utils/templates.js +0 -2
- package/package.json +6 -4
|
@@ -20,7 +20,7 @@ function toCamelCase(str) {
|
|
|
20
20
|
function formatString(str, quote = "'", multiline = false) {
|
|
21
21
|
if (!str) return `${quote}${quote}`;
|
|
22
22
|
if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
|
|
23
|
-
return `${quote}${str.replace(new RegExp(quote, "g"),
|
|
23
|
+
return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Convert JSON Schema to Zod schema using existing utility
|
|
@@ -80,7 +80,7 @@ function generateDataComponentDefinition(componentId, componentData, style = DEF
|
|
|
80
80
|
/**
|
|
81
81
|
* Generate imports needed for a data component file
|
|
82
82
|
*/
|
|
83
|
-
function generateDataComponentImports(
|
|
83
|
+
function generateDataComponentImports(componentData, style = DEFAULT_STYLE) {
|
|
84
84
|
const { quotes, semicolons } = style;
|
|
85
85
|
const q = quotes === "single" ? "'" : "\"";
|
|
86
86
|
const semi = semicolons ? ";" : "";
|
|
@@ -93,9 +93,9 @@ function generateDataComponentImports(componentId, componentData, style = DEFAUL
|
|
|
93
93
|
* Generate complete data component file (imports + definition)
|
|
94
94
|
*/
|
|
95
95
|
function generateDataComponentFile(componentId, componentData, style = DEFAULT_STYLE) {
|
|
96
|
-
const imports = generateDataComponentImports(
|
|
96
|
+
const imports = generateDataComponentImports(componentData, style);
|
|
97
97
|
const definition = generateDataComponentDefinition(componentId, componentData, style);
|
|
98
|
-
return imports.join("\n")
|
|
98
|
+
return `${imports.join("\n")}\n\n${definition}\n`;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
//#endregion
|
|
@@ -4,10 +4,13 @@ const DEFAULT_STYLE = {
|
|
|
4
4
|
semicolons: true,
|
|
5
5
|
indentation: " "
|
|
6
6
|
};
|
|
7
|
+
/**
|
|
8
|
+
* Utility functions
|
|
9
|
+
*/
|
|
7
10
|
function formatString(str, quote = "'", multiline = false) {
|
|
8
11
|
if (!str) return `${quote}${quote}`;
|
|
9
12
|
if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
|
|
10
|
-
return `${quote}${str.replace(new RegExp(quote, "g"),
|
|
13
|
+
return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
|
|
11
14
|
}
|
|
12
15
|
/**
|
|
13
16
|
* Format credentials object for environment settings
|
|
@@ -55,7 +58,7 @@ function formatCredentialsObject(credentials, style, indentLevel) {
|
|
|
55
58
|
function generateEnvironmentSettingsDefinition(environmentName, environmentData, style = DEFAULT_STYLE) {
|
|
56
59
|
if (!environmentName || typeof environmentName !== "string") throw new Error("environmentName is required and must be a string");
|
|
57
60
|
if (!environmentData || typeof environmentData !== "object") throw new Error(`environmentData is required for environment '${environmentName}'`);
|
|
58
|
-
const {
|
|
61
|
+
const { semicolons, indentation } = style;
|
|
59
62
|
const semi = semicolons ? ";" : "";
|
|
60
63
|
const lines = [];
|
|
61
64
|
lines.push(`export const ${environmentName} = registerEnvironmentSettings({`);
|
|
@@ -71,7 +74,7 @@ function generateEnvironmentSettingsDefinition(environmentName, environmentData,
|
|
|
71
74
|
* Generate Main Environment Settings Index (index.ts)
|
|
72
75
|
*/
|
|
73
76
|
function generateEnvironmentIndexDefinition(environments, style = DEFAULT_STYLE) {
|
|
74
|
-
const {
|
|
77
|
+
const { semicolons, indentation } = style;
|
|
75
78
|
const semi = semicolons ? ";" : "";
|
|
76
79
|
const lines = [];
|
|
77
80
|
lines.push(`export const envSettings = createEnvironmentSettings({`);
|
|
@@ -83,7 +86,7 @@ function generateEnvironmentIndexDefinition(environments, style = DEFAULT_STYLE)
|
|
|
83
86
|
/**
|
|
84
87
|
* Generate imports for individual environment settings file
|
|
85
88
|
*/
|
|
86
|
-
function generateEnvironmentSettingsImports(
|
|
89
|
+
function generateEnvironmentSettingsImports(environmentData, style = DEFAULT_STYLE) {
|
|
87
90
|
const { quotes, semicolons } = style;
|
|
88
91
|
const q = quotes === "single" ? "'" : "\"";
|
|
89
92
|
const semi = semicolons ? ";" : "";
|
|
@@ -112,9 +115,9 @@ function generateEnvironmentIndexImports(environments, style = DEFAULT_STYLE) {
|
|
|
112
115
|
* Generate complete environment settings file
|
|
113
116
|
*/
|
|
114
117
|
function generateEnvironmentSettingsFile(environmentName, environmentData, style = DEFAULT_STYLE) {
|
|
115
|
-
const imports = generateEnvironmentSettingsImports(
|
|
118
|
+
const imports = generateEnvironmentSettingsImports(environmentData, style);
|
|
116
119
|
const definition = generateEnvironmentSettingsDefinition(environmentName, environmentData, style);
|
|
117
|
-
return imports.join("\n")
|
|
120
|
+
return `${imports.join("\n")}\n\n${definition}\n`;
|
|
118
121
|
}
|
|
119
122
|
/**
|
|
120
123
|
* Generate complete environment index file
|
|
@@ -122,7 +125,7 @@ function generateEnvironmentSettingsFile(environmentName, environmentData, style
|
|
|
122
125
|
function generateEnvironmentIndexFile(environments, style = DEFAULT_STYLE) {
|
|
123
126
|
const imports = generateEnvironmentIndexImports(environments, style);
|
|
124
127
|
const definition = generateEnvironmentIndexDefinition(environments, style);
|
|
125
|
-
return imports.join("\n")
|
|
128
|
+
return `${imports.join("\n")}\n\n${definition}\n`;
|
|
126
129
|
}
|
|
127
130
|
/**
|
|
128
131
|
* Generate environment file (alias for generateEnvironmentSettingsFile)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { jsonSchemaToZod } from "json-schema-to-zod";
|
|
2
|
-
|
|
3
1
|
//#region src/commands/pull-v3/components/function-tool-generator.ts
|
|
4
2
|
const DEFAULT_STYLE = {
|
|
5
3
|
quotes: "single",
|
|
@@ -15,7 +13,7 @@ function toCamelCase(str) {
|
|
|
15
13
|
function formatString(str, quote = "'", multiline = false) {
|
|
16
14
|
if (!str) return `${quote}${quote}`;
|
|
17
15
|
if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
|
|
18
|
-
return `${quote}${str.replace(new RegExp(quote, "g"),
|
|
16
|
+
return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
|
|
19
17
|
}
|
|
20
18
|
/**
|
|
21
19
|
* Format JavaScript function code with proper indentation
|
|
@@ -54,7 +52,7 @@ function generateFunctionToolDefinition(toolId, toolData, style = DEFAULT_STYLE)
|
|
|
54
52
|
if (index === 0) return `${indentation}inputSchema: ${line}`;
|
|
55
53
|
return `${indentation}${line}`;
|
|
56
54
|
}).join("\n");
|
|
57
|
-
lines.push(formattedSchema
|
|
55
|
+
lines.push(`${formattedSchema},`);
|
|
58
56
|
}
|
|
59
57
|
const executeCode = toolData.executeCode || toolData.execute;
|
|
60
58
|
if (executeCode) {
|
|
@@ -73,7 +71,7 @@ function generateFunctionToolDefinition(toolId, toolData, style = DEFAULT_STYLE)
|
|
|
73
71
|
/**
|
|
74
72
|
* Generate imports needed for a function tool file
|
|
75
73
|
*/
|
|
76
|
-
function generateFunctionToolImports(
|
|
74
|
+
function generateFunctionToolImports(style = DEFAULT_STYLE) {
|
|
77
75
|
const { quotes, semicolons } = style;
|
|
78
76
|
const q = quotes === "single" ? "'" : "\"";
|
|
79
77
|
const semi = semicolons ? ";" : "";
|
|
@@ -85,9 +83,9 @@ function generateFunctionToolImports(toolId, toolData, style = DEFAULT_STYLE) {
|
|
|
85
83
|
* Generate complete function tool file (imports + definition)
|
|
86
84
|
*/
|
|
87
85
|
function generateFunctionToolFile(toolId, toolData, style = DEFAULT_STYLE) {
|
|
88
|
-
const imports = generateFunctionToolImports(
|
|
86
|
+
const imports = generateFunctionToolImports(style);
|
|
89
87
|
const definition = generateFunctionToolDefinition(toolId, toolData, style);
|
|
90
|
-
return imports.join("\n")
|
|
88
|
+
return `${imports.join("\n")}\n\n${definition}\n`;
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
//#endregion
|
|
@@ -13,7 +13,7 @@ function toCamelCase(str) {
|
|
|
13
13
|
function formatString(str, quote = "'", multiline = false) {
|
|
14
14
|
if (!str) return `${quote}${quote}`;
|
|
15
15
|
if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
|
|
16
|
-
return `${quote}${str.replace(new RegExp(quote, "g"),
|
|
16
|
+
return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* Generate MCP Tool Definition using mcpTool() builder function
|
|
@@ -47,7 +47,7 @@ function generateMcpToolDefinition(toolId, toolData, style = DEFAULT_STYLE, regi
|
|
|
47
47
|
if (index === 0) return `${indentation}headers: ${line}`;
|
|
48
48
|
return `${indentation}${line}`;
|
|
49
49
|
}).join("\n");
|
|
50
|
-
lines.push(formattedHeaders
|
|
50
|
+
lines.push(`${formattedHeaders},`);
|
|
51
51
|
}
|
|
52
52
|
if (toolData.credential) if (typeof toolData.credential === "object") {
|
|
53
53
|
const credentialStr = JSON.stringify(toolData.credential);
|
|
@@ -64,7 +64,7 @@ function generateMcpToolDefinition(toolId, toolData, style = DEFAULT_STYLE, regi
|
|
|
64
64
|
/**
|
|
65
65
|
* Generate imports needed for an MCP tool file
|
|
66
66
|
*/
|
|
67
|
-
function generateMcpToolImports(
|
|
67
|
+
function generateMcpToolImports(toolData, style = DEFAULT_STYLE) {
|
|
68
68
|
const { quotes, semicolons } = style;
|
|
69
69
|
const q = quotes === "single" ? "'" : "\"";
|
|
70
70
|
const semi = semicolons ? ";" : "";
|
|
@@ -77,9 +77,9 @@ function generateMcpToolImports(toolId, toolData, style = DEFAULT_STYLE) {
|
|
|
77
77
|
* Generate complete MCP tool file (imports + definition)
|
|
78
78
|
*/
|
|
79
79
|
function generateMcpToolFile(toolId, toolData, style = DEFAULT_STYLE, registry) {
|
|
80
|
-
const imports = generateMcpToolImports(
|
|
80
|
+
const imports = generateMcpToolImports(toolData, style);
|
|
81
81
|
const definition = generateMcpToolDefinition(toolId, toolData, style, registry);
|
|
82
|
-
return imports.join("\n")
|
|
82
|
+
return `${imports.join("\n")}\n\n${definition}\n`;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
//#endregion
|
|
@@ -62,7 +62,7 @@ function generateProjectDefinition(projectId, projectData, style = DEFAULT_STYLE
|
|
|
62
62
|
/**
|
|
63
63
|
* Generate imports needed for a project file
|
|
64
64
|
*/
|
|
65
|
-
function generateProjectImports(
|
|
65
|
+
function generateProjectImports(projectData, style = DEFAULT_STYLE, registry) {
|
|
66
66
|
const imports = [];
|
|
67
67
|
imports.push(generateImport(["project"], "@inkeep/agents-sdk", style));
|
|
68
68
|
if (registry) {
|
|
@@ -83,8 +83,8 @@ function generateProjectImports(projectId, projectData, style = DEFAULT_STYLE, r
|
|
|
83
83
|
else if (typeof projectData.tools === "object") toolIds = Object.keys(projectData.tools);
|
|
84
84
|
for (const toolId of toolIds) {
|
|
85
85
|
let componentType = "tools";
|
|
86
|
-
if (registry
|
|
87
|
-
else if (registry
|
|
86
|
+
if (registry?.get(toolId, "functionTools")) componentType = "functionTools";
|
|
87
|
+
else if (registry?.get(toolId, "tools")) componentType = "tools";
|
|
88
88
|
referencedComponents.push({
|
|
89
89
|
id: toolId,
|
|
90
90
|
type: componentType
|
|
@@ -138,7 +138,7 @@ function generateProjectImports(projectId, projectData, style = DEFAULT_STYLE, r
|
|
|
138
138
|
* Generate complete project file (imports + definition)
|
|
139
139
|
*/
|
|
140
140
|
function generateProjectFile(projectId, projectData, style = DEFAULT_STYLE, registry) {
|
|
141
|
-
return generateFileContent(generateProjectImports(
|
|
141
|
+
return generateFileContent(generateProjectImports(projectData, style, registry), [generateProjectDefinition(projectId, projectData, style, registry)]);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
//#endregion
|
|
@@ -21,7 +21,7 @@ function toCamelCase(str) {
|
|
|
21
21
|
function formatString(str, quote = "'", multiline = false) {
|
|
22
22
|
if (!str) return `${quote}${quote}`;
|
|
23
23
|
if (multiline && (str.includes("\n") || str.length > 80)) return `\`${str.replace(/`/g, "\\`")}\``;
|
|
24
|
-
return `${quote}${str.replace(new RegExp(quote, "g"),
|
|
24
|
+
return `${quote}${str.replace(new RegExp(quote, "g"), `\\${quote}`)}${quote}`;
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Convert JSON Schema to Zod schema using existing utility
|
|
@@ -58,9 +58,9 @@ function generateStatusComponentDefinition(componentId, componentData, style = D
|
|
|
58
58
|
const schemaLines = zodSchema.split("\n");
|
|
59
59
|
lines.push(`${indentation}detailsSchema: ${schemaLines[0]}`);
|
|
60
60
|
schemaLines.slice(1, -1).forEach((line) => {
|
|
61
|
-
lines[lines.length - 1] +=
|
|
61
|
+
lines[lines.length - 1] += `\n${indentation}${line}`;
|
|
62
62
|
});
|
|
63
|
-
lines[lines.length - 1] +=
|
|
63
|
+
lines[lines.length - 1] += `\n${indentation}${schemaLines[schemaLines.length - 1]},`;
|
|
64
64
|
} else lines.push(`${indentation}detailsSchema: ${zodSchema},`);
|
|
65
65
|
}
|
|
66
66
|
if (lines.length > 0 && lines[lines.length - 1].endsWith(",")) lines[lines.length - 1] = lines[lines.length - 1].slice(0, -1);
|
|
@@ -70,7 +70,7 @@ function generateStatusComponentDefinition(componentId, componentData, style = D
|
|
|
70
70
|
/**
|
|
71
71
|
* Generate imports needed for a status component file
|
|
72
72
|
*/
|
|
73
|
-
function generateStatusComponentImports(
|
|
73
|
+
function generateStatusComponentImports(componentData, style = DEFAULT_STYLE) {
|
|
74
74
|
const { quotes, semicolons } = style;
|
|
75
75
|
const q = quotes === "single" ? "'" : "\"";
|
|
76
76
|
const semi = semicolons ? ";" : "";
|
|
@@ -83,9 +83,9 @@ function generateStatusComponentImports(componentId, componentData, style = DEFA
|
|
|
83
83
|
* Generate complete status component file (imports + definition)
|
|
84
84
|
*/
|
|
85
85
|
function generateStatusComponentFile(componentId, componentData, style = DEFAULT_STYLE) {
|
|
86
|
-
const imports = generateStatusComponentImports(
|
|
86
|
+
const imports = generateStatusComponentImports(componentData, style);
|
|
87
87
|
const definition = generateStatusComponentDefinition(componentId, componentData, style);
|
|
88
|
-
return imports.join("\n")
|
|
88
|
+
return `${imports.join("\n")}\n\n${definition}\n`;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
//#endregion
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { ManagementApiClient } from "../../api.js";
|
|
2
|
-
import "../../utils/config.js";
|
|
3
2
|
import { initializeCommand } from "../../utils/cli-pipeline.js";
|
|
4
3
|
import { performBackgroundVersionCheck } from "../../utils/background-version-check.js";
|
|
5
|
-
import "../../utils/json-comparison.js";
|
|
6
4
|
import { loadProject } from "../../utils/project-loader.js";
|
|
7
5
|
import { extractSubAgents } from "./utils/component-registry.js";
|
|
8
|
-
import { compareProjects } from "./project-comparator.js";
|
|
9
6
|
import { checkAndPromptForStaleComponentCleanup, cleanupStaleComponents, copyProjectToTemp } from "./component-updater.js";
|
|
10
7
|
import { introspectGenerate } from "./introspect-generator.js";
|
|
8
|
+
import { compareProjects } from "./project-comparator.js";
|
|
11
9
|
import { existsSync, mkdirSync } from "node:fs";
|
|
12
|
-
import {
|
|
10
|
+
import { join, resolve } from "node:path";
|
|
13
11
|
import * as p from "@clack/prompts";
|
|
14
12
|
import chalk from "chalk";
|
|
15
13
|
import { EventEmitter } from "node:events";
|
|
@@ -38,7 +36,7 @@ function resetStdinState() {
|
|
|
38
36
|
/**
|
|
39
37
|
* Create project directory structure
|
|
40
38
|
*/
|
|
41
|
-
function createProjectStructure(projectDir
|
|
39
|
+
function createProjectStructure(projectDir) {
|
|
42
40
|
const projectRoot = projectDir;
|
|
43
41
|
const paths = {
|
|
44
42
|
projectRoot,
|
|
@@ -60,11 +58,11 @@ function createProjectStructure(projectDir, projectId) {
|
|
|
60
58
|
/**
|
|
61
59
|
* Enrich canDelegateTo references with component type information
|
|
62
60
|
*/
|
|
63
|
-
function enrichCanDelegateToWithTypes(project
|
|
61
|
+
function enrichCanDelegateToWithTypes(project) {
|
|
64
62
|
const agentIds = new Set(project.agents ? Object.keys(project.agents) : []);
|
|
65
63
|
const subAgentIds = new Set(Object.keys(extractSubAgents(project)));
|
|
66
64
|
const externalAgentIds = new Set(project.externalAgents ? Object.keys(project.externalAgents) : []);
|
|
67
|
-
const enrichCanDelegateToArray = (canDelegateTo
|
|
65
|
+
const enrichCanDelegateToArray = (canDelegateTo) => {
|
|
68
66
|
if (!Array.isArray(canDelegateTo)) return;
|
|
69
67
|
for (let i = 0; i < canDelegateTo.length; i++) {
|
|
70
68
|
const item = canDelegateTo[i];
|
|
@@ -79,15 +77,15 @@ function enrichCanDelegateToWithTypes(project, debug = false) {
|
|
|
79
77
|
}
|
|
80
78
|
};
|
|
81
79
|
if (project.agents) {
|
|
82
|
-
for (const
|
|
83
|
-
for (const
|
|
80
|
+
for (const agentData of Object.values(project.agents)) if (agentData.subAgents) {
|
|
81
|
+
for (const subAgentData of Object.values(agentData.subAgents)) if (subAgentData.canDelegateTo) enrichCanDelegateToArray(subAgentData.canDelegateTo);
|
|
84
82
|
}
|
|
85
83
|
}
|
|
86
84
|
}
|
|
87
85
|
/**
|
|
88
86
|
* Read existing project from filesystem if it exists
|
|
89
87
|
*/
|
|
90
|
-
async function readExistingProject(projectRoot
|
|
88
|
+
async function readExistingProject(projectRoot) {
|
|
91
89
|
if (!existsSync(join(projectRoot, "index.ts"))) return null;
|
|
92
90
|
try {
|
|
93
91
|
const { loadProject: loadProject$1 } = await import("../../utils/project-loader.js");
|
|
@@ -97,9 +95,7 @@ async function readExistingProject(projectRoot, debug = false) {
|
|
|
97
95
|
reject(/* @__PURE__ */ new Error("getFullDefinition() timed out after 30 seconds - likely circular reference or infinite loop in local project"));
|
|
98
96
|
}, 3e4);
|
|
99
97
|
})]);
|
|
100
|
-
} catch
|
|
101
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
102
|
-
errorMessage.includes("Credential") && errorMessage.includes("not found");
|
|
98
|
+
} catch {
|
|
103
99
|
return null;
|
|
104
100
|
}
|
|
105
101
|
}
|
|
@@ -125,7 +121,7 @@ async function pullV3Command(options) {
|
|
|
125
121
|
else console.log(chalk.gray(" Smart comparison • Detect all changes • Targeted updates"));
|
|
126
122
|
const s = p.spinner();
|
|
127
123
|
try {
|
|
128
|
-
const { config,
|
|
124
|
+
const { config, isCI } = await initializeCommand({
|
|
129
125
|
configPath: options.config,
|
|
130
126
|
profileName: options.profile,
|
|
131
127
|
tag: options.tag,
|
|
@@ -219,21 +215,20 @@ async function pullV3Command(options) {
|
|
|
219
215
|
}
|
|
220
216
|
if (remoteProject.agents && remoteProject.tools) {
|
|
221
217
|
const projectToolIds = Object.keys(remoteProject.tools);
|
|
222
|
-
for (const
|
|
223
|
-
Object.keys(agentData.tools).length;
|
|
218
|
+
for (const agentData of Object.values(remoteProject.agents)) if (agentData.tools) {
|
|
224
219
|
const agentSpecificTools = Object.fromEntries(Object.entries(agentData.tools).filter(([toolId]) => !projectToolIds.includes(toolId)));
|
|
225
220
|
if (Object.keys(agentSpecificTools).length > 0) agentData.tools = agentSpecificTools;
|
|
226
221
|
else delete agentData.tools;
|
|
227
222
|
}
|
|
228
223
|
}
|
|
229
|
-
enrichCanDelegateToWithTypes(remoteProject
|
|
224
|
+
enrichCanDelegateToWithTypes(remoteProject);
|
|
230
225
|
s.message("Project data fetched");
|
|
231
226
|
if (options.json) {
|
|
232
227
|
console.log(JSON.stringify(remoteProject, null, 2));
|
|
233
228
|
restoreLogLevel();
|
|
234
229
|
return;
|
|
235
230
|
}
|
|
236
|
-
const paths = createProjectStructure(projectDir
|
|
231
|
+
const paths = createProjectStructure(projectDir);
|
|
237
232
|
if (options.introspect) {
|
|
238
233
|
console.log(chalk.yellow("\n🔍 Introspect mode: Regenerating all files from scratch"));
|
|
239
234
|
s.start("Generating all files deterministically...");
|
|
@@ -247,7 +242,7 @@ async function pullV3Command(options) {
|
|
|
247
242
|
if (batchMode) return { success: true };
|
|
248
243
|
process.exit(0);
|
|
249
244
|
}
|
|
250
|
-
const localProject = await readExistingProject(paths.projectRoot
|
|
245
|
+
const localProject = await readExistingProject(paths.projectRoot);
|
|
251
246
|
if (!localProject) s.message("No existing project found - treating as new project");
|
|
252
247
|
else s.message("Existing project loaded");
|
|
253
248
|
s.start("Building component registry from local files...");
|
|
@@ -261,7 +256,7 @@ async function pullV3Command(options) {
|
|
|
261
256
|
const nameGroups = /* @__PURE__ */ new Map();
|
|
262
257
|
for (const comp of allComponents) {
|
|
263
258
|
if (!nameGroups.has(comp.name)) nameGroups.set(comp.name, []);
|
|
264
|
-
nameGroups.get(comp.name)
|
|
259
|
+
nameGroups.get(comp.name)?.push(comp);
|
|
265
260
|
}
|
|
266
261
|
for (const [varName, components] of nameGroups.entries()) if (components.length > 1) {
|
|
267
262
|
console.log(chalk.red(` ❌ Variable name conflict: "${varName}"`));
|
|
@@ -269,7 +264,7 @@ async function pullV3Command(options) {
|
|
|
269
264
|
} else console.log(chalk.gray(` ✅ ${varName} (${components[0].type}:${components[0].id})`));
|
|
270
265
|
}
|
|
271
266
|
s.start("Comparing projects for changes...");
|
|
272
|
-
const comparison = await compareProjects(localProject, remoteProject,
|
|
267
|
+
const comparison = await compareProjects(localProject, remoteProject, options.debug);
|
|
273
268
|
if (!comparison.hasChanges && !options.force) {
|
|
274
269
|
s.stop();
|
|
275
270
|
console.log(chalk.green("✅ Project is already up to date"));
|
|
@@ -289,7 +284,7 @@ async function pullV3Command(options) {
|
|
|
289
284
|
copyProjectToTemp(paths.projectRoot, tempDirName);
|
|
290
285
|
console.log(chalk.green(`✅ Existing project copied to temp directory`));
|
|
291
286
|
s.start("Checking for stale components...");
|
|
292
|
-
const shouldCleanupStale = await checkAndPromptForStaleComponentCleanup(
|
|
287
|
+
const shouldCleanupStale = await checkAndPromptForStaleComponentCleanup(remoteProject, localRegistry);
|
|
293
288
|
resetStdinState();
|
|
294
289
|
if (shouldCleanupStale) {
|
|
295
290
|
s.start("Cleaning up stale components from temp directory...");
|
|
@@ -315,7 +310,7 @@ async function pullV3Command(options) {
|
|
|
315
310
|
const nameGroups = /* @__PURE__ */ new Map();
|
|
316
311
|
for (const comp of allComponents) {
|
|
317
312
|
if (!nameGroups.has(comp.name)) nameGroups.set(comp.name, []);
|
|
318
|
-
nameGroups.get(comp.name)
|
|
313
|
+
nameGroups.get(comp.name)?.push(comp);
|
|
319
314
|
}
|
|
320
315
|
for (const [varName, components] of nameGroups.entries()) if (components.length > 1) {
|
|
321
316
|
console.log(chalk.red(` ❌ Variable name conflict: "${varName}"`));
|
|
@@ -333,9 +328,9 @@ async function pullV3Command(options) {
|
|
|
333
328
|
const newComponentsForContext = newComponentResults && newComponentResults.length > 0 ? newComponentResults.filter((result) => result.success).map((result) => ({
|
|
334
329
|
componentId: result.componentId,
|
|
335
330
|
componentType: result.componentType,
|
|
336
|
-
filePath: result.filePath.replace(paths.projectRoot
|
|
331
|
+
filePath: result.filePath.replace(`${paths.projectRoot}/`, "")
|
|
337
332
|
})) : void 0;
|
|
338
|
-
await updateModifiedComponents(comparison, remoteProject, localRegistry, paths.projectRoot, options.
|
|
333
|
+
await updateModifiedComponents(comparison, remoteProject, localRegistry, paths.projectRoot, options.debug, tempDirName, newComponentsForContext);
|
|
339
334
|
}
|
|
340
335
|
s.start("Generating project index file in temp directory...");
|
|
341
336
|
const { generateProjectIndex } = await import("./project-index-generator.js");
|
|
@@ -380,7 +375,7 @@ async function pullAllProjects(options) {
|
|
|
380
375
|
console.log(chalk.gray(" • Existing projects: Smart comparison + LLM merging + confirmation prompts"));
|
|
381
376
|
console.log(chalk.gray(" • New projects: Fresh generation with introspect mode\n"));
|
|
382
377
|
performBackgroundVersionCheck();
|
|
383
|
-
const { config,
|
|
378
|
+
const { config, isCI } = await initializeCommand({
|
|
384
379
|
configPath: options.config,
|
|
385
380
|
profileName: options.profile,
|
|
386
381
|
tag: options.tag,
|
|
@@ -487,7 +482,7 @@ async function pullSingleProject(projectId, projectName, options, config, isCI)
|
|
|
487
482
|
else delete process.env.LOG_LEVEL;
|
|
488
483
|
};
|
|
489
484
|
const remoteProject = await (await ManagementApiClient.create(config.agentsManageApiUrl, options.config, config.tenantId, projectId, isCI, config.agentsManageApiKey)).getFullProject(projectId);
|
|
490
|
-
await introspectGenerate(remoteProject, createProjectStructure(targetDir
|
|
485
|
+
await introspectGenerate(remoteProject, createProjectStructure(targetDir), options.env || "development", false);
|
|
491
486
|
restoreLogLevel();
|
|
492
487
|
return {
|
|
493
488
|
projectId,
|
|
@@ -33,7 +33,7 @@ function ensureDir(filePath) {
|
|
|
33
33
|
* Check if an agent is complete enough for code generation
|
|
34
34
|
* An agent needs a name, defaultSubAgentId, and at least one sub-agent
|
|
35
35
|
*/
|
|
36
|
-
function isAgentComplete(
|
|
36
|
+
function isAgentComplete(agentData) {
|
|
37
37
|
if (!agentData.name) return {
|
|
38
38
|
complete: false,
|
|
39
39
|
reason: "missing name"
|
|
@@ -102,7 +102,7 @@ async function introspectGenerate(project, paths, environment, debug, options =
|
|
|
102
102
|
generatedFiles.push(functionFile);
|
|
103
103
|
functionToolsGenerated.add(toolId);
|
|
104
104
|
}
|
|
105
|
-
if (project.agents) for (const
|
|
105
|
+
if (project.agents) for (const agentData of Object.values(project.agents)) {
|
|
106
106
|
const agentFunctionTools = agentData.functionTools;
|
|
107
107
|
const agentFunctions = agentData.functions;
|
|
108
108
|
if (agentFunctionTools) for (const [toolId, toolData] of Object.entries(agentFunctionTools)) {
|
|
@@ -126,7 +126,7 @@ async function introspectGenerate(project, paths, environment, debug, options =
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
if (project.functions) {
|
|
129
|
-
for (const
|
|
129
|
+
for (const funcId of Object.keys(project.functions)) if (!functionToolsGenerated.has(funcId)) {
|
|
130
130
|
if (!(Object.values(project.functionTools || {}).some((ft) => ft.functionId === funcId) || Object.values(project.agents || {}).some((agent) => Object.values(agent.functionTools || {}).some((ft) => ft.functionId === funcId))) && debug) console.log(chalk.yellow(`⚠️ Skipping orphaned function '${funcId}' - no functionTool references it`));
|
|
131
131
|
}
|
|
132
132
|
}
|
|
@@ -182,7 +182,7 @@ async function introspectGenerate(project, paths, environment, debug, options =
|
|
|
182
182
|
}
|
|
183
183
|
const completeAgentIds = /* @__PURE__ */ new Set();
|
|
184
184
|
if (project.agents) for (const [agentId, agentData] of Object.entries(project.agents)) {
|
|
185
|
-
const completeness = isAgentComplete(
|
|
185
|
+
const completeness = isAgentComplete(agentData);
|
|
186
186
|
if (completeness.complete) completeAgentIds.add(agentId);
|
|
187
187
|
else {
|
|
188
188
|
skippedAgents.push({
|
|
@@ -196,7 +196,7 @@ async function introspectGenerate(project, paths, environment, debug, options =
|
|
|
196
196
|
let totalSubAgents = 0;
|
|
197
197
|
for (const [agentId, agentData] of Object.entries(project.agents)) {
|
|
198
198
|
if (!completeAgentIds.has(agentId)) continue;
|
|
199
|
-
if (agentData.subAgents) for (const
|
|
199
|
+
if (agentData.subAgents) for (const _subAgentId of Object.keys(agentData.subAgents)) totalSubAgents++;
|
|
200
200
|
}
|
|
201
201
|
if (totalSubAgents > 0) for (const [agentId, agentData] of Object.entries(project.agents)) {
|
|
202
202
|
if (!completeAgentIds.has(agentId)) continue;
|
|
@@ -251,7 +251,7 @@ async function introspectGenerate(project, paths, environment, debug, options =
|
|
|
251
251
|
*/
|
|
252
252
|
function findContextConfigData(project, contextId) {
|
|
253
253
|
if (project.agents) {
|
|
254
|
-
for (const
|
|
254
|
+
for (const agentData of Object.values(project.agents)) if (agentData.contextConfig) {
|
|
255
255
|
if (agentData.contextConfig.id === contextId) return agentData.contextConfig;
|
|
256
256
|
}
|
|
257
257
|
}
|
|
@@ -261,7 +261,7 @@ function findContextConfigData(project, contextId) {
|
|
|
261
261
|
*/
|
|
262
262
|
function findStatusComponentData(project, statusId) {
|
|
263
263
|
if (project.agents) {
|
|
264
|
-
for (const
|
|
264
|
+
for (const agentData of Object.values(project.agents)) if (agentData.statusUpdates?.statusComponents) for (const statusComp of agentData.statusUpdates.statusComponents) {
|
|
265
265
|
let compId;
|
|
266
266
|
if (typeof statusComp === "string") compId = statusComp;
|
|
267
267
|
else if (typeof statusComp === "object" && statusComp) compId = statusComp.type;
|
|
@@ -54,7 +54,7 @@ async function mergeComponentsWithLLM(request) {
|
|
|
54
54
|
let relativePath = "";
|
|
55
55
|
for (let i = 0; i < upLevels; i++) relativePath += "../";
|
|
56
56
|
relativePath += toParts.slice(commonLength).join("/");
|
|
57
|
-
return relativePath.startsWith("../") ? relativePath :
|
|
57
|
+
return relativePath.startsWith("../") ? relativePath : `./${relativePath}`;
|
|
58
58
|
}
|
|
59
59
|
const componentsToExportList = componentsToExport && componentsToExport.length > 0 ? componentsToExport.map((c) => `- ${c.variableName} (${c.reason})`).join("\n") : "";
|
|
60
60
|
const prompt = `You are a TypeScript code expert tasked with intelligently merging component updates.
|
|
@@ -75,10 +75,9 @@ function generateComponentContent(componentType, componentId, componentData, com
|
|
|
75
75
|
case "functionTools": return generateFunctionToolFile(componentId, componentData, defaultStyle);
|
|
76
76
|
case "credentials": return generateCredentialFile(componentId, componentData, defaultStyle);
|
|
77
77
|
case "contextConfigs": {
|
|
78
|
-
const agentId = componentData._agentId;
|
|
79
78
|
const cleanComponentData = { ...componentData };
|
|
80
79
|
delete cleanComponentData._agentId;
|
|
81
|
-
return generateContextConfigFile(componentId, cleanComponentData, defaultStyle, componentRegistry
|
|
80
|
+
return generateContextConfigFile(componentId, cleanComponentData, defaultStyle, componentRegistry);
|
|
82
81
|
}
|
|
83
82
|
default: throw new Error(`No generator for component type: ${componentType}`);
|
|
84
83
|
}
|
|
@@ -132,7 +131,7 @@ async function createNewComponents(comparison, remoteProject, localRegistry, pat
|
|
|
132
131
|
const addedComponents = changes.added || [];
|
|
133
132
|
for (const componentId of addedComponents) {
|
|
134
133
|
if (localRegistry.get(componentId, componentType)) continue;
|
|
135
|
-
const relativePath = determineNewFilePath(componentType, componentId, targetPaths).replace(
|
|
134
|
+
const relativePath = determineNewFilePath(componentType, componentId, targetPaths).replace(`${tempDirName ? targetPaths.projectRoot : paths.projectRoot}/`, "");
|
|
136
135
|
let explicitVariableName;
|
|
137
136
|
if (componentType === "contextConfigs") {
|
|
138
137
|
const contextResult = findContextConfigData(remoteProject, componentId);
|
|
@@ -192,18 +191,8 @@ async function createNewComponents(comparison, remoteProject, localRegistry, pat
|
|
|
192
191
|
});
|
|
193
192
|
continue;
|
|
194
193
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
} catch (dirError) {
|
|
198
|
-
throw dirError;
|
|
199
|
-
}
|
|
200
|
-
let content;
|
|
201
|
-
try {
|
|
202
|
-
content = generateComponentContent(componentType, componentId, componentData, localRegistry);
|
|
203
|
-
} catch (genError) {
|
|
204
|
-
throw genError;
|
|
205
|
-
}
|
|
206
|
-
writeFileSync(filePath, content, "utf8");
|
|
194
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
195
|
+
writeFileSync(filePath, generateComponentContent(componentType, componentId, componentData, localRegistry), "utf8");
|
|
207
196
|
const registryEntry = localRegistry.get(componentId, componentType);
|
|
208
197
|
if (!registryEntry) throw new Error(`Component ${componentId} (${componentType}) was not registered in the registry`);
|
|
209
198
|
const variableName = registryEntry.name;
|
|
@@ -259,7 +248,7 @@ async function createNewComponents(comparison, remoteProject, localRegistry, pat
|
|
|
259
248
|
*/
|
|
260
249
|
function findStatusComponentData(project, statusId) {
|
|
261
250
|
if (project.agents) {
|
|
262
|
-
for (const
|
|
251
|
+
for (const agentData of Object.values(project.agents)) if (agentData.statusUpdates?.statusComponents) for (const statusComp of agentData.statusUpdates.statusComponents) {
|
|
263
252
|
let compId;
|
|
264
253
|
if (typeof statusComp === "string") compId = statusComp;
|
|
265
254
|
else if (typeof statusComp === "object" && statusComp) compId = statusComp.type;
|