@inkeep/agents-cli 0.59.3 → 0.59.4
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 +1 -1
- package/dist/commands/pull-v4/collector-common.js +128 -0
- package/dist/commands/pull-v4/collector-common.js.map +1 -0
- package/dist/commands/pull-v4/collector-reference-helpers.js +323 -0
- package/dist/commands/pull-v4/collector-reference-helpers.js.map +1 -0
- package/dist/commands/pull-v4/component-parser.js +2 -1
- package/dist/commands/pull-v4/component-parser.js.map +1 -1
- package/dist/commands/pull-v4/file-scope.js +43 -0
- package/dist/commands/pull-v4/file-scope.js.map +1 -0
- package/dist/commands/pull-v4/generation-resolver.js +305 -0
- package/dist/commands/pull-v4/generation-resolver.js.map +1 -0
- package/dist/commands/pull-v4/generation-types.js +56 -0
- package/dist/commands/pull-v4/generation-types.js.map +1 -0
- package/dist/commands/pull-v4/generators/agent-generator.helpers.js +4 -10
- package/dist/commands/pull-v4/generators/agent-generator.helpers.js.map +1 -1
- package/dist/commands/pull-v4/generators/agent-generator.js +154 -81
- package/dist/commands/pull-v4/generators/agent-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/artifact-component-generator.js +48 -27
- package/dist/commands/pull-v4/generators/artifact-component-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/context-config-generator.js +147 -129
- package/dist/commands/pull-v4/generators/context-config-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/credential-generator.js +36 -14
- package/dist/commands/pull-v4/generators/credential-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/data-component-generator.js +55 -19
- package/dist/commands/pull-v4/generators/data-component-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/environment-generator.js +29 -33
- package/dist/commands/pull-v4/generators/environment-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/environment-settings-generator.js +57 -0
- package/dist/commands/pull-v4/generators/environment-settings-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/external-agent-generator.js +51 -23
- package/dist/commands/pull-v4/generators/external-agent-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/function-tool-generator.js +50 -14
- package/dist/commands/pull-v4/generators/function-tool-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/helpers/agent.js +129 -0
- package/dist/commands/pull-v4/generators/helpers/agent.js.map +1 -0
- package/dist/commands/pull-v4/generators/helpers/sub-agent.js +65 -0
- package/dist/commands/pull-v4/generators/helpers/sub-agent.js.map +1 -0
- package/dist/commands/pull-v4/generators/index.js +38 -0
- package/dist/commands/pull-v4/generators/index.js.map +1 -0
- package/dist/commands/pull-v4/generators/mcp-tool-generator.js +48 -27
- package/dist/commands/pull-v4/generators/mcp-tool-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/project-generator.js +144 -110
- package/dist/commands/pull-v4/generators/project-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/scheduled-trigger-generator.js +66 -0
- package/dist/commands/pull-v4/generators/scheduled-trigger-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/status-component-generator.js +55 -20
- package/dist/commands/pull-v4/generators/status-component-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/sub-agent-generator.helpers.js +4 -1
- package/dist/commands/pull-v4/generators/sub-agent-generator.helpers.js.map +1 -1
- package/dist/commands/pull-v4/generators/sub-agent-generator.js +282 -166
- package/dist/commands/pull-v4/generators/sub-agent-generator.js.map +1 -1
- package/dist/commands/pull-v4/generators/trigger-generator.js +62 -27
- package/dist/commands/pull-v4/generators/trigger-generator.js.map +1 -1
- package/dist/commands/pull-v4/import-plan.js +40 -0
- package/dist/commands/pull-v4/import-plan.js.map +1 -0
- package/dist/commands/pull-v4/introspect/index.js +11 -7
- package/dist/commands/pull-v4/introspect/index.js.map +1 -1
- package/dist/commands/pull-v4/introspect-generator.js +15 -1218
- package/dist/commands/pull-v4/introspect-generator.js.map +1 -1
- package/dist/commands/pull-v4/module-merge.js +14 -5
- package/dist/commands/pull-v4/module-merge.js.map +1 -1
- package/dist/commands/pull-v4/reference-resolution.js +111 -0
- package/dist/commands/pull-v4/reference-resolution.js.map +1 -0
- package/dist/commands/pull-v4/simple-factory-generator.js +54 -0
- package/dist/commands/pull-v4/simple-factory-generator.js.map +1 -0
- package/dist/commands/pull-v4/{generators/skill-generator.js → skill.js} +18 -6
- package/dist/commands/pull-v4/skill.js.map +1 -0
- package/dist/commands/pull-v4/typescript-file-writer.js +78 -0
- package/dist/commands/pull-v4/typescript-file-writer.js.map +1 -0
- package/dist/commands/pull-v4/utils/code-values.js +64 -0
- package/dist/commands/pull-v4/utils/code-values.js.map +1 -0
- package/dist/commands/pull-v4/utils/factory-writer.js +128 -0
- package/dist/commands/pull-v4/utils/factory-writer.js.map +1 -0
- package/dist/commands/pull-v4/utils/index.js +8 -0
- package/dist/commands/pull-v4/utils/naming.js +74 -0
- package/dist/commands/pull-v4/utils/naming.js.map +1 -0
- package/dist/commands/pull-v4/utils/schema-rendering.js +20 -0
- package/dist/commands/pull-v4/utils/schema-rendering.js.map +1 -0
- package/dist/commands/pull-v4/utils/shared.js +18 -0
- package/dist/commands/pull-v4/utils/shared.js.map +1 -0
- package/dist/commands/pull-v4/utils/templates.js +58 -0
- package/dist/commands/pull-v4/utils/templates.js.map +1 -0
- package/package.json +4 -4
- package/dist/commands/pull-v4/generators/skill-generator.js.map +0 -1
- package/dist/commands/pull-v4/scheduled-trigger-generator.js +0 -38
- package/dist/commands/pull-v4/scheduled-trigger-generator.js.map +0 -1
- package/dist/commands/pull-v4/utils.js +0 -320
- package/dist/commands/pull-v4/utils.js.map +0 -1
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { codeReference } from "../utils/code-values.js";
|
|
2
|
+
import { toCamelCase, toTriggerReferenceName } from "../utils/naming.js";
|
|
3
|
+
import { addValueToObject } from "../utils/factory-writer.js";
|
|
4
|
+
import "../utils/index.js";
|
|
5
|
+
import { asRecord } from "../collector-common.js";
|
|
6
|
+
import { buildSequentialNameFileNames } from "../generation-resolver.js";
|
|
7
|
+
import { generateFactorySourceFile } from "../simple-factory-generator.js";
|
|
8
|
+
import { addNamedImports, applyImportPlan, createImportPlan } from "../import-plan.js";
|
|
2
9
|
import { FullProjectDefinitionSchema } from "@inkeep/agents-core";
|
|
3
10
|
import { z } from "zod";
|
|
11
|
+
import { join } from "node:path";
|
|
4
12
|
import { SyntaxKind } from "ts-morph";
|
|
5
13
|
|
|
6
14
|
//#region src/commands/pull-v4/generators/trigger-generator.ts
|
|
@@ -18,34 +26,61 @@ const TriggerSchema = z.strictObject({
|
|
|
18
26
|
signingSecretCredentialReferencePath: z.string().nonempty().optional()
|
|
19
27
|
});
|
|
20
28
|
function generateTriggerDefinition({ id, runAsUserId, createdBy, ...data }) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
return generateFactorySourceFile(data, {
|
|
30
|
+
schema: TriggerSchema,
|
|
31
|
+
factory: {
|
|
32
|
+
importName: "Trigger",
|
|
33
|
+
variableName: (parsed) => toTriggerReferenceName(parsed.name),
|
|
34
|
+
syntaxKind: SyntaxKind.NewExpression
|
|
35
|
+
},
|
|
36
|
+
render({ parsed, sourceFile, configObject }) {
|
|
37
|
+
const { triggerId, signingSecretCredentialReferenceId, signingSecretCredentialReferenceName, signingSecretCredentialReferencePath, ...rest } = parsed;
|
|
38
|
+
for (const [key, value] of Object.entries({
|
|
39
|
+
id: triggerId,
|
|
40
|
+
...rest
|
|
41
|
+
})) addValueToObject(configObject, key, value);
|
|
42
|
+
const importPlan = createImportPlan();
|
|
43
|
+
if (signingSecretCredentialReferenceId) {
|
|
44
|
+
const varName = signingSecretCredentialReferenceName ?? toCamelCase(signingSecretCredentialReferenceId);
|
|
45
|
+
addNamedImports(importPlan, `../../credentials/${signingSecretCredentialReferencePath ?? signingSecretCredentialReferenceId}`, varName);
|
|
46
|
+
addValueToObject(configObject, "signingSecretCredentialReference", codeReference(varName));
|
|
47
|
+
}
|
|
48
|
+
applyImportPlan(sourceFile, importPlan);
|
|
49
|
+
}
|
|
28
50
|
});
|
|
29
|
-
const { triggerId, signingSecretCredentialReferenceId, signingSecretCredentialReferenceName, signingSecretCredentialReferencePath, ...rest } = parsed;
|
|
30
|
-
for (const [key, value] of Object.entries({
|
|
31
|
-
id: triggerId,
|
|
32
|
-
...rest
|
|
33
|
-
})) addValueToObject(configObject, key, value);
|
|
34
|
-
if (signingSecretCredentialReferenceId) {
|
|
35
|
-
const varName = signingSecretCredentialReferenceName ?? toCamelCase(signingSecretCredentialReferenceId);
|
|
36
|
-
const modulePath = signingSecretCredentialReferencePath ?? signingSecretCredentialReferenceId;
|
|
37
|
-
sourceFile.addImportDeclaration({
|
|
38
|
-
namedImports: [varName],
|
|
39
|
-
moduleSpecifier: `../../credentials/${modulePath}`
|
|
40
|
-
});
|
|
41
|
-
configObject.addPropertyAssignment({
|
|
42
|
-
name: "signingSecretCredentialReference",
|
|
43
|
-
initializer: varName
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
return sourceFile;
|
|
47
51
|
}
|
|
52
|
+
const task = {
|
|
53
|
+
type: "trigger",
|
|
54
|
+
collect(context) {
|
|
55
|
+
if (!context.project.agents) return [];
|
|
56
|
+
const records = [];
|
|
57
|
+
for (const agentId of context.completeAgentIds) {
|
|
58
|
+
const agentData = context.project.agents[agentId];
|
|
59
|
+
if (!agentData?.triggers) continue;
|
|
60
|
+
const triggerEntries = Object.entries(agentData.triggers);
|
|
61
|
+
const fileNamesByTriggerId = buildSequentialNameFileNames(triggerEntries);
|
|
62
|
+
for (const [triggerId, triggerData] of triggerEntries) {
|
|
63
|
+
const triggerRecord = asRecord(triggerData);
|
|
64
|
+
const signingSecretCredentialReferenceId = typeof triggerRecord?.signingSecretCredentialReferenceId === "string" ? triggerRecord.signingSecretCredentialReferenceId : void 0;
|
|
65
|
+
const signingSecretCredentialReferenceName = signingSecretCredentialReferenceId ? context.resolver.getCredentialReferenceName(signingSecretCredentialReferenceId) : void 0;
|
|
66
|
+
const signingSecretCredentialReferencePath = signingSecretCredentialReferenceId ? context.resolver.getCredentialReferencePath(signingSecretCredentialReferenceId) : void 0;
|
|
67
|
+
records.push({
|
|
68
|
+
id: triggerId,
|
|
69
|
+
filePath: context.resolver.resolveOutputFilePath("triggers", triggerId, join(context.paths.agentsDir, "triggers", fileNamesByTriggerId[triggerId])),
|
|
70
|
+
payload: {
|
|
71
|
+
triggerId,
|
|
72
|
+
...triggerData,
|
|
73
|
+
...signingSecretCredentialReferenceName && { signingSecretCredentialReferenceName },
|
|
74
|
+
...signingSecretCredentialReferencePath && { signingSecretCredentialReferencePath }
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return records;
|
|
80
|
+
},
|
|
81
|
+
generate: generateTriggerDefinition
|
|
82
|
+
};
|
|
48
83
|
|
|
49
84
|
//#endregion
|
|
50
|
-
export { generateTriggerDefinition };
|
|
85
|
+
export { generateTriggerDefinition, task };
|
|
51
86
|
//# sourceMappingURL=trigger-generator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trigger-generator.js","names":[],"sources":["../../../../src/commands/pull-v4/generators/trigger-generator.ts"],"sourcesContent":["import { FullProjectDefinitionSchema } from '@inkeep/agents-core';\nimport { type SourceFile, SyntaxKind } from 'ts-morph';\nimport { z } from 'zod';\nimport {
|
|
1
|
+
{"version":3,"file":"trigger-generator.js","names":[],"sources":["../../../../src/commands/pull-v4/generators/trigger-generator.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { FullProjectDefinitionSchema } from '@inkeep/agents-core';\nimport { type SourceFile, SyntaxKind } from 'ts-morph';\nimport { z } from 'zod';\nimport { asRecord } from '../collector-common';\nimport { buildSequentialNameFileNames } from '../generation-resolver';\nimport type { GenerationTask } from '../generation-types';\nimport { addNamedImports, applyImportPlan, createImportPlan } from '../import-plan';\nimport { generateFactorySourceFile } from '../simple-factory-generator';\nimport { addValueToObject, codeReference, toCamelCase, toTriggerReferenceName } from '../utils';\n\nconst MySchema = FullProjectDefinitionSchema.shape.agents.valueType.shape.triggers\n .unwrap()\n .valueType.omit({\n id: true,\n });\n\nconst TriggerSchema = z.strictObject({\n triggerId: z.string().nonempty(),\n ...MySchema.shape,\n description: z.preprocess((v) => v || undefined, MySchema.shape.description),\n inputSchema: z.preprocess((v) => v || undefined, MySchema.shape.inputSchema),\n outputTransform: z.preprocess((v) => v || undefined, MySchema.shape.outputTransform),\n messageTemplate: z.preprocess((v) => v || undefined, MySchema.shape.messageTemplate),\n authentication: z.preprocess(\n (v) => v || undefined,\n // ✖ Invalid input: expected string, received undefined\n // → at authentication.headers[0].value\n z.unknown()\n ),\n signatureVerification: z.preprocess((v) => v || undefined, MySchema.shape.signatureVerification),\n signingSecretCredentialReferenceName: z.string().nonempty().optional(),\n signingSecretCredentialReferencePath: z.string().nonempty().optional(),\n});\n\ntype TriggerInput = z.input<typeof TriggerSchema>;\n\nexport function generateTriggerDefinition({\n id,\n runAsUserId,\n createdBy,\n ...data\n}: TriggerInput & Record<string, unknown>): SourceFile {\n return generateFactorySourceFile(data, {\n schema: TriggerSchema,\n factory: {\n importName: 'Trigger',\n variableName: (parsed) => toTriggerReferenceName(parsed.name),\n syntaxKind: SyntaxKind.NewExpression,\n },\n render({ parsed, sourceFile, configObject }) {\n const {\n triggerId,\n signingSecretCredentialReferenceId,\n signingSecretCredentialReferenceName,\n signingSecretCredentialReferencePath,\n ...rest\n } = parsed;\n\n for (const [key, value] of Object.entries({\n id: triggerId,\n ...rest,\n })) {\n addValueToObject(configObject, key, value);\n }\n\n const importPlan = createImportPlan();\n if (signingSecretCredentialReferenceId) {\n const varName =\n signingSecretCredentialReferenceName ??\n toCamelCase(signingSecretCredentialReferenceId as string);\n const modulePath =\n signingSecretCredentialReferencePath ?? (signingSecretCredentialReferenceId as string);\n addNamedImports(importPlan, `../../credentials/${modulePath}`, varName);\n addValueToObject(configObject, 'signingSecretCredentialReference', codeReference(varName));\n }\n applyImportPlan(sourceFile, importPlan);\n },\n });\n}\n\nexport const task = {\n type: 'trigger',\n collect(context) {\n if (!context.project.agents) {\n return [];\n }\n\n const records = [];\n for (const agentId of context.completeAgentIds) {\n const agentData = context.project.agents[agentId];\n if (!agentData?.triggers) {\n continue;\n }\n\n const triggerEntries = Object.entries(agentData.triggers);\n const fileNamesByTriggerId = buildSequentialNameFileNames(triggerEntries);\n\n for (const [triggerId, triggerData] of triggerEntries) {\n const triggerRecord = asRecord(triggerData);\n const signingSecretCredentialReferenceId =\n typeof triggerRecord?.signingSecretCredentialReferenceId === 'string'\n ? triggerRecord.signingSecretCredentialReferenceId\n : undefined;\n const signingSecretCredentialReferenceName = signingSecretCredentialReferenceId\n ? context.resolver.getCredentialReferenceName(signingSecretCredentialReferenceId)\n : undefined;\n const signingSecretCredentialReferencePath = signingSecretCredentialReferenceId\n ? context.resolver.getCredentialReferencePath(signingSecretCredentialReferenceId)\n : undefined;\n\n records.push({\n id: triggerId,\n filePath: context.resolver.resolveOutputFilePath(\n 'triggers',\n triggerId,\n join(context.paths.agentsDir, 'triggers', fileNamesByTriggerId[triggerId])\n ),\n payload: {\n triggerId,\n ...triggerData,\n ...(signingSecretCredentialReferenceName && {\n signingSecretCredentialReferenceName,\n }),\n ...(signingSecretCredentialReferencePath && {\n signingSecretCredentialReferencePath,\n }),\n } as Parameters<typeof generateTriggerDefinition>[0],\n });\n }\n }\n\n return records;\n },\n generate: generateTriggerDefinition,\n} satisfies GenerationTask<Parameters<typeof generateTriggerDefinition>[0]>;\n"],"mappings":";;;;;;;;;;;;;;AAWA,MAAM,WAAW,4BAA4B,MAAM,OAAO,UAAU,MAAM,SACvE,QAAQ,CACR,UAAU,KAAK,EACd,IAAI,MACL,CAAC;AAEJ,MAAM,gBAAgB,EAAE,aAAa;CACnC,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,GAAG,SAAS;CACZ,aAAa,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,YAAY;CAC5E,aAAa,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,YAAY;CAC5E,iBAAiB,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,gBAAgB;CACpF,iBAAiB,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,gBAAgB;CACpF,gBAAgB,EAAE,YACf,MAAM,KAAK,QAGZ,EAAE,SAAS,CACZ;CACD,uBAAuB,EAAE,YAAY,MAAM,KAAK,QAAW,SAAS,MAAM,sBAAsB;CAChG,sCAAsC,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU;CACtE,sCAAsC,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU;CACvE,CAAC;AAIF,SAAgB,0BAA0B,EACxC,IACA,aACA,WACA,GAAG,QACkD;AACrD,QAAO,0BAA0B,MAAM;EACrC,QAAQ;EACR,SAAS;GACP,YAAY;GACZ,eAAe,WAAW,uBAAuB,OAAO,KAAK;GAC7D,YAAY,WAAW;GACxB;EACD,OAAO,EAAE,QAAQ,YAAY,gBAAgB;GAC3C,MAAM,EACJ,WACA,oCACA,sCACA,sCACA,GAAG,SACD;AAEJ,QAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ;IACxC,IAAI;IACJ,GAAG;IACJ,CAAC,CACA,kBAAiB,cAAc,KAAK,MAAM;GAG5C,MAAM,aAAa,kBAAkB;AACrC,OAAI,oCAAoC;IACtC,MAAM,UACJ,wCACA,YAAY,mCAA6C;AAG3D,oBAAgB,YAAY,qBAD1B,wCAAyC,sCACoB,QAAQ;AACvE,qBAAiB,cAAc,oCAAoC,cAAc,QAAQ,CAAC;;AAE5F,mBAAgB,YAAY,WAAW;;EAE1C,CAAC;;AAGJ,MAAa,OAAO;CAClB,MAAM;CACN,QAAQ,SAAS;AACf,MAAI,CAAC,QAAQ,QAAQ,OACnB,QAAO,EAAE;EAGX,MAAM,UAAU,EAAE;AAClB,OAAK,MAAM,WAAW,QAAQ,kBAAkB;GAC9C,MAAM,YAAY,QAAQ,QAAQ,OAAO;AACzC,OAAI,CAAC,WAAW,SACd;GAGF,MAAM,iBAAiB,OAAO,QAAQ,UAAU,SAAS;GACzD,MAAM,uBAAuB,6BAA6B,eAAe;AAEzE,QAAK,MAAM,CAAC,WAAW,gBAAgB,gBAAgB;IACrD,MAAM,gBAAgB,SAAS,YAAY;IAC3C,MAAM,qCACJ,OAAO,eAAe,uCAAuC,WACzD,cAAc,qCACd;IACN,MAAM,uCAAuC,qCACzC,QAAQ,SAAS,2BAA2B,mCAAmC,GAC/E;IACJ,MAAM,uCAAuC,qCACzC,QAAQ,SAAS,2BAA2B,mCAAmC,GAC/E;AAEJ,YAAQ,KAAK;KACX,IAAI;KACJ,UAAU,QAAQ,SAAS,sBACzB,YACA,WACA,KAAK,QAAQ,MAAM,WAAW,YAAY,qBAAqB,WAAW,CAC3E;KACD,SAAS;MACP;MACA,GAAG;MACH,GAAI,wCAAwC,EAC1C,sCACD;MACD,GAAI,wCAAwC,EAC1C,sCACD;MACF;KACF,CAAC;;;AAIN,SAAO;;CAET,UAAU;CACX"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/commands/pull-v4/import-plan.ts
|
|
2
|
+
function createImportPlan() {
|
|
3
|
+
return [];
|
|
4
|
+
}
|
|
5
|
+
function addNamedImports(plan, moduleSpecifier, namedImports) {
|
|
6
|
+
const normalizedNamedImports = Array.isArray(namedImports) ? namedImports : [namedImports];
|
|
7
|
+
if (!normalizedNamedImports.length) return plan;
|
|
8
|
+
let importSpec = plan.find((entry) => entry.moduleSpecifier === moduleSpecifier);
|
|
9
|
+
if (!importSpec) {
|
|
10
|
+
importSpec = {
|
|
11
|
+
moduleSpecifier,
|
|
12
|
+
namedImports: []
|
|
13
|
+
};
|
|
14
|
+
plan.push(importSpec);
|
|
15
|
+
}
|
|
16
|
+
const existingImportKeys = new Set(importSpec.namedImports.map(toNamedImportKey));
|
|
17
|
+
for (const namedImport of normalizedNamedImports) {
|
|
18
|
+
const importKey = toNamedImportKey(namedImport);
|
|
19
|
+
if (existingImportKeys.has(importKey)) continue;
|
|
20
|
+
importSpec.namedImports.push(namedImport);
|
|
21
|
+
existingImportKeys.add(importKey);
|
|
22
|
+
}
|
|
23
|
+
return plan;
|
|
24
|
+
}
|
|
25
|
+
function applyImportPlan(sourceFile, importPlan) {
|
|
26
|
+
for (const importSpec of importPlan) {
|
|
27
|
+
if (!importSpec.namedImports.length) continue;
|
|
28
|
+
sourceFile.addImportDeclaration({
|
|
29
|
+
namedImports: importSpec.namedImports,
|
|
30
|
+
moduleSpecifier: importSpec.moduleSpecifier
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function toNamedImportKey(namedImport) {
|
|
35
|
+
return typeof namedImport === "string" ? namedImport : `${namedImport.name}:${namedImport.alias}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
export { addNamedImports, applyImportPlan, createImportPlan };
|
|
40
|
+
//# sourceMappingURL=import-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-plan.js","names":[],"sources":["../../../src/commands/pull-v4/import-plan.ts"],"sourcesContent":["import type { SourceFile } from 'ts-morph';\n\nexport type NamedImportSpec = string | { name: string; alias: string };\n\nexport interface ImportSpec {\n moduleSpecifier: string;\n namedImports: NamedImportSpec[];\n}\n\nexport type ImportPlan = ImportSpec[];\n\nexport function createImportPlan(): ImportPlan {\n return [];\n}\n\nexport function addNamedImports(\n plan: ImportPlan,\n moduleSpecifier: string,\n namedImports: NamedImportSpec | NamedImportSpec[]\n): ImportPlan {\n const normalizedNamedImports = Array.isArray(namedImports) ? namedImports : [namedImports];\n if (!normalizedNamedImports.length) {\n return plan;\n }\n\n let importSpec = plan.find((entry) => entry.moduleSpecifier === moduleSpecifier);\n if (!importSpec) {\n importSpec = {\n moduleSpecifier,\n namedImports: [],\n };\n plan.push(importSpec);\n }\n\n const existingImportKeys = new Set(importSpec.namedImports.map(toNamedImportKey));\n for (const namedImport of normalizedNamedImports) {\n const importKey = toNamedImportKey(namedImport);\n if (existingImportKeys.has(importKey)) {\n continue;\n }\n\n importSpec.namedImports.push(namedImport);\n existingImportKeys.add(importKey);\n }\n\n return plan;\n}\n\nexport function applyImportPlan(sourceFile: SourceFile, importPlan: ImportPlan): void {\n for (const importSpec of importPlan) {\n if (!importSpec.namedImports.length) {\n continue;\n }\n\n sourceFile.addImportDeclaration({\n namedImports: importSpec.namedImports,\n moduleSpecifier: importSpec.moduleSpecifier,\n });\n }\n}\n\nfunction toNamedImportKey(namedImport: NamedImportSpec): string {\n return typeof namedImport === 'string' ? namedImport : `${namedImport.name}:${namedImport.alias}`;\n}\n"],"mappings":";AAWA,SAAgB,mBAA+B;AAC7C,QAAO,EAAE;;AAGX,SAAgB,gBACd,MACA,iBACA,cACY;CACZ,MAAM,yBAAyB,MAAM,QAAQ,aAAa,GAAG,eAAe,CAAC,aAAa;AAC1F,KAAI,CAAC,uBAAuB,OAC1B,QAAO;CAGT,IAAI,aAAa,KAAK,MAAM,UAAU,MAAM,oBAAoB,gBAAgB;AAChF,KAAI,CAAC,YAAY;AACf,eAAa;GACX;GACA,cAAc,EAAE;GACjB;AACD,OAAK,KAAK,WAAW;;CAGvB,MAAM,qBAAqB,IAAI,IAAI,WAAW,aAAa,IAAI,iBAAiB,CAAC;AACjF,MAAK,MAAM,eAAe,wBAAwB;EAChD,MAAM,YAAY,iBAAiB,YAAY;AAC/C,MAAI,mBAAmB,IAAI,UAAU,CACnC;AAGF,aAAW,aAAa,KAAK,YAAY;AACzC,qBAAmB,IAAI,UAAU;;AAGnC,QAAO;;AAGT,SAAgB,gBAAgB,YAAwB,YAA8B;AACpF,MAAK,MAAM,cAAc,YAAY;AACnC,MAAI,CAAC,WAAW,aAAa,OAC3B;AAGF,aAAW,qBAAqB;GAC9B,cAAc,WAAW;GACzB,iBAAiB,WAAW;GAC7B,CAAC;;;AAIN,SAAS,iBAAiB,aAAsC;AAC9D,QAAO,OAAO,gBAAgB,WAAW,cAAc,GAAG,YAAY,KAAK,GAAG,YAAY"}
|
|
@@ -191,11 +191,7 @@ async function pullV4Command(options) {
|
|
|
191
191
|
return;
|
|
192
192
|
}
|
|
193
193
|
const paths = createProjectStructure(projectDir);
|
|
194
|
-
|
|
195
|
-
if (skills && Object.keys(skills).length) {
|
|
196
|
-
const { generateSkills } = await import("../generators/skill-generator.js");
|
|
197
|
-
await generateSkills(skills, paths.skillsDir);
|
|
198
|
-
}
|
|
194
|
+
await generateProjectSkillsIfPresent(remoteProject, paths.skillsDir);
|
|
199
195
|
s.start("Starting generating files...");
|
|
200
196
|
await introspectGenerate({
|
|
201
197
|
project: remoteProject,
|
|
@@ -339,9 +335,11 @@ async function pullSingleProject(projectId, projectName, options, config, isCI)
|
|
|
339
335
|
else delete process.env.LOG_LEVEL;
|
|
340
336
|
};
|
|
341
337
|
const remoteProject = await (await ManagementApiClient.create(config.agentsApiUrl, options.config, config.tenantId, projectId, isCI, config.agentsApiKey)).getFullProject(projectId);
|
|
338
|
+
const paths = createProjectStructure(targetDir);
|
|
339
|
+
await generateProjectSkillsIfPresent(remoteProject, paths.skillsDir);
|
|
342
340
|
await introspectGenerate({
|
|
343
341
|
project: remoteProject,
|
|
344
|
-
paths
|
|
342
|
+
paths
|
|
345
343
|
});
|
|
346
344
|
restoreLogLevel();
|
|
347
345
|
return {
|
|
@@ -360,7 +358,13 @@ async function pullSingleProject(projectId, projectName, options, config, isCI)
|
|
|
360
358
|
};
|
|
361
359
|
}
|
|
362
360
|
}
|
|
361
|
+
async function generateProjectSkillsIfPresent(remoteProject, skillsDir) {
|
|
362
|
+
const skills = remoteProject.skills ?? {};
|
|
363
|
+
if (!Object.keys(skills).length) return;
|
|
364
|
+
const { generateSkills } = await import("../skill.js");
|
|
365
|
+
await generateSkills(skills, skillsDir);
|
|
366
|
+
}
|
|
363
367
|
|
|
364
368
|
//#endregion
|
|
365
|
-
export { createProjectStructure, enrichCanDelegateToWithTypes, pullV4Command };
|
|
369
|
+
export { createProjectStructure, enrichCanDelegateToWithTypes, pullSingleProject, pullV4Command };
|
|
366
370
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/commands/pull-v4/introspect/index.ts"],"sourcesContent":["/**\n * Pull v3 - Clean, efficient project generation\n *\n * Step 1: Validate and compile existing code\n * Step 2: Compare project with DB to detect ALL changes\n * Step 3: Classify changes as new vs modified components\n * Step 4: Generate new components deterministically\n * Step 5: Use LLM to correct modified components\n */\n\nimport { EventEmitter } from 'node:events';\nimport { existsSync, mkdirSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { styleText } from 'node:util';\nimport * as p from '@clack/prompts';\nimport type { FullProjectDefinition } from '@inkeep/agents-core';\n\n// Increase max listeners to prevent warnings during complex CLI flows\n// This is needed because @clack/prompts + multiple interactive prompts + spinners all add listeners\nEventEmitter.defaultMaxListeners = 20;\n\nimport { ManagementApiClient } from '../../../api';\nimport { performBackgroundVersionCheck } from '../../../utils/background-version-check';\nimport { initializeCommand } from '../../../utils/cli-pipeline';\nimport { loadProject } from '../../../utils/project-loader';\nimport { introspectGenerate } from '../introspect-generator';\n\nexport interface PullV3Options {\n project?: string;\n config?: string;\n profile?: string;\n env?: string;\n json?: boolean;\n debug?: boolean;\n verbose?: boolean;\n force?: boolean;\n introspect?: boolean;\n all?: boolean;\n tag?: string;\n quiet?: boolean;\n /** Internal: used for batch operations to return results instead of calling process.exit() */\n _batchMode?: boolean;\n}\n\nexport interface PullResult {\n success: boolean;\n skipped?: boolean;\n upToDate?: boolean;\n error?: string;\n}\n\ninterface BatchPullResult {\n projectId: string;\n projectName?: string;\n targetDir: string;\n success: boolean;\n error?: string;\n}\n\ninterface ProjectPaths {\n projectRoot: string;\n agentsDir: string;\n toolsDir: string;\n dataComponentsDir: string;\n artifactComponentsDir: string;\n statusComponentsDir: string;\n environmentsDir: string;\n credentialsDir: string;\n contextConfigsDir: string;\n externalAgentsDir: string;\n skillsDir: string;\n}\n\n/**\n * Create project directory structure\n */\nexport function createProjectStructure(projectRoot: string): ProjectPaths {\n mkdirSync(projectRoot, { recursive: true });\n return {\n projectRoot,\n agentsDir: join(projectRoot, 'agents'),\n toolsDir: join(projectRoot, 'tools'),\n dataComponentsDir: join(projectRoot, 'data-components'),\n artifactComponentsDir: join(projectRoot, 'artifact-components'),\n statusComponentsDir: join(projectRoot, 'status-components'),\n environmentsDir: join(projectRoot, 'environments'),\n credentialsDir: join(projectRoot, 'credentials'),\n contextConfigsDir: join(projectRoot, 'context-configs'),\n externalAgentsDir: join(projectRoot, 'external-agents'),\n skillsDir: join(projectRoot, 'skills'),\n };\n}\n\n/**\n * Enrich canDelegateTo references with component type information\n */\nexport function enrichCanDelegateToWithTypes(project: FullProjectDefinition): void {\n const { agents } = project;\n // Get all available component IDs by type\n const agentsIdSet = new Set(Object.keys(agents));\n const subAgentsIdSet = new Set(\n Object.values(agents).flatMap((agentData) => Object.keys(agentData.subAgents))\n );\n const externalAgentsIdSet = new Set(\n project.externalAgents ? Object.keys(project.externalAgents) : []\n );\n\n // Function to enrich a canDelegateTo array\n\n function enrichCanDelegateToArray(canDelegateTo: unknown[]): unknown[] {\n return canDelegateTo.map((item) => {\n // Skip if it's already an object (already has type info)\n if (typeof item !== 'string') return item;\n if (agentsIdSet.has(item)) return { agentId: item };\n if (subAgentsIdSet.has(item)) return { subAgentId: item };\n if (externalAgentsIdSet.has(item)) return { externalAgentId: item };\n return item;\n });\n }\n\n // Process all agents\n for (const { subAgents } of Object.values(project.agents)) {\n // Process subAgents within agents\n for (const subAgentData of Object.values(subAgents)) {\n if (Array.isArray(subAgentData.canDelegateTo)) {\n // @ts-expect-error\n subAgentData.canDelegateTo = enrichCanDelegateToArray(subAgentData.canDelegateTo);\n }\n }\n }\n}\n\n/**\n * Main pull v4 command\n * @returns PullResult when in batch mode, otherwise void (exits process)\n */\nexport async function pullV4Command(options: PullV3Options): Promise<PullResult | undefined> {\n // Handle --all flag for batch operations\n if (options.all) {\n await pullAllProjects(options);\n return;\n }\n\n const batchMode = options._batchMode ?? false;\n\n // Suppress SDK logging for cleaner output\n const originalLogLevel = process.env.LOG_LEVEL;\n process.env.LOG_LEVEL = 'silent';\n\n const restoreLogLevel = () => {\n if (originalLogLevel !== undefined) {\n process.env.LOG_LEVEL = originalLogLevel;\n } else {\n delete process.env.LOG_LEVEL;\n }\n };\n\n // Background version check (skip in batch mode - already done)\n if (!batchMode) {\n performBackgroundVersionCheck();\n }\n\n console.log(styleText('blue', '\\nInkeep Pull:'));\n if (options.introspect) {\n console.log(\n styleText('gray', ' Introspect mode • Complete regeneration • No comparison needed')\n );\n } else {\n console.log(styleText('gray', ' Smart comparison • Detect all changes • Targeted updates'));\n }\n\n const s = p.spinner();\n\n try {\n // Step 1: Load configuration (same as push command)\n const { config, isCI } = await initializeCommand({\n configPath: options.config,\n profileName: options.profile,\n tag: options.tag,\n showSpinner: true,\n spinnerText: 'Loading configuration...',\n logConfig: true,\n quiet: options.quiet,\n });\n\n // Step 2: Determine project directory and ID\n s.start('Detecting project...');\n let projectDir: string;\n let projectId: string;\n let localProjectForId: any = null;\n\n const currentDir = process.cwd();\n const hasIndexInCurrent = existsSync(join(currentDir, 'index.ts'));\n\n if (hasIndexInCurrent) {\n // We're in a project directory\n projectDir = currentDir;\n\n s.start('Loading local project...');\n try {\n localProjectForId = await loadProject(projectDir);\n const localProjectId = localProjectForId.getId();\n\n if (options.project) {\n // Validate that --project matches local project ID\n if (localProjectId !== options.project) {\n s.stop('Project ID mismatch');\n console.error(\n styleText(\n 'red',\n `Local project ID \"${localProjectId}\" doesn't match --project \"${options.project}\"`\n )\n );\n console.error(\n styleText(\n 'yellow',\n 'Either remove --project flag or ensure it matches the local project ID'\n )\n );\n if (batchMode) {\n return { success: false, error: 'Project ID mismatch' };\n }\n process.exit(1);\n }\n }\n\n projectId = localProjectId;\n s.stop(`Using local project: ${projectId}`);\n } catch (error) {\n s.stop('Failed to load local project');\n throw new Error(\n `Could not load local project: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n } else {\n // No index.ts in current directory\n if (!options.project) {\n s.stop('No index.ts found in current directory');\n console.error(\n styleText(\n 'yellow',\n 'Please run this command from a directory containing index.ts or use --project <project-id>'\n )\n );\n if (batchMode) {\n return { success: false, error: 'No index.ts found and no --project specified' };\n }\n process.exit(1);\n }\n\n // Try --project as directory path first\n const projectPath = resolve(currentDir, options.project);\n const hasIndexInPath = existsSync(join(projectPath, 'index.ts'));\n\n if (hasIndexInPath) {\n // --project is a valid directory path\n projectDir = projectPath;\n s.start('Loading project from specified path...');\n try {\n localProjectForId = await loadProject(projectDir);\n projectId = localProjectForId.getId();\n s.stop(`Using project from path: ${projectId}`);\n } catch (error) {\n s.stop('Failed to load project from path');\n throw new Error(\n `Could not load project from ${projectPath}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n } else {\n // Treat --project as project ID, create subdirectory\n projectId = options.project;\n projectDir = join(currentDir, projectId);\n s.stop(`Creating new project directory: ${projectDir}`);\n }\n }\n\n // Step 4: Fetch project data from API\n s.start(`Fetching project: ${projectId}`);\n\n const apiClient = await ManagementApiClient.create(\n config.agentsApiUrl,\n options.config,\n config.tenantId,\n projectId,\n isCI,\n config.agentsApiKey\n );\n\n const remoteProject = await apiClient.getFullProject(projectId);\n\n if (options.debug && remoteProject.functions) {\n console.log(\n styleText('gray', ' 📋 Project-level functions from API:'),\n Object.keys(remoteProject.functions)\n );\n Object.entries(remoteProject.functions).forEach(([id, data]: [string, any]) => {\n console.log(\n styleText(\n 'gray',\n ` ${id}: has name=${!!data.name}, has description=${!!data.description}`\n )\n );\n });\n }\n\n // Normalize remote project (same as pull-v2 - hoist agent-level functionTools)\n if (remoteProject.agents) {\n for (const [agentId, agentData] of Object.entries(remoteProject.agents) as any[]) {\n if (agentData.functionTools) {\n remoteProject.functionTools = remoteProject.functionTools || {};\n Object.assign(remoteProject.functionTools, agentData.functionTools);\n if (options.debug) {\n console.log(\n styleText(\n 'gray',\n ` Hoisted functionTools from agent ${agentId}: ${Object.keys(agentData.functionTools).join(', ')}`\n )\n );\n }\n }\n if (agentData.functions) {\n remoteProject.functions ||= {};\n const { functions } = remoteProject;\n // Only hoist agent functions if project-level functions don't already exist (clean function data)\n Object.entries(agentData.functions).forEach(([funcId, funcData]: [string, any]) => {\n // Clean function data - remove functionTool metadata that shouldn't be in functions collection\n functions[funcId] ||= {\n id: funcData.id,\n inputSchema: funcData.inputSchema,\n executeCode: funcData.executeCode,\n dependencies: funcData.dependencies,\n createdAt: '',\n updatedAt: '',\n };\n });\n }\n }\n }\n\n // Filter out project-level tools from individual agents\n // The API includes project-level tools in each agent's tools field, but our generated\n // code structure keeps tools separate and imports them via canUse relationships\n if (remoteProject.agents && remoteProject.tools) {\n const projectToolIds = Object.keys(remoteProject.tools);\n\n for (const agentData of Object.values(remoteProject.agents) as any[]) {\n if (agentData.tools) {\n // Filter out any tools that are defined at project level\n const agentSpecificTools = Object.fromEntries(\n Object.entries(agentData.tools).filter(([toolId]) => !projectToolIds.includes(toolId))\n );\n\n // Only keep tools field if there are agent-specific tools remaining\n if (Object.keys(agentSpecificTools).length > 0) {\n agentData.tools = agentSpecificTools;\n } else {\n // Remove the tools field entirely if all tools were project-level\n delete agentData.tools;\n }\n }\n }\n }\n\n // Enrich canDelegateTo references with component type information\n // @ts-expect-error -- fixme Types of property `models` are incompatible.\n enrichCanDelegateToWithTypes(remoteProject);\n\n s.message('Project data fetched');\n\n if (options.json) {\n console.log(JSON.stringify(remoteProject, null, 2));\n restoreLogLevel();\n return;\n }\n\n // Step 5: Set up project structure\n const paths = createProjectStructure(projectDir);\n\n // @ts-expect-error -- fix types\n const skills = remoteProject.skills;\n\n if (skills && Object.keys(skills).length) {\n const { generateSkills } = await import('../generators/skill-generator');\n await generateSkills(skills, paths.skillsDir);\n }\n\n s.start('Starting generating files...');\n await introspectGenerate({\n // @ts-expect-error -- ignore Types of property 'models' are incompatible.\n project: remoteProject,\n paths,\n debug: options.debug,\n });\n s.stop('All files generated');\n\n console.log(styleText('green', '\\nProject synced successfully!'));\n console.log(styleText('gray', ` Location: ${paths.projectRoot}`));\n console.log(styleText('gray', ` Environment: ${options.env || 'development'}`));\n console.log(\n styleText(\n 'yellow',\n '⚠️ If you encounter broken code after running `inkeep pull`, please report it at https://github.com/inkeep/agents/issues.'\n )\n );\n\n restoreLogLevel();\n if (batchMode) {\n return { success: true };\n }\n process.exit(0);\n } catch (error) {\n const message = error instanceof Error ? error.stack : String(error);\n s.stop();\n console.error(styleText('red', `\\nError: ${message}`));\n if (options.debug && error instanceof Error) {\n console.error(styleText('red', error.stack || ''));\n }\n restoreLogLevel();\n if (batchMode) {\n return { success: false, error: message };\n }\n process.exit(1);\n }\n}\n\n/**\n * Pull all projects for the current tenant\n * Uses smart comparison with LLM merging for existing projects, introspect for new projects\n */\nasync function pullAllProjects(options: PullV3Options): Promise<void> {\n console.log(styleText('blue', '\\n🔄 Batch Pull: Sequential processing with smart comparison\\n'));\n console.log(\n styleText(\n 'gray',\n ' • Existing projects: Smart comparison + AST merging + confirmation prompts'\n )\n );\n console.log(styleText('gray', ' • New projects: Fresh generation with introspect mode\\n'));\n\n // Background version check (only once for batch)\n performBackgroundVersionCheck();\n\n // Load configuration first\n const { config, isCI } = await initializeCommand({\n configPath: options.config,\n profileName: options.profile,\n tag: options.tag,\n showSpinner: true,\n spinnerText: 'Loading configuration...',\n logConfig: true,\n quiet: options.quiet,\n });\n\n const s = p.spinner();\n\n try {\n // Fetch all projects from the API\n s.start('Fetching project list from API...');\n const apiClient = await ManagementApiClient.create(\n config.agentsApiUrl,\n options.config,\n config.tenantId,\n undefined,\n isCI,\n config.agentsApiKey\n );\n\n const projects = await apiClient.listAllProjects();\n s.stop(`Found ${projects.length} project(s)`);\n\n if (!projects.length) {\n console.log(styleText('yellow', 'No projects found for this tenant.'));\n process.exit(0);\n }\n\n // Categorize projects\n const existingProjects: typeof projects = [];\n const newProjects: typeof projects = [];\n\n for (const project of projects) {\n const targetDir = join(process.cwd(), project.id);\n if (existsSync(join(targetDir, 'index.ts'))) {\n existingProjects.push(project);\n } else {\n newProjects.push(project);\n }\n }\n\n console.log(styleText('gray', '\\nProjects to pull:\\n'));\n if (existingProjects.length > 0) {\n console.log(styleText('cyan', ' Existing (smart comparison):'));\n for (const project of existingProjects) {\n console.log(styleText('gray', ` • ${project.name || project.id} (${project.id})`));\n }\n }\n if (newProjects.length > 0) {\n console.log(styleText('cyan', ' New (introspect):'));\n for (const project of newProjects) {\n console.log(styleText('gray', ` • ${project.name || project.id} (${project.id})`));\n }\n }\n console.log();\n\n const results: BatchPullResult[] = [];\n const total = projects.length;\n\n for (let i = 0; i < projects.length; i++) {\n const project = projects[i];\n const progress = `[${i + 1}/${total}]`;\n\n console.log(styleText('cyan', `\\n${'─'.repeat(60)}`));\n console.log(styleText('cyan', `${progress} Pulling ${project.name || project.id}...`));\n\n const result = await pullSingleProject(project.id, project.name, options, config, isCI);\n results.push(result);\n\n if (result.success) {\n console.log(\n styleText(\n 'green',\n `\\n ✓ ${result.projectName || result.projectId} → ${result.targetDir}`\n )\n );\n } else {\n console.log(\n styleText('red', `\\n ✗ ${result.projectName || result.projectId}: ${result.error}`)\n );\n }\n }\n\n // Print summary\n const succeeded = results.filter((r) => r.success).length;\n const failed = results.filter((r) => !r.success).length;\n\n console.log(styleText('cyan', `\\n${'═'.repeat(60)}`));\n console.log(styleText('cyan', '📊 Batch Pull Summary:'));\n console.log(styleText('green', ` ✓ Succeeded: ${succeeded}`));\n if (failed > 0) {\n console.log(styleText('red', ` ✗ Failed: ${failed}`));\n\n console.log(styleText('red', '\\nFailed projects:'));\n for (const result of results) {\n if (!result.success) {\n console.log(styleText('red', ` • ${result.projectId}: ${result.error}`));\n }\n }\n }\n\n process.exit(failed > 0 ? 1 : 0);\n } catch (error) {\n s.stop();\n console.error(\n styleText('red', `\\nError: ${error instanceof Error ? error.message : String(error)}`)\n );\n process.exit(1);\n }\n}\n\n/**\n * Pull a single project (used by batch operations)\n * Uses smart comparison flow for existing projects, introspect for new projects\n */\nasync function pullSingleProject(\n projectId: string,\n projectName: string | undefined,\n options: PullV3Options,\n config: any,\n isCI?: boolean\n): Promise<BatchPullResult> {\n const targetDir = join(process.cwd(), projectId);\n const hasExistingProject = existsSync(join(targetDir, 'index.ts'));\n\n try {\n if (hasExistingProject) {\n // Project exists locally - use smart comparison flow with LLM merging and user prompts\n console.log(styleText('gray', ` 📂 Existing project found - using smart comparison mode`));\n\n // Save current directory and change to project directory\n const originalDir = process.cwd();\n process.chdir(targetDir);\n\n try {\n // Call the main pull command in batch mode (returns results instead of exiting)\n const result = await pullV4Command({\n ...options,\n project: projectId,\n all: false, // Don't recurse into batch mode\n _batchMode: true,\n });\n\n // Restore original directory\n process.chdir(originalDir);\n\n if (result && typeof result === 'object') {\n return {\n projectId,\n projectName,\n targetDir,\n success: result.success,\n error: result.error,\n };\n }\n\n return {\n projectId,\n projectName,\n targetDir,\n success: true,\n };\n } catch (error) {\n // Restore original directory even on error\n process.chdir(originalDir);\n throw error;\n }\n }\n console.log(styleText('gray', ' New project'));\n\n // Suppress SDK logging\n const originalLogLevel = process.env.LOG_LEVEL;\n process.env.LOG_LEVEL = 'silent';\n\n const restoreLogLevel = () => {\n if (originalLogLevel !== undefined) {\n process.env.LOG_LEVEL = originalLogLevel;\n } else {\n delete process.env.LOG_LEVEL;\n }\n };\n\n // Fetch project data from API\n const apiClient = await ManagementApiClient.create(\n config.agentsApiUrl,\n options.config,\n config.tenantId,\n projectId,\n isCI,\n config.agentsApiKey\n );\n\n const remoteProject = await apiClient.getFullProject(projectId);\n // Create project structure\n const paths = createProjectStructure(targetDir);\n\n // Generate all files using introspect mode for new projects\n await introspectGenerate({\n // @ts-expect-error -- ignore Types of property 'models' are incompatible.\n project: remoteProject,\n paths,\n });\n\n restoreLogLevel();\n\n return {\n projectId,\n projectName: projectName || remoteProject.name,\n targetDir,\n success: true,\n };\n } catch (error) {\n return {\n projectId,\n projectName,\n targetDir,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/commands/pull-v4/introspect/index.ts"],"sourcesContent":["/**\n * Pull v3 - Clean, efficient project generation\n *\n * Step 1: Validate and compile existing code\n * Step 2: Compare project with DB to detect ALL changes\n * Step 3: Classify changes as new vs modified components\n * Step 4: Generate new components deterministically\n * Step 5: Use LLM to correct modified components\n */\n\nimport { EventEmitter } from 'node:events';\nimport { existsSync, mkdirSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { styleText } from 'node:util';\nimport * as p from '@clack/prompts';\nimport type { FullProjectDefinition } from '@inkeep/agents-core';\n\n// Increase max listeners to prevent warnings during complex CLI flows\n// This is needed because @clack/prompts + multiple interactive prompts + spinners all add listeners\nEventEmitter.defaultMaxListeners = 20;\n\nimport { ManagementApiClient } from '../../../api';\nimport { performBackgroundVersionCheck } from '../../../utils/background-version-check';\nimport { initializeCommand } from '../../../utils/cli-pipeline';\nimport { loadProject } from '../../../utils/project-loader';\nimport { introspectGenerate } from '../introspect-generator';\n\nexport interface PullV3Options {\n project?: string;\n config?: string;\n profile?: string;\n env?: string;\n json?: boolean;\n debug?: boolean;\n verbose?: boolean;\n force?: boolean;\n introspect?: boolean;\n all?: boolean;\n tag?: string;\n quiet?: boolean;\n /** Internal: used for batch operations to return results instead of calling process.exit() */\n _batchMode?: boolean;\n}\n\nexport interface PullResult {\n success: boolean;\n skipped?: boolean;\n upToDate?: boolean;\n error?: string;\n}\n\ninterface BatchPullResult {\n projectId: string;\n projectName?: string;\n targetDir: string;\n success: boolean;\n error?: string;\n}\n\ninterface ProjectPaths {\n projectRoot: string;\n agentsDir: string;\n toolsDir: string;\n dataComponentsDir: string;\n artifactComponentsDir: string;\n statusComponentsDir: string;\n environmentsDir: string;\n credentialsDir: string;\n contextConfigsDir: string;\n externalAgentsDir: string;\n skillsDir: string;\n}\n\n/**\n * Create project directory structure\n */\nexport function createProjectStructure(projectRoot: string): ProjectPaths {\n mkdirSync(projectRoot, { recursive: true });\n return {\n projectRoot,\n agentsDir: join(projectRoot, 'agents'),\n toolsDir: join(projectRoot, 'tools'),\n dataComponentsDir: join(projectRoot, 'data-components'),\n artifactComponentsDir: join(projectRoot, 'artifact-components'),\n statusComponentsDir: join(projectRoot, 'status-components'),\n environmentsDir: join(projectRoot, 'environments'),\n credentialsDir: join(projectRoot, 'credentials'),\n contextConfigsDir: join(projectRoot, 'context-configs'),\n externalAgentsDir: join(projectRoot, 'external-agents'),\n skillsDir: join(projectRoot, 'skills'),\n };\n}\n\n/**\n * Enrich canDelegateTo references with component type information\n */\nexport function enrichCanDelegateToWithTypes(project: FullProjectDefinition): void {\n const { agents } = project;\n // Get all available component IDs by type\n const agentsIdSet = new Set(Object.keys(agents));\n const subAgentsIdSet = new Set(\n Object.values(agents).flatMap((agentData) => Object.keys(agentData.subAgents))\n );\n const externalAgentsIdSet = new Set(\n project.externalAgents ? Object.keys(project.externalAgents) : []\n );\n\n // Function to enrich a canDelegateTo array\n\n function enrichCanDelegateToArray(canDelegateTo: unknown[]): unknown[] {\n return canDelegateTo.map((item) => {\n // Skip if it's already an object (already has type info)\n if (typeof item !== 'string') return item;\n if (agentsIdSet.has(item)) return { agentId: item };\n if (subAgentsIdSet.has(item)) return { subAgentId: item };\n if (externalAgentsIdSet.has(item)) return { externalAgentId: item };\n return item;\n });\n }\n\n // Process all agents\n for (const { subAgents } of Object.values(project.agents)) {\n // Process subAgents within agents\n for (const subAgentData of Object.values(subAgents)) {\n if (Array.isArray(subAgentData.canDelegateTo)) {\n // @ts-expect-error\n subAgentData.canDelegateTo = enrichCanDelegateToArray(subAgentData.canDelegateTo);\n }\n }\n }\n}\n\n/**\n * Main pull v4 command\n * @returns PullResult when in batch mode, otherwise void (exits process)\n */\nexport async function pullV4Command(options: PullV3Options): Promise<PullResult | undefined> {\n // Handle --all flag for batch operations\n if (options.all) {\n await pullAllProjects(options);\n return;\n }\n\n const batchMode = options._batchMode ?? false;\n\n // Suppress SDK logging for cleaner output\n const originalLogLevel = process.env.LOG_LEVEL;\n process.env.LOG_LEVEL = 'silent';\n\n const restoreLogLevel = () => {\n if (originalLogLevel !== undefined) {\n process.env.LOG_LEVEL = originalLogLevel;\n } else {\n delete process.env.LOG_LEVEL;\n }\n };\n\n // Background version check (skip in batch mode - already done)\n if (!batchMode) {\n performBackgroundVersionCheck();\n }\n\n console.log(styleText('blue', '\\nInkeep Pull:'));\n if (options.introspect) {\n console.log(\n styleText('gray', ' Introspect mode • Complete regeneration • No comparison needed')\n );\n } else {\n console.log(styleText('gray', ' Smart comparison • Detect all changes • Targeted updates'));\n }\n\n const s = p.spinner();\n\n try {\n // Step 1: Load configuration (same as push command)\n const { config, isCI } = await initializeCommand({\n configPath: options.config,\n profileName: options.profile,\n tag: options.tag,\n showSpinner: true,\n spinnerText: 'Loading configuration...',\n logConfig: true,\n quiet: options.quiet,\n });\n\n // Step 2: Determine project directory and ID\n s.start('Detecting project...');\n let projectDir: string;\n let projectId: string;\n let localProjectForId: any = null;\n\n const currentDir = process.cwd();\n const hasIndexInCurrent = existsSync(join(currentDir, 'index.ts'));\n\n if (hasIndexInCurrent) {\n // We're in a project directory\n projectDir = currentDir;\n\n s.start('Loading local project...');\n try {\n localProjectForId = await loadProject(projectDir);\n const localProjectId = localProjectForId.getId();\n\n if (options.project) {\n // Validate that --project matches local project ID\n if (localProjectId !== options.project) {\n s.stop('Project ID mismatch');\n console.error(\n styleText(\n 'red',\n `Local project ID \"${localProjectId}\" doesn't match --project \"${options.project}\"`\n )\n );\n console.error(\n styleText(\n 'yellow',\n 'Either remove --project flag or ensure it matches the local project ID'\n )\n );\n if (batchMode) {\n return { success: false, error: 'Project ID mismatch' };\n }\n process.exit(1);\n }\n }\n\n projectId = localProjectId;\n s.stop(`Using local project: ${projectId}`);\n } catch (error) {\n s.stop('Failed to load local project');\n throw new Error(\n `Could not load local project: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n } else {\n // No index.ts in current directory\n if (!options.project) {\n s.stop('No index.ts found in current directory');\n console.error(\n styleText(\n 'yellow',\n 'Please run this command from a directory containing index.ts or use --project <project-id>'\n )\n );\n if (batchMode) {\n return { success: false, error: 'No index.ts found and no --project specified' };\n }\n process.exit(1);\n }\n\n // Try --project as directory path first\n const projectPath = resolve(currentDir, options.project);\n const hasIndexInPath = existsSync(join(projectPath, 'index.ts'));\n\n if (hasIndexInPath) {\n // --project is a valid directory path\n projectDir = projectPath;\n s.start('Loading project from specified path...');\n try {\n localProjectForId = await loadProject(projectDir);\n projectId = localProjectForId.getId();\n s.stop(`Using project from path: ${projectId}`);\n } catch (error) {\n s.stop('Failed to load project from path');\n throw new Error(\n `Could not load project from ${projectPath}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n } else {\n // Treat --project as project ID, create subdirectory\n projectId = options.project;\n projectDir = join(currentDir, projectId);\n s.stop(`Creating new project directory: ${projectDir}`);\n }\n }\n\n // Step 4: Fetch project data from API\n s.start(`Fetching project: ${projectId}`);\n\n const apiClient = await ManagementApiClient.create(\n config.agentsApiUrl,\n options.config,\n config.tenantId,\n projectId,\n isCI,\n config.agentsApiKey\n );\n\n const remoteProject = await apiClient.getFullProject(projectId);\n\n if (options.debug && remoteProject.functions) {\n console.log(\n styleText('gray', ' 📋 Project-level functions from API:'),\n Object.keys(remoteProject.functions)\n );\n Object.entries(remoteProject.functions).forEach(([id, data]: [string, any]) => {\n console.log(\n styleText(\n 'gray',\n ` ${id}: has name=${!!data.name}, has description=${!!data.description}`\n )\n );\n });\n }\n\n // Normalize remote project (same as pull-v2 - hoist agent-level functionTools)\n if (remoteProject.agents) {\n for (const [agentId, agentData] of Object.entries(remoteProject.agents) as any[]) {\n if (agentData.functionTools) {\n remoteProject.functionTools = remoteProject.functionTools || {};\n Object.assign(remoteProject.functionTools, agentData.functionTools);\n if (options.debug) {\n console.log(\n styleText(\n 'gray',\n ` Hoisted functionTools from agent ${agentId}: ${Object.keys(agentData.functionTools).join(', ')}`\n )\n );\n }\n }\n if (agentData.functions) {\n remoteProject.functions ||= {};\n const { functions } = remoteProject;\n // Only hoist agent functions if project-level functions don't already exist (clean function data)\n Object.entries(agentData.functions).forEach(([funcId, funcData]: [string, any]) => {\n // Clean function data - remove functionTool metadata that shouldn't be in functions collection\n functions[funcId] ||= {\n id: funcData.id,\n inputSchema: funcData.inputSchema,\n executeCode: funcData.executeCode,\n dependencies: funcData.dependencies,\n createdAt: '',\n updatedAt: '',\n };\n });\n }\n }\n }\n\n // Filter out project-level tools from individual agents\n // The API includes project-level tools in each agent's tools field, but our generated\n // code structure keeps tools separate and imports them via canUse relationships\n if (remoteProject.agents && remoteProject.tools) {\n const projectToolIds = Object.keys(remoteProject.tools);\n\n for (const agentData of Object.values(remoteProject.agents) as any[]) {\n if (agentData.tools) {\n // Filter out any tools that are defined at project level\n const agentSpecificTools = Object.fromEntries(\n Object.entries(agentData.tools).filter(([toolId]) => !projectToolIds.includes(toolId))\n );\n\n // Only keep tools field if there are agent-specific tools remaining\n if (Object.keys(agentSpecificTools).length > 0) {\n agentData.tools = agentSpecificTools;\n } else {\n // Remove the tools field entirely if all tools were project-level\n delete agentData.tools;\n }\n }\n }\n }\n\n // Enrich canDelegateTo references with component type information\n // @ts-expect-error -- fixme Types of property `models` are incompatible.\n enrichCanDelegateToWithTypes(remoteProject);\n\n s.message('Project data fetched');\n\n if (options.json) {\n console.log(JSON.stringify(remoteProject, null, 2));\n restoreLogLevel();\n return;\n }\n\n // Step 5: Set up project structure\n const paths = createProjectStructure(projectDir);\n\n await generateProjectSkillsIfPresent(remoteProject, paths.skillsDir);\n\n s.start('Starting generating files...');\n await introspectGenerate({\n // @ts-expect-error -- ignore Types of property 'models' are incompatible.\n project: remoteProject,\n paths,\n debug: options.debug,\n });\n s.stop('All files generated');\n\n console.log(styleText('green', '\\nProject synced successfully!'));\n console.log(styleText('gray', ` Location: ${paths.projectRoot}`));\n console.log(styleText('gray', ` Environment: ${options.env || 'development'}`));\n console.log(\n styleText(\n 'yellow',\n '⚠️ If you encounter broken code after running `inkeep pull`, please report it at https://github.com/inkeep/agents/issues.'\n )\n );\n\n restoreLogLevel();\n if (batchMode) {\n return { success: true };\n }\n process.exit(0);\n } catch (error) {\n const message = error instanceof Error ? error.stack : String(error);\n s.stop();\n console.error(styleText('red', `\\nError: ${message}`));\n if (options.debug && error instanceof Error) {\n console.error(styleText('red', error.stack || ''));\n }\n restoreLogLevel();\n if (batchMode) {\n return { success: false, error: message };\n }\n process.exit(1);\n }\n}\n\n/**\n * Pull all projects for the current tenant\n * Uses smart comparison with LLM merging for existing projects, introspect for new projects\n */\nasync function pullAllProjects(options: PullV3Options): Promise<void> {\n console.log(styleText('blue', '\\n🔄 Batch Pull: Sequential processing with smart comparison\\n'));\n console.log(\n styleText(\n 'gray',\n ' • Existing projects: Smart comparison + AST merging + confirmation prompts'\n )\n );\n console.log(styleText('gray', ' • New projects: Fresh generation with introspect mode\\n'));\n\n // Background version check (only once for batch)\n performBackgroundVersionCheck();\n\n // Load configuration first\n const { config, isCI } = await initializeCommand({\n configPath: options.config,\n profileName: options.profile,\n tag: options.tag,\n showSpinner: true,\n spinnerText: 'Loading configuration...',\n logConfig: true,\n quiet: options.quiet,\n });\n\n const s = p.spinner();\n\n try {\n // Fetch all projects from the API\n s.start('Fetching project list from API...');\n const apiClient = await ManagementApiClient.create(\n config.agentsApiUrl,\n options.config,\n config.tenantId,\n undefined,\n isCI,\n config.agentsApiKey\n );\n\n const projects = await apiClient.listAllProjects();\n s.stop(`Found ${projects.length} project(s)`);\n\n if (!projects.length) {\n console.log(styleText('yellow', 'No projects found for this tenant.'));\n process.exit(0);\n }\n\n // Categorize projects\n const existingProjects: typeof projects = [];\n const newProjects: typeof projects = [];\n\n for (const project of projects) {\n const targetDir = join(process.cwd(), project.id);\n if (existsSync(join(targetDir, 'index.ts'))) {\n existingProjects.push(project);\n } else {\n newProjects.push(project);\n }\n }\n\n console.log(styleText('gray', '\\nProjects to pull:\\n'));\n if (existingProjects.length > 0) {\n console.log(styleText('cyan', ' Existing (smart comparison):'));\n for (const project of existingProjects) {\n console.log(styleText('gray', ` • ${project.name || project.id} (${project.id})`));\n }\n }\n if (newProjects.length > 0) {\n console.log(styleText('cyan', ' New (introspect):'));\n for (const project of newProjects) {\n console.log(styleText('gray', ` • ${project.name || project.id} (${project.id})`));\n }\n }\n console.log();\n\n const results: BatchPullResult[] = [];\n const total = projects.length;\n\n for (let i = 0; i < projects.length; i++) {\n const project = projects[i];\n const progress = `[${i + 1}/${total}]`;\n\n console.log(styleText('cyan', `\\n${'─'.repeat(60)}`));\n console.log(styleText('cyan', `${progress} Pulling ${project.name || project.id}...`));\n\n const result = await pullSingleProject(project.id, project.name, options, config, isCI);\n results.push(result);\n\n if (result.success) {\n console.log(\n styleText(\n 'green',\n `\\n ✓ ${result.projectName || result.projectId} → ${result.targetDir}`\n )\n );\n } else {\n console.log(\n styleText('red', `\\n ✗ ${result.projectName || result.projectId}: ${result.error}`)\n );\n }\n }\n\n // Print summary\n const succeeded = results.filter((r) => r.success).length;\n const failed = results.filter((r) => !r.success).length;\n\n console.log(styleText('cyan', `\\n${'═'.repeat(60)}`));\n console.log(styleText('cyan', '📊 Batch Pull Summary:'));\n console.log(styleText('green', ` ✓ Succeeded: ${succeeded}`));\n if (failed > 0) {\n console.log(styleText('red', ` ✗ Failed: ${failed}`));\n\n console.log(styleText('red', '\\nFailed projects:'));\n for (const result of results) {\n if (!result.success) {\n console.log(styleText('red', ` • ${result.projectId}: ${result.error}`));\n }\n }\n }\n\n process.exit(failed > 0 ? 1 : 0);\n } catch (error) {\n s.stop();\n console.error(\n styleText('red', `\\nError: ${error instanceof Error ? error.message : String(error)}`)\n );\n process.exit(1);\n }\n}\n\n/**\n * Pull a single project (used by batch operations)\n * Uses smart comparison flow for existing projects, introspect for new projects\n */\nexport async function pullSingleProject(\n projectId: string,\n projectName: string | undefined,\n options: PullV3Options,\n config: any,\n isCI?: boolean\n): Promise<BatchPullResult> {\n const targetDir = join(process.cwd(), projectId);\n const hasExistingProject = existsSync(join(targetDir, 'index.ts'));\n\n try {\n if (hasExistingProject) {\n // Project exists locally - use smart comparison flow with LLM merging and user prompts\n console.log(styleText('gray', ` 📂 Existing project found - using smart comparison mode`));\n\n // Save current directory and change to project directory\n const originalDir = process.cwd();\n process.chdir(targetDir);\n\n try {\n // Call the main pull command in batch mode (returns results instead of exiting)\n const result = await pullV4Command({\n ...options,\n project: projectId,\n all: false, // Don't recurse into batch mode\n _batchMode: true,\n });\n\n // Restore original directory\n process.chdir(originalDir);\n\n if (result && typeof result === 'object') {\n return {\n projectId,\n projectName,\n targetDir,\n success: result.success,\n error: result.error,\n };\n }\n\n return {\n projectId,\n projectName,\n targetDir,\n success: true,\n };\n } catch (error) {\n // Restore original directory even on error\n process.chdir(originalDir);\n throw error;\n }\n }\n console.log(styleText('gray', ' New project'));\n\n // Suppress SDK logging\n const originalLogLevel = process.env.LOG_LEVEL;\n process.env.LOG_LEVEL = 'silent';\n\n const restoreLogLevel = () => {\n if (originalLogLevel !== undefined) {\n process.env.LOG_LEVEL = originalLogLevel;\n } else {\n delete process.env.LOG_LEVEL;\n }\n };\n\n // Fetch project data from API\n const apiClient = await ManagementApiClient.create(\n config.agentsApiUrl,\n options.config,\n config.tenantId,\n projectId,\n isCI,\n config.agentsApiKey\n );\n\n const remoteProject = await apiClient.getFullProject(projectId);\n // Create project structure\n const paths = createProjectStructure(targetDir);\n await generateProjectSkillsIfPresent(remoteProject, paths.skillsDir);\n\n // Generate all files using introspect mode for new projects\n await introspectGenerate({\n // @ts-expect-error -- ignore Types of property 'models' are incompatible.\n project: remoteProject,\n paths,\n });\n\n restoreLogLevel();\n\n return {\n projectId,\n projectName: projectName || remoteProject.name,\n targetDir,\n success: true,\n };\n } catch (error) {\n return {\n projectId,\n projectName,\n targetDir,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nasync function generateProjectSkillsIfPresent(\n remoteProject: any,\n skillsDir: string\n): Promise<void> {\n const skills = remoteProject.skills ?? {};\n if (!Object.keys(skills).length) {\n return;\n }\n\n const { generateSkills } = await import('../skill');\n await generateSkills(skills, skillsDir);\n}\n"],"mappings":"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"}
|