@inkeep/agents-cli 0.58.10 → 0.58.13
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 +3 -2
- package/dist/agents-cli/package.js.map +1 -0
- package/dist/api.js +7 -11
- package/dist/api.js.map +1 -0
- package/dist/commands/add-ui.js +2 -1
- package/dist/commands/add-ui.js.map +1 -0
- package/dist/commands/add.js +2 -1
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/config.js +2 -1
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/dev.js +2 -1
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/init.js +2 -1
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list-agents.js +2 -1
- package/dist/commands/list-agents.js.map +1 -0
- package/dist/commands/login.js +2 -1
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +2 -1
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/profile.js +2 -1
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/pull-v4/component-parser.js +2 -1
- package/dist/commands/pull-v4/component-parser.js.map +1 -0
- package/dist/commands/pull-v4/component-registry.js +2 -1
- package/dist/commands/pull-v4/component-registry.js.map +1 -0
- package/dist/commands/pull-v4/generators/agent-generator.helpers.js +186 -0
- package/dist/commands/pull-v4/generators/agent-generator.helpers.js.map +1 -0
- package/dist/commands/pull-v4/generators/agent-generator.js +70 -209
- package/dist/commands/pull-v4/generators/agent-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/artifact-component-generator.js +13 -16
- package/dist/commands/pull-v4/generators/artifact-component-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/context-config-generator.js +38 -24
- package/dist/commands/pull-v4/generators/context-config-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/credential-generator.js +14 -10
- package/dist/commands/pull-v4/generators/credential-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/data-component-generator.js +10 -12
- package/dist/commands/pull-v4/generators/data-component-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/environment-generator.js +11 -91
- package/dist/commands/pull-v4/generators/environment-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/external-agent-generator.js +22 -39
- package/dist/commands/pull-v4/generators/external-agent-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/function-tool-generator.js +19 -31
- package/dist/commands/pull-v4/generators/function-tool-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/mcp-tool-generator.js +30 -71
- package/dist/commands/pull-v4/generators/mcp-tool-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/project-generator.js +64 -31
- package/dist/commands/pull-v4/generators/project-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/skill-generator.js +4 -1
- package/dist/commands/pull-v4/generators/skill-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/status-component-generator.js +19 -19
- package/dist/commands/pull-v4/generators/status-component-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/sub-agent-generator.helpers.js +84 -0
- package/dist/commands/pull-v4/generators/sub-agent-generator.helpers.js.map +1 -0
- package/dist/commands/pull-v4/generators/sub-agent-generator.js +82 -113
- package/dist/commands/pull-v4/generators/sub-agent-generator.js.map +1 -0
- package/dist/commands/pull-v4/generators/trigger-generator.js +21 -30
- package/dist/commands/pull-v4/generators/trigger-generator.js.map +1 -0
- package/dist/commands/pull-v4/introspect/demo-project.js +1616 -0
- package/dist/commands/pull-v4/introspect/demo-project.js.map +1 -0
- package/dist/commands/pull-v4/introspect/index.js +17 -16
- package/dist/commands/pull-v4/introspect/index.js.map +1 -0
- package/dist/commands/pull-v4/introspect/test-helpers.js +5 -3
- package/dist/commands/pull-v4/introspect/test-helpers.js.map +1 -0
- package/dist/commands/pull-v4/introspect-generator.js +606 -93
- package/dist/commands/pull-v4/introspect-generator.js.map +1 -0
- package/dist/commands/pull-v4/module-merge.js +2 -1
- package/dist/commands/pull-v4/module-merge.js.map +1 -0
- package/dist/commands/pull-v4/scheduled-trigger-generator.js +16 -17
- package/dist/commands/pull-v4/scheduled-trigger-generator.js.map +1 -0
- package/dist/commands/pull-v4/utils.js +90 -28
- package/dist/commands/pull-v4/utils.js.map +1 -0
- package/dist/commands/push.js +2 -1
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/status.js +2 -1
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.js +2 -1
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/whoami.js +2 -1
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -0
- package/dist/env.js +2 -1
- package/dist/env.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -0
- package/dist/instrumentation.js +2 -1
- package/dist/instrumentation.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/array.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/array.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/base.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/base.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/character.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/character.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/css.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/css.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/json.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/json.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/line.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/line.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/sentence.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/sentence.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/word.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/word.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/patch/create.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/patch/create.js.map +1 -0
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/util/string.js +2 -1
- package/dist/node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/util/string.js.map +1 -0
- package/dist/utils/background-version-check.js +2 -1
- package/dist/utils/background-version-check.js.map +1 -0
- package/dist/utils/ci-environment.js +2 -1
- package/dist/utils/ci-environment.js.map +1 -0
- package/dist/utils/cli-pipeline.js +2 -1
- package/dist/utils/cli-pipeline.js.map +1 -0
- package/dist/utils/config.js +2 -1
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/credentials.js +2 -1
- package/dist/utils/credentials.js.map +1 -0
- package/dist/utils/environment-loader.js +2 -1
- package/dist/utils/environment-loader.js.map +1 -0
- package/dist/utils/file-finder.js +2 -1
- package/dist/utils/file-finder.js.map +1 -0
- package/dist/utils/json-comparator.js +2 -1
- package/dist/utils/json-comparator.js.map +1 -0
- package/dist/utils/json-comparison.js +2 -1
- package/dist/utils/json-comparison.js.map +1 -0
- package/dist/utils/mcp-runner.js +2 -1
- package/dist/utils/mcp-runner.js.map +1 -0
- package/dist/utils/model-config.js +2 -1
- package/dist/utils/model-config.js.map +1 -0
- package/dist/utils/package-manager.js +2 -1
- package/dist/utils/package-manager.js.map +1 -0
- package/dist/utils/profile-config.js +2 -1
- package/dist/utils/profile-config.js.map +1 -0
- package/dist/utils/profiles/profile-manager.js +2 -1
- package/dist/utils/profiles/profile-manager.js.map +1 -0
- package/dist/utils/profiles/types.js +2 -1
- package/dist/utils/profiles/types.js.map +1 -0
- package/dist/utils/project-directory.js +2 -1
- package/dist/utils/project-directory.js.map +1 -0
- package/dist/utils/project-loader.js +2 -1
- package/dist/utils/project-loader.js.map +1 -0
- package/dist/utils/schema-introspection.js +2 -1
- package/dist/utils/schema-introspection.js.map +1 -0
- package/dist/utils/templates.js +2 -1
- package/dist/utils/templates.js.map +1 -0
- package/dist/utils/tsx-loader.js +2 -1
- package/dist/utils/tsx-loader.js.map +1 -0
- package/dist/utils/version-check.js +2 -1
- package/dist/utils/version-check.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":[""],"mappings":""}
|
package/dist/api.js
CHANGED
|
@@ -2,11 +2,6 @@ import { OPENAI_MODELS, apiFetch } from "@inkeep/agents-core";
|
|
|
2
2
|
|
|
3
3
|
//#region src/api.ts
|
|
4
4
|
var BaseApiClient = class {
|
|
5
|
-
apiUrl;
|
|
6
|
-
tenantId;
|
|
7
|
-
projectId;
|
|
8
|
-
apiKey;
|
|
9
|
-
isCI;
|
|
10
5
|
constructor(apiUrl, tenantId, projectId, apiKey, isCI = false) {
|
|
11
6
|
this.apiUrl = apiUrl;
|
|
12
7
|
this.tenantId = tenantId;
|
|
@@ -23,7 +18,7 @@ var BaseApiClient = class {
|
|
|
23
18
|
* Uses X-API-Key for CI mode, Authorization Bearer for interactive mode
|
|
24
19
|
*/
|
|
25
20
|
async authenticatedFetch(url, options = {}) {
|
|
26
|
-
const headers = { ...options.headers
|
|
21
|
+
const headers = { ...options.headers };
|
|
27
22
|
if (this.apiKey) if (this.isCI) headers["X-API-Key"] = this.apiKey;
|
|
28
23
|
else headers.Authorization = `Bearer ${this.apiKey}`;
|
|
29
24
|
return apiFetch(url, {
|
|
@@ -45,8 +40,8 @@ var BaseApiClient = class {
|
|
|
45
40
|
}
|
|
46
41
|
};
|
|
47
42
|
var ManagementApiClient = class ManagementApiClient extends BaseApiClient {
|
|
48
|
-
constructor(
|
|
49
|
-
super(
|
|
43
|
+
constructor(...args) {
|
|
44
|
+
super(...args);
|
|
50
45
|
}
|
|
51
46
|
static async create(apiUrl, configPath, tenantIdOverride, projectIdOverride, isCI, apiKeyOverride) {
|
|
52
47
|
const { validateConfiguration } = await import("./utils/config.js");
|
|
@@ -203,8 +198,8 @@ var ManagementApiClient = class ManagementApiClient extends BaseApiClient {
|
|
|
203
198
|
}
|
|
204
199
|
};
|
|
205
200
|
var ExecutionApiClient = class ExecutionApiClient extends BaseApiClient {
|
|
206
|
-
constructor(
|
|
207
|
-
super(
|
|
201
|
+
constructor(...args) {
|
|
202
|
+
super(...args);
|
|
208
203
|
}
|
|
209
204
|
static async create(apiUrl, configPath, tenantIdOverride, projectIdOverride, isCI) {
|
|
210
205
|
const { validateConfiguration } = await import("./utils/config.js");
|
|
@@ -242,4 +237,5 @@ var ExecutionApiClient = class ExecutionApiClient extends BaseApiClient {
|
|
|
242
237
|
};
|
|
243
238
|
|
|
244
239
|
//#endregion
|
|
245
|
-
export { ExecutionApiClient, ManagementApiClient };
|
|
240
|
+
export { ExecutionApiClient, ManagementApiClient };
|
|
241
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","names":["errorText"],"sources":["../src/api.ts"],"sourcesContent":["// Import shared API client from agents-core\nimport {\n type AgentApiInsert,\n type AgentApiSelect,\n apiFetch,\n type FullProjectSelectResponse,\n OPENAI_MODELS,\n} from '@inkeep/agents-core';\nimport type { z } from 'zod';\n\ntype FullProjectResponse = z.infer<typeof FullProjectSelectResponse>;\n\nabstract class BaseApiClient {\n protected constructor(\n protected apiUrl: string,\n protected tenantId: string | undefined,\n protected projectId: string,\n protected apiKey?: string,\n protected isCI = false\n ) {}\n\n protected checkTenantId(): string {\n if (!this.tenantId) {\n throw new Error('No tenant ID configured. Please run: inkeep init');\n }\n return this.tenantId;\n }\n\n /**\n * Wrapper around fetch that automatically includes auth header\n * Uses X-API-Key for CI mode, Authorization Bearer for interactive mode\n */\n protected async authenticatedFetch(url: string, options: RequestInit = {}): Promise<Response> {\n // Build headers with auth if API key is present\n const headers: Record<string, string> = {\n ...(options.headers as Record<string, string>),\n };\n\n // Add auth header based on mode\n if (this.apiKey) {\n if (this.isCI) {\n // CI mode: use X-API-Key header for tenant-level API keys\n headers['X-API-Key'] = this.apiKey;\n } else {\n // Interactive mode: use Bearer token for user session tokens\n headers.Authorization = `Bearer ${this.apiKey}`;\n }\n }\n\n return apiFetch(url, {\n ...options,\n headers,\n });\n }\n\n getTenantId(): string | undefined {\n return this.tenantId;\n }\n\n getProjectId(): string {\n return this.projectId;\n }\n\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n getIsCI(): boolean {\n return this.isCI;\n }\n}\n\ntype ConstructorParams = [\n apiUrl: string,\n tenantId: string | undefined,\n projectId: string,\n apiKey?: string,\n isCI?: boolean,\n];\n\nexport class ManagementApiClient extends BaseApiClient {\n private constructor(...args: ConstructorParams) {\n super(...args);\n }\n\n static async create(\n apiUrl?: string,\n configPath?: string,\n tenantIdOverride?: string,\n projectIdOverride?: string,\n isCI?: boolean,\n apiKeyOverride?: string\n ): Promise<ManagementApiClient> {\n // Load config from file\n const { validateConfiguration } = await import('./utils/config.js');\n const config = await validateConfiguration(configPath);\n\n // Allow overrides from parameters\n const resolvedApiUrl = apiUrl || config.agentsApiUrl;\n const tenantId = tenantIdOverride || config.tenantId;\n const projectId = projectIdOverride || '';\n\n // Use explicit API key override if provided (e.g., from profile credentials)\n const apiKey = apiKeyOverride || config.agentsApiKey;\n\n return new ManagementApiClient(resolvedApiUrl, tenantId, projectId, apiKey, isCI ?? false);\n }\n\n async listAgents(): Promise<AgentApiSelect[]> {\n const tenantId = this.checkTenantId();\n const projectId = this.getProjectId();\n\n const response = await this.authenticatedFetch(\n `${this.apiUrl}/manage/tenants/${tenantId}/projects/${projectId}/agents?limit=100`,\n {\n method: 'GET',\n }\n );\n\n if (!response.ok) {\n throw new Error(\n `Failed to list agents: ${response.statusText}. ${this.apiUrl}/manage/tenants/${tenantId}/projects/${projectId}/agents`\n );\n }\n\n const data = await response.json();\n return data.data || [];\n }\n\n async getAgent(agentId: string): Promise<AgentApiSelect | null> {\n // Since there's no dedicated GET endpoint for agents,\n // we check if the agent exists in the CRUD endpoint\n const agents = await this.listAgents();\n const agent = agents.find((g) => g.id === agentId);\n\n // If found in CRUD, return it as a valid agent\n // The agent is usable for chat even without a dedicated GET endpoint\n return agent || null;\n }\n\n async pushAgent(agentDefinition: AgentApiInsert): Promise<any> {\n const tenantId = this.checkTenantId();\n const projectId = this.getProjectId();\n\n const agentId = agentDefinition.id;\n if (!agentId) {\n throw new Error('Agent must have an id property');\n }\n\n // Try to update first using PUT, if it doesn't exist, it will create it\n const response = await this.authenticatedFetch(\n `${this.apiUrl}/manage/tenants/${tenantId}/projects/${projectId}/agents/${agentId}`,\n {\n method: 'PUT',\n body: JSON.stringify({\n ...agentDefinition,\n tenantId,\n }),\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to push agent: ${response.statusText}\\n${errorText}`);\n }\n\n const data = await response.json();\n return data.data;\n }\n\n async getFullProject(projectId: string): Promise<FullProjectResponse['data']> {\n const tenantId = this.checkTenantId();\n\n const response = await this.authenticatedFetch(\n `${this.apiUrl}/manage/tenants/${tenantId}/project-full/${projectId}`,\n {\n method: 'GET',\n }\n );\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new Error(`Project \"${projectId}\" not found`);\n }\n if (response.status === 401 || response.status === 403) {\n const errorText = await response.text().catch(() => '');\n let errorMessage = 'Authentication failed - check your API key configuration\\n\\n';\n errorMessage += 'Common issues:\\n';\n errorMessage += ' • Missing or invalid API key in inkeep.config.ts\\n';\n errorMessage += ' • API key does not have access to this tenant/project\\n';\n errorMessage +=\n ' • For local development, ensure INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET is set\\n';\n if (errorText) {\n errorMessage += `\\nServer response: ${errorText}`;\n }\n throw new Error(errorMessage);\n }\n const errorText = await response.text().catch(() => '');\n throw new Error(\n `Failed to fetch project: ${response.statusText}${errorText ? `\\n${errorText}` : ''}`\n );\n }\n\n const responseData = await response.json();\n return responseData.data;\n }\n\n /**\n * List all projects for the current tenant\n * @param page - Page number (1-based)\n * @param limit - Number of results per page (max 100)\n * @returns List of projects with pagination info\n */\n async listProjects(\n page: number = 1,\n limit: number = 100\n ): Promise<{ data: any[]; pagination: { page: number; limit: number; total: number } }> {\n const tenantId = this.checkTenantId();\n\n const response = await this.authenticatedFetch(\n `${this.apiUrl}/manage/tenants/${tenantId}/projects?page=${page}&limit=${limit}`,\n {\n method: 'GET',\n }\n );\n\n if (!response.ok) {\n if (response.status === 401 || response.status === 403) {\n const errorText = await response.text().catch(() => '');\n let errorMessage = 'Authentication failed - check your API key configuration\\n\\n';\n errorMessage += 'Common issues:\\n';\n errorMessage += ' • Missing or invalid API key in inkeep.config.ts\\n';\n errorMessage += ' • API key does not have access to this tenant\\n';\n if (errorText) {\n errorMessage += `\\nServer response: ${errorText}`;\n }\n throw new Error(errorMessage);\n }\n const errorText = await response.text().catch(() => '');\n throw new Error(\n `Failed to list projects: ${response.statusText}${errorText ? `\\n${errorText}` : ''}`\n );\n }\n\n const responseData = await response.json();\n return responseData;\n }\n\n /**\n * List all projects for the current tenant (fetches all pages)\n * @returns Array of all projects\n */\n async listAllProjects(): Promise<any[]> {\n const allProjects: any[] = [];\n let page = 1;\n const limit = 100;\n\n while (true) {\n const result = await this.listProjects(page, limit);\n allProjects.push(...result.data);\n\n // Check if we've fetched all projects\n if (result.data.length < limit || allProjects.length >= result.pagination.total) {\n break;\n }\n page++;\n }\n\n return allProjects;\n }\n\n async getDataComponent(componentId: string): Promise<{\n id: string;\n name: string;\n render: { component: string; mockData: Record<string, unknown> } | null;\n } | null> {\n const tenantId = this.checkTenantId();\n const projectId = this.getProjectId();\n const response = await this.authenticatedFetch(\n `${this.apiUrl}/manage/tenants/${tenantId}/projects/${projectId}/data-components/${componentId}`,\n { method: 'GET' }\n );\n if (response.status === 404) return null;\n if (!response.ok) {\n const err = await response.text().catch(() => '');\n throw new Error(\n `Failed to fetch data component: ${response.statusText}${err ? `\\n${err}` : ''}`\n );\n }\n const json = await response.json();\n return json.data ?? null;\n }\n\n async listDataComponents(): Promise<\n {\n id: string;\n name: string;\n render: { component: string; mockData: Record<string, unknown> } | null;\n }[]\n > {\n const tenantId = this.checkTenantId();\n const projectId = this.getProjectId();\n const all: {\n id: string;\n name: string;\n render: { component: string; mockData: Record<string, unknown> } | null;\n }[] = [];\n let page = 1;\n const limit = 100;\n let result: { data: any[]; pagination: { total: number } };\n do {\n const response = await this.authenticatedFetch(\n `${this.apiUrl}/manage/tenants/${tenantId}/projects/${projectId}/data-components?page=${page}&limit=${limit}`,\n { method: 'GET' }\n );\n if (!response.ok) {\n const err = await response.text().catch(() => '');\n throw new Error(\n `Failed to list data components: ${response.statusText}${err ? `\\n${err}` : ''}`\n );\n }\n result = await response.json();\n all.push(...(result.data || []));\n page++;\n } while (result.data?.length === limit && all.length < (result.pagination?.total ?? 0));\n return all;\n }\n\n async getArtifactComponent(componentId: string): Promise<{\n id: string;\n name: string;\n render: { component: string; mockData: Record<string, unknown> } | null;\n } | null> {\n const tenantId = this.checkTenantId();\n const projectId = this.getProjectId();\n const response = await this.authenticatedFetch(\n `${this.apiUrl}/manage/tenants/${tenantId}/projects/${projectId}/artifact-components/${componentId}`,\n { method: 'GET' }\n );\n if (response.status === 404) return null;\n if (!response.ok) {\n const err = await response.text().catch(() => '');\n throw new Error(\n `Failed to fetch artifact component: ${response.statusText}${err ? `\\n${err}` : ''}`\n );\n }\n const json = await response.json();\n return json.data ?? null;\n }\n\n async listArtifactComponents(): Promise<\n {\n id: string;\n name: string;\n render: { component: string; mockData: Record<string, unknown> } | null;\n }[]\n > {\n const tenantId = this.checkTenantId();\n const projectId = this.getProjectId();\n const all: {\n id: string;\n name: string;\n render: { component: string; mockData: Record<string, unknown> } | null;\n }[] = [];\n let page = 1;\n const limit = 100;\n let result: { data: any[]; pagination: { total: number } };\n do {\n const response = await this.authenticatedFetch(\n `${this.apiUrl}/manage/tenants/${tenantId}/projects/${projectId}/artifact-components?page=${page}&limit=${limit}`,\n { method: 'GET' }\n );\n if (!response.ok) {\n const err = await response.text().catch(() => '');\n throw new Error(\n `Failed to list artifact components: ${response.statusText}${err ? `\\n${err}` : ''}`\n );\n }\n result = await response.json();\n all.push(...(result.data || []));\n page++;\n } while (result.data?.length === limit && all.length < (result.pagination?.total ?? 0));\n return all;\n }\n}\n\nexport class ExecutionApiClient extends BaseApiClient {\n private constructor(...args: ConstructorParams) {\n super(...args);\n }\n\n static async create(\n apiUrl?: string,\n configPath?: string,\n tenantIdOverride?: string,\n projectIdOverride?: string,\n isCI?: boolean\n ): Promise<ExecutionApiClient> {\n // Load config from file\n const { validateConfiguration } = await import('./utils/config.js');\n const config = await validateConfiguration(configPath);\n\n // Allow overrides from parameters\n const resolvedApiUrl = apiUrl || config.agentsApiUrl;\n const tenantId = tenantIdOverride || config.tenantId;\n const projectId = projectIdOverride || '';\n\n return new ExecutionApiClient(\n resolvedApiUrl,\n tenantId,\n projectId,\n config.agentsApiKey,\n isCI ?? false\n );\n }\n\n async chatCompletion(\n agentId: string,\n messages: any[],\n conversationId?: string,\n emitOperations?: boolean\n ): Promise<ReadableStream<Uint8Array> | string> {\n const response = await this.authenticatedFetch(`${this.apiUrl}/run/v1/chat/completions`, {\n method: 'POST',\n headers: {\n Accept: 'text/event-stream',\n 'x-inkeep-tenant-id': this.tenantId || 'test-tenant-id',\n 'x-inkeep-project-id': this.projectId,\n 'x-inkeep-agent-id': agentId,\n ...(emitOperations && { 'x-emit-operations': 'true' }),\n },\n body: JSON.stringify({\n model: OPENAI_MODELS.GPT_4_1_MINI, // Required but will be overridden by graph config\n messages,\n conversationId,\n stream: true,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Chat request failed: ${response.statusText}\\n${errorText}`);\n }\n\n // Check if response is streaming\n const contentType = response.headers.get('content-type');\n if (contentType?.includes('text/event-stream')) {\n if (!response.body) {\n throw new Error('No response body for streaming request');\n }\n return response.body;\n }\n // Non-streaming response\n const data = await response.json();\n return data.choices?.[0]?.message?.content || data.result || '';\n }\n}\n"],"mappings":"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"}
|
package/dist/commands/add-ui.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-ui.js","names":[],"sources":["../../src/commands/add-ui.ts"],"sourcesContent":["import path from 'node:path';\nimport * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport { findUp } from 'find-up';\nimport fs from 'fs-extra';\nimport type { FunctionDeclaration, VariableStatement } from 'ts-morph';\nimport { Project } from 'ts-morph';\nimport { ManagementApiClient } from '../api';\nimport { initializeCommand } from '../utils/cli-pipeline';\nimport { findConfigFile, findProjectConfig } from '../utils/config';\n\nconst UI_DIR_RELATIVE = 'apps/agents-ui/src/ui';\n\nfunction toPascalCase(name: string): string {\n if (!name?.trim()) return 'Component';\n return name\n .trim()\n .replace(/[-_]+/g, ' ')\n .split(/\\s+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * Ensures the component declaration is exported using AST. Finds the first\n * function or const component (PascalCase name) and adds export if missing.\n */\nexport function ensureExported(code: string): string {\n try {\n const project = new Project({\n useInMemoryFileSystem: true,\n compilerOptions: { jsx: 1 },\n });\n const sourceFile = project.createSourceFile('temp.tsx', code);\n type Candidate =\n | { start: number; type: 'function'; node: FunctionDeclaration }\n | { start: number; type: 'variable'; node: VariableStatement };\n const candidates: Candidate[] = [];\n for (const fn of sourceFile.getFunctions()) {\n if (fn.getName()) candidates.push({ start: fn.getStart(), type: 'function', node: fn });\n }\n for (const stmt of sourceFile.getVariableStatements()) {\n const decl = stmt.getDeclarationList().getDeclarations()[0];\n const name = decl?.getName?.();\n if (typeof name === 'string' && name.length > 0 && name[0] === name[0].toUpperCase()) {\n candidates.push({ start: stmt.getStart(), type: 'variable', node: stmt });\n }\n }\n candidates.sort((a, b) => a.start - b.start);\n const first = candidates[0];\n if (!first) return code;\n if (first.type === 'function') {\n if (!first.node.isExported()) first.node.setIsExported(true);\n } else {\n if (!first.node.hasExportKeyword()) first.node.toggleModifier('export', true);\n }\n return sourceFile.getFullText();\n } catch {\n return code;\n }\n}\n\nasync function findUiDirectory(): Promise<string> {\n const cwd = process.cwd();\n const uiDir = path.join(cwd, UI_DIR_RELATIVE);\n if (await fs.pathExists(uiDir)) return uiDir;\n const found = await findUp(UI_DIR_RELATIVE, { type: 'directory' });\n if (found) return found;\n const agentsUi = await findUp('apps/agents-ui-demo', { type: 'directory' });\n if (agentsUi) return path.join(agentsUi, 'src', 'ui');\n return path.join(cwd, UI_DIR_RELATIVE);\n}\n\ntype ComponentItem = {\n id: string;\n name: string;\n render: { component: string; mockData: Record<string, unknown> } | null;\n};\n\nasync function fetchAllComponentsWithRender(\n client: ManagementApiClient\n): Promise<{ data: ComponentItem[]; artifact: ComponentItem[] }> {\n const [dataComponents, artifactComponents] = await Promise.all([\n client.listDataComponents(),\n client.listArtifactComponents(),\n ]);\n return { data: dataComponents, artifact: artifactComponents };\n}\n\nfunction formatComponentList(data: ComponentItem[], artifact: ComponentItem[]): string {\n const withRender = (c: ComponentItem) => c.render?.component?.trim();\n const lines: string[] = [];\n for (const c of data.filter(withRender)) {\n lines.push(` ${chalk.cyan(c.id)} ${chalk.gray('(data)')} ${c.name}`);\n }\n for (const c of artifact.filter(withRender)) {\n lines.push(` ${chalk.cyan(c.id)} ${chalk.gray('(artifact)')} ${c.name}`);\n }\n return lines.length ? lines.join('\\n') : ' (none with render code)';\n}\n\nexport interface AddUiOptions {\n ui?: string | true;\n list?: boolean;\n config?: string;\n profile?: string;\n quiet?: boolean;\n}\n\nexport async function addUiCommand(options: AddUiOptions): Promise<void> {\n const componentId = typeof options.ui === 'string' ? options.ui : undefined;\n\n const configPath = options.config\n ? path.resolve(process.cwd(), options.config)\n : findConfigFile(process.cwd());\n if (!configPath) {\n console.error(\n chalk.red(\n 'No Inkeep config found. Run from a project directory with inkeep.config.ts or pass --config <path>.'\n )\n );\n process.exit(1);\n }\n\n const { config, isCI } = await initializeCommand({\n configPath,\n profileName: options.profile,\n showSpinner: true,\n spinnerText: 'Loading configuration...',\n logConfig: !options.quiet,\n quiet: options.quiet,\n });\n\n const projectConfig = await findProjectConfig(path.dirname(configPath));\n const projectId = projectConfig?.projectId ?? null;\n if (!projectId) {\n console.error(\n chalk.red('Project ID not found in config. Set projectId in your inkeep.config.ts.')\n );\n process.exit(1);\n }\n\n if (!config.agentsApiKey) {\n console.error(\n chalk.red('Not authenticated. Run \"inkeep login\" or set agentsApi.apiKey in your config.')\n );\n process.exit(1);\n }\n\n let client: ManagementApiClient;\n try {\n client = await ManagementApiClient.create(\n config.agentsApiUrl,\n configPath,\n config.tenantId,\n projectId,\n isCI ?? false,\n config.agentsApiKey\n );\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(chalk.red(`Failed to create API client: ${message}`));\n process.exit(1);\n }\n\n const toWrite: { pascalName: string; code: string }[] = [];\n const s = p.spinner();\n\n if (options.list) {\n s.start('Fetching components...');\n const { data: dataComponents, artifact: artifactComponents } =\n await fetchAllComponentsWithRender(client);\n s.stop();\n console.log(chalk.cyan('\\nAvailable UI components (use id with inkeep add --ui <id>):\\n'));\n console.log(formatComponentList(dataComponents, artifactComponents));\n console.log('');\n process.exit(0);\n }\n\n s.start('Resolving UI directory...');\n const uiDir = await findUiDirectory();\n await fs.ensureDir(uiDir);\n s.stop();\n\n if (componentId) {\n let comp: ComponentItem | null = await client.getDataComponent(componentId);\n let kind = 'data';\n if (!comp) {\n comp = await client.getArtifactComponent(componentId);\n kind = 'artifact';\n }\n if (!comp) {\n s.start('Fetching available components...');\n const { data: dataComponents, artifact: artifactComponents } =\n await fetchAllComponentsWithRender(client);\n s.stop();\n console.error(\n chalk.red(`Component \"${componentId}\" not found (tried data and artifact components).`)\n );\n console.log(chalk.cyan('\\nAvailable UI components (use id with inkeep add --ui <id>):\\n'));\n console.log(formatComponentList(dataComponents, artifactComponents));\n console.log('');\n process.exit(1);\n }\n if (!comp.render?.component?.trim()) {\n console.error(\n chalk.red(\n `Component \"${comp.name}\" (${kind}) has no render code. Generate a render in the dashboard first.`\n )\n );\n process.exit(1);\n }\n const pascalName = toPascalCase(comp.name);\n toWrite.push({ pascalName, code: ensureExported(comp.render.component) });\n } else {\n s.start('Fetching data and artifact components...');\n const [dataComponents, artifactComponents] = await Promise.all([\n client.listDataComponents(),\n client.listArtifactComponents(),\n ]);\n s.stop();\n const withRender = (c: ComponentItem) =>\n c.render?.component?.trim()\n ? { pascalName: toPascalCase(c.name), code: ensureExported(c.render.component) }\n : null;\n for (const c of dataComponents) {\n const item = withRender(c);\n if (item) toWrite.push(item);\n }\n for (const c of artifactComponents) {\n const item = withRender(c);\n if (item) toWrite.push(item);\n }\n if (toWrite.length === 0) {\n console.log(\n chalk.yellow(\n 'No components with render code found. Generate renders in the dashboard first.'\n )\n );\n process.exit(0);\n }\n }\n\n s.start(`Writing ${toWrite.length} component(s) to ${uiDir}...`);\n for (const { pascalName, code } of toWrite) {\n const filePath = path.join(uiDir, `${pascalName}.tsx`);\n await fs.writeFile(filePath, code, 'utf-8');\n }\n s.stop(\n chalk.green(\n `Added ${toWrite.length} component(s) to ${path.relative(process.cwd(), uiDir)}. ` +\n `Import with: import { <Name> } from './ui/<Name>';`\n )\n );\n}\n"],"mappings":"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"}
|
package/dist/commands/add.js
CHANGED
|
@@ -147,4 +147,5 @@ async function findAppDirectory(type) {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
//#endregion
|
|
150
|
-
export { addCommand, addMcpTemplate, addProjectTemplate, checkTemplateDir, defaultAnthropicModelConfigurations, defaultGoogleModelConfigurations, defaultOpenaiModelConfigurations, findAppDirectory };
|
|
150
|
+
export { addCommand, addMcpTemplate, addProjectTemplate, checkTemplateDir, defaultAnthropicModelConfigurations, defaultGoogleModelConfigurations, defaultOpenaiModelConfigurations, findAppDirectory };
|
|
151
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","names":["template"],"sources":["../../src/commands/add.ts"],"sourcesContent":["import path from 'node:path';\nimport * as p from '@clack/prompts';\nimport { ANTHROPIC_MODELS, GOOGLE_MODELS, OPENAI_MODELS } from '@inkeep/agents-core';\nimport chalk from 'chalk';\nimport { findUp } from 'find-up';\nimport fs from 'fs-extra';\nimport type { ModelSettings } from '../utils/model-config';\nimport {\n type ContentReplacement,\n cloneTemplate,\n cloneTemplateLocal,\n getAvailableTemplates,\n} from '../utils/templates';\nimport { addUiCommand } from './add-ui';\n\nexport interface AddOptions {\n project?: string;\n mcp?: string;\n ui?: string | true;\n list?: boolean;\n targetPath?: string;\n config?: string;\n profile?: string;\n quiet?: boolean;\n localPrefix?: string;\n}\n\nexport const defaultGoogleModelConfigurations: ModelSettings = {\n base: {\n model: GOOGLE_MODELS.GEMINI_2_5_FLASH,\n },\n structuredOutput: {\n model: GOOGLE_MODELS.GEMINI_2_5_FLASH_LITE,\n },\n summarizer: {\n model: GOOGLE_MODELS.GEMINI_2_5_FLASH_LITE,\n },\n};\n\nexport const defaultOpenaiModelConfigurations: ModelSettings = {\n base: {\n model: OPENAI_MODELS.GPT_5_2,\n },\n structuredOutput: {\n model: OPENAI_MODELS.GPT_4_1_MINI,\n },\n summarizer: {\n model: OPENAI_MODELS.GPT_4_1_NANO,\n },\n};\n\nexport const defaultAnthropicModelConfigurations: ModelSettings = {\n base: {\n model: ANTHROPIC_MODELS.CLAUDE_SONNET_4_5,\n },\n structuredOutput: {\n model: ANTHROPIC_MODELS.CLAUDE_SONNET_4_5,\n },\n summarizer: {\n model: ANTHROPIC_MODELS.CLAUDE_SONNET_4_5,\n },\n};\n\nexport async function addCommand(options: AddOptions): Promise<void> {\n if (options.ui !== undefined) {\n await addUiCommand({\n ui: options.ui,\n list: options.list,\n config: options.config,\n profile: options.profile,\n quiet: options.quiet,\n });\n return;\n }\n const projectTemplates = await getAvailableTemplates('template-projects', options.localPrefix);\n const mcpTemplates = await getAvailableTemplates('template-mcps', options.localPrefix);\n if (!options.project && !options.mcp) {\n console.log(chalk.cyan('\\nUsage:\\n'));\n console.log(chalk.white('Add a project with: inkeep add --project <project-template>'));\n console.log(chalk.gray(' Example: inkeep add --project docs-assistant\\n'));\n console.log(chalk.yellow('Available project templates:'));\n for (const template of projectTemplates) {\n console.log(chalk.gray(` • ${template}`));\n }\n\n console.log(chalk.white('\\nAdd an MCP server with: inkeep add --mcp <mcp-template>'));\n console.log(chalk.gray(' Example: inkeep add --mcp slack\\n'));\n console.log(chalk.yellow('Available MCP templates:'));\n for (const template of mcpTemplates) {\n console.log(chalk.gray(` • ${template}`));\n }\n process.exit(0);\n } else {\n if (options.project && !projectTemplates.includes(options.project)) {\n console.error(`❌ Project template \"${options.project}\" not found`);\n process.exit(1);\n }\n if (options.mcp && !mcpTemplates.includes(options.mcp)) {\n console.error(`❌ MCP template \"${options.mcp}\" not found`);\n process.exit(1);\n }\n\n if (options.project) {\n await addProjectTemplate(\n projectTemplates,\n options.project,\n options.targetPath,\n options.localPrefix\n );\n }\n if (options.mcp) {\n await addMcpTemplate(mcpTemplates, options.mcp, options.targetPath, options.localPrefix);\n }\n return;\n }\n}\n\nexport async function checkTemplateDir(\n templateDir: string,\n commandType: 'project' | 'mcp'\n): Promise<void> {\n const s = p.spinner();\n // Check if the template directory already exists\n if (await fs.pathExists(templateDir)) {\n const overwrite = await p.confirm({\n message: `Directory \"${templateDir}\" already exists. Do you want to overwrite it?`,\n });\n if (!overwrite) {\n p.cancel(\n `You can specify a different target path like: \\`inkeep add --${commandType} <${commandType}-template> --target-path <path>\\``\n );\n process.exit(0);\n }\n s.start('Cleaning existing directory...');\n await fs.emptyDir(templateDir);\n s.stop();\n }\n}\n\nfunction buildTemplateUrl(\n templateType: 'template-projects' | 'template-mcps',\n templateName: string\n): string {\n return `https://github.com/inkeep/agents/agents-cookbook/${templateType}/${templateName}`;\n}\n\nexport async function addProjectTemplate(\n availableTemplates: string[],\n template: string,\n targetPath: string | undefined,\n localPrefix: string | undefined\n): Promise<void> {\n if (!template) {\n console.log(chalk.yellow('Available templates:'));\n for (const template of availableTemplates) {\n console.log(chalk.gray(` • ${template}`));\n }\n process.exit(0);\n } else {\n if (!availableTemplates.includes(template)) {\n console.error(`❌ Template \"${template}\" not found`);\n process.exit(1);\n }\n const s = p.spinner();\n\n const anthropicKey = process.env.ANTHROPIC_API_KEY;\n const openAiKey = process.env.OPENAI_API_KEY;\n const googleKey = process.env.GOOGLE_GENERATIVE_AI_API_KEY;\n\n let defaultModelSettings = {};\n if (anthropicKey) {\n defaultModelSettings = defaultAnthropicModelConfigurations;\n } else if (openAiKey) {\n defaultModelSettings = defaultOpenaiModelConfigurations;\n } else if (googleKey) {\n defaultModelSettings = defaultGoogleModelConfigurations;\n }\n\n const contentReplacements: ContentReplacement[] = [\n {\n filePath: 'index.ts',\n replacements: {\n models: defaultModelSettings,\n },\n },\n ];\n\n // Check if the model settings are empty\n if (Object.keys(defaultModelSettings).length === 0) {\n console.error(\n '❌ No AI provider key found in environment variables. Please set one of: ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_GENERATIVE_AI_API_KEY'\n );\n }\n const projectDirectory = await findAppDirectory('project');\n\n // Determine the base directory (use provided target path or current directory)\n const baseDir = targetPath || projectDirectory;\n\n // Create the full path including the template name as a subdirectory\n const templateDir = path.join(baseDir, template);\n\n await checkTemplateDir(templateDir, 'project');\n\n // Ensure the base directory exists\n if (targetPath && !(await fs.pathExists(baseDir))) {\n try {\n await fs.mkdir(baseDir, { recursive: true });\n } catch (error) {\n console.error(\n `❌ Failed to create target directory \"${baseDir}\": ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n process.exit(1);\n }\n }\n\n s.start('Adding template...');\n\n // Clone into the template-named subdirectory\n if (localPrefix && localPrefix.length > 0) {\n const fullTemplatePath = path.join(localPrefix, 'template-projects', template);\n await cloneTemplateLocal(fullTemplatePath, templateDir, contentReplacements);\n } else {\n const fullTemplatePath = buildTemplateUrl('template-projects', template);\n await cloneTemplate(fullTemplatePath, templateDir, contentReplacements);\n }\n s.stop(`Template \"${template}\" added to ${templateDir}`);\n return;\n }\n}\n\nexport async function addMcpTemplate(\n availableTemplates: string[],\n template: string,\n targetPath: string | undefined,\n localPrefix: string | undefined\n): Promise<void> {\n if (!template) {\n console.log(chalk.yellow('Available templates:'));\n for (const template of availableTemplates) {\n console.log(chalk.gray(` • ${template}`));\n }\n process.exit(0);\n }\n\n if (!targetPath) {\n const foundPath = await findAppDirectory('mcp');\n targetPath = path.join(foundPath, template);\n }\n\n await checkTemplateDir(targetPath, 'mcp');\n\n const s = p.spinner();\n s.start('Adding template...');\n if (localPrefix && localPrefix.length > 0) {\n const fullTemplatePath = path.join(localPrefix, 'template-mcps', template);\n await cloneTemplateLocal(fullTemplatePath, targetPath);\n } else {\n const fullTemplatePath = buildTemplateUrl('template-mcps', template);\n await cloneTemplate(fullTemplatePath, targetPath);\n }\n s.stop(`MCP template \"${template}\" added to ${targetPath}`);\n}\n\nexport async function findAppDirectory(type: 'project' | 'mcp'): Promise<string> {\n const searchPath = type === 'project' ? 'src/projects' : 'apps/mcp/app';\n const directory = await findUp(searchPath, { type: 'directory' });\n\n if (!directory || !directory.includes(searchPath)) {\n console.log(chalk.yellow(`⚠️ No ${type} directory found.`));\n const continueAnyway = await p.confirm({\n message: `Do you want to add to ${process.cwd()} instead?`,\n });\n if (!continueAnyway) {\n p.cancel('Operation cancelled');\n process.exit(0);\n }\n }\n return directory || process.cwd();\n}\n"],"mappings":"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"}
|
package/dist/commands/config.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../../src/commands/config.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport chalk from 'chalk';\nimport { LOCAL_REMOTE } from '../utils/profiles';\n\nexport interface ConfigOptions {\n config?: string;\n configFilePath?: string; // deprecated, kept for backward compatibility\n}\n\nexport async function configGetCommand(key?: string, options?: ConfigOptions): Promise<void> {\n // Use new config parameter, fall back to configFilePath for backward compatibility\n const configPath =\n options?.config || options?.configFilePath || join(process.cwd(), 'inkeep.config.ts');\n\n if (!existsSync(configPath)) {\n console.error(chalk.red('No configuration file found.'));\n console.log(\n chalk.gray('Run \"inkeep init\" to create one, or specify a config file with --config')\n );\n process.exit(1);\n }\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n\n // Parse the config file to extract values\n const tenantIdMatch = content.match(/tenantId:\\s*['\"]([^'\"]+)['\"]/);\n const apiUrlMatch = content.match(/apiUrl:\\s*['\"]([^'\"]+)['\"]/);\n\n const config = {\n tenantId: tenantIdMatch ? tenantIdMatch[1] : undefined,\n apiUrl: apiUrlMatch ? apiUrlMatch[1] : undefined,\n };\n\n if (key) {\n // Get specific key\n const value = config[key as keyof typeof config];\n if (value !== undefined) {\n console.log(value);\n } else {\n console.error(chalk.red(`Unknown configuration key: ${key}`));\n console.log(chalk.gray('Available keys: tenantId, apiUrl'));\n process.exit(1);\n }\n } else {\n // Display all config\n console.log(chalk.cyan('Current configuration:'));\n console.log(chalk.gray(' Config file:'), configPath);\n console.log(chalk.gray(' Tenant ID:'), config.tenantId || chalk.yellow('(not set)'));\n console.log(chalk.gray(' API URL:'), config.apiUrl || chalk.yellow('(not set)'));\n }\n } catch (error) {\n console.error(chalk.red('Failed to read configuration:'), error);\n process.exit(1);\n }\n}\n\nexport async function configSetCommand(\n key: string,\n value: string,\n options?: ConfigOptions\n): Promise<void> {\n // Use new config parameter, fall back to configFilePath for backward compatibility\n const configPath =\n options?.config || options?.configFilePath || join(process.cwd(), 'inkeep.config.ts');\n\n // Validate the key\n if (!['tenantId', 'apiUrl'].includes(key)) {\n console.error(chalk.red(`Invalid configuration key: ${key}`));\n console.log(chalk.gray('Available keys: tenantId, apiUrl'));\n process.exit(1);\n }\n\n // Validate apiUrl if setting it\n if (key === 'apiUrl') {\n try {\n new URL(value);\n } catch {\n console.error(chalk.red('Invalid URL format'));\n process.exit(1);\n }\n }\n\n if (!existsSync(configPath)) {\n // Create a new config file if it doesn't exist\n const configContent = `import { defineConfig } from '@inkeep/agents-cli';\n\nexport default defineConfig({\n tenantId: '${key === 'tenantId' ? value : ''}',\n apiUrl: '${key === 'apiUrl' ? value : LOCAL_REMOTE.api}',\n});\n`;\n\n try {\n writeFileSync(configPath, configContent);\n console.log(chalk.green('✓'), `Created config file and set ${key} to:`, chalk.cyan(value));\n } catch (error) {\n console.error(chalk.red('Failed to create config file:'), error);\n process.exit(1);\n }\n } else {\n // Update existing config file\n try {\n let content = readFileSync(configPath, 'utf-8');\n\n if (key === 'tenantId') {\n // Update or add tenantId\n if (content.includes('tenantId:')) {\n content = content.replace(/tenantId:\\s*['\"][^'\"]*['\"]/, `tenantId: '${value}'`);\n } else {\n // Add tenantId to the config object\n content = content.replace(\n /defineConfig\\s*\\(\\s*{/,\n `defineConfig({\\n tenantId: '${value}',`\n );\n }\n } else if (key === 'apiUrl') {\n // Update or add apiUrl\n if (content.includes('apiUrl:')) {\n content = content.replace(/apiUrl:\\s*['\"][^'\"]*['\"]/, `apiUrl: '${value}'`);\n } else {\n // Add apiUrl to the config object\n content = content.replace(\n /defineConfig\\s*\\(\\s*{/,\n `defineConfig({\\n apiUrl: '${value}',`\n );\n }\n }\n\n writeFileSync(configPath, content);\n console.log(chalk.green('✓'), `Updated ${key} to:`, chalk.cyan(value));\n } catch (error) {\n console.error(chalk.red('Failed to update config file:'), error);\n process.exit(1);\n }\n }\n}\n\nexport async function configListCommand(options?: ConfigOptions): Promise<void> {\n // Alias for configGetCommand without a key\n await configGetCommand(undefined, options);\n}\n"],"mappings":"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"}
|
package/dist/commands/dev.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","names":["resolve","path"],"sources":["../../src/commands/dev.ts"],"sourcesContent":["import { fork } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport fs from 'fs-extra';\nimport open from 'open';\n\nconst require = createRequire(import.meta.url);\n\nasync function waitForServer(host: string, port: number, maxAttempts = 60): Promise<boolean> {\n for (let i = 0; i < maxAttempts; i++) {\n try {\n const response = await fetch(`http://${host}:${port}`, {\n method: 'GET',\n signal: AbortSignal.timeout(2000),\n });\n if (response.ok) {\n const text = await response.text();\n if (text && text.length > 0 && text.includes('<!DOCTYPE html>')) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n return true;\n }\n }\n } catch {\n // Server not ready yet, wait and retry\n }\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n return false;\n}\n\nexport interface DevOptions {\n port: number;\n host: string;\n build: boolean;\n outputDir: string;\n path: boolean;\n export: boolean;\n openBrowser: boolean;\n}\n\nfunction resolveWebRuntime(isRoot = false) {\n try {\n // First try to resolve as a package (if installed)\n const pkg = require.resolve('@inkeep/agents-manage-ui/package.json');\n const root = dirname(pkg);\n\n if (isRoot) {\n return root;\n }\n\n return join(root, '.next/standalone/agents-manage-ui');\n } catch (err) {\n throw new Error(\n `Could not find @inkeep/agents-manage-ui package. Please install it first:\\n\\n` +\n ` npm install @inkeep/agents-manage-ui\\n` +\n ` # or\\n` +\n ` pnpm add @inkeep/agents-manage-ui\\n\\n` +\n `Error: ${err instanceof Error ? err.message : 'Unknown error'}`\n );\n }\n}\n\nasync function startWebApp({\n port,\n host,\n openBrowser,\n}: Pick<DevOptions, 'port' | 'host' | 'openBrowser'>) {\n console.log('');\n const s = p.spinner();\n s.start('Starting dashboard server...');\n\n try {\n const rt = resolveWebRuntime();\n const entry = join(rt, 'server.js');\n // Check if the standalone build exists\n if (!existsSync(entry)) {\n s.stop('Dashboard server not found');\n console.error(chalk.red('The dashboard server has not been built yet.'));\n process.exit(1);\n }\n\n s.stop('Starting dashboard server...');\n console.log('');\n\n const child = fork(entry, [], {\n cwd: rt,\n env: {\n ...process.env,\n NODE_ENV: 'production',\n PORT: String(port),\n HOSTNAME: host,\n },\n stdio: 'inherit',\n });\n\n console.log(chalk.green(`🚀 Dashboard server started at http://${host}:${port}`));\n console.log('');\n console.log(chalk.gray('Press Ctrl+C to stop the server'));\n console.log('');\n\n if (openBrowser) {\n console.log(chalk.gray('Waiting for server to be ready...'));\n const isReady = await waitForServer(host, port);\n if (isReady) {\n await open(`http://${host}:${port}`);\n } else {\n console.log(chalk.yellow('⚠️ Server did not respond in time, skipping browser open'));\n console.log(chalk.gray(` You can manually open: http://${host}:${port}`));\n }\n }\n\n // Handle process termination\n process.on('SIGINT', () => {\n console.log('');\n console.log(chalk.yellow('\\n🛑 Stopping dashboard server...'));\n child.kill('SIGINT');\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n child.kill('SIGTERM');\n process.exit(0);\n });\n\n return child;\n } catch (error) {\n s.stop('Failed to start dashboard server');\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');\n process.exit(1);\n }\n}\n\nasync function buildNextApp({ outputDir }: { outputDir: string }) {\n console.log('');\n const s = p.spinner();\n s.start('Building Standalone build...');\n\n try {\n const pkg = require.resolve('@inkeep/agents-manage-ui/package.json');\n const root = dirname(pkg);\n const standalonePath = join(root, '.next/standalone/agents-manage-ui');\n\n // Check if the standalone build exists\n if (!existsSync(standalonePath)) {\n s.stop('Standalone build not found');\n console.error(chalk.red('The standalone build has not been created yet.'));\n console.error(chalk.yellow('Please build the dashboard first:'));\n console.error(chalk.gray(' cd node_modules/@inkeep/agents-manage-ui'));\n console.error(chalk.gray(' npm run build'));\n process.exit(1);\n }\n\n // 2. Remove existing output directory if it exists\n if (existsSync(outputDir)) {\n await fs.remove(outputDir);\n }\n\n // 2. Remove existing output directory if it exists\n if (existsSync(outputDir)) {\n await fs.remove(outputDir);\n }\n\n // 3. Create output directory\n await fs.ensureDir(outputDir);\n\n // 4. Copy the entire standalone package\n await fs.copy(standalonePath, outputDir);\n\n // 5. Create a simple package.json with the correct start script\n const packageJson = {\n name: 'inkeep-dashboard',\n version: '1.0.0',\n scripts: {\n start: 'node server.js',\n },\n dependencies: {},\n };\n\n await fs.writeJson(join(outputDir, 'package.json'), packageJson, { spaces: 2 });\n\n s.stop(`Build created at ${outputDir}/`);\n\n console.log('');\n console.log(chalk.green('✅ Build completed successfully!'));\n console.log('');\n console.log(chalk.blue('📁 To run your dashboard:'));\n console.log(chalk.gray(' cd'), chalk.white(outputDir));\n console.log(chalk.gray(' npm start'));\n console.log('');\n console.log(chalk.blue('🌐 Or with pnpm:'));\n console.log(chalk.gray(' cd'), chalk.white(outputDir));\n console.log(chalk.gray(' pnpm start'));\n console.log('');\n } catch (error) {\n s.stop('Failed to build dashboard');\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');\n throw error;\n }\n}\n\nasync function exportNextApp({ outputDir }: { outputDir: string }) {\n console.log('');\n const s = p.spinner();\n s.start('Exporting Next.js project...');\n\n try {\n const pkg = require.resolve('@inkeep/agents-manage-ui/package.json');\n const root = dirname(pkg);\n\n // Check if the source project exists\n if (!existsSync(root)) {\n s.stop('Source project not found');\n console.error(chalk.red('The @inkeep/agents-manage-ui package was not found.'));\n console.error(chalk.yellow('Please install it first:'));\n console.error(chalk.gray(' npm install @inkeep/agents-manage-ui'));\n console.error(chalk.gray(' # or'));\n console.error(chalk.gray(' pnpm add @inkeep/agents-manage-ui'));\n process.exit(1);\n }\n\n // Remove existing output directory if it exists\n if (existsSync(outputDir)) {\n await fs.remove(outputDir);\n }\n\n // Create output directory\n await fs.ensureDir(outputDir);\n\n // Copy all files except .next folder\n const items = await fs.readdir(root);\n for (const item of items) {\n const srcPath = join(root, item);\n const destPath = join(outputDir, item);\n\n // Skip .next folder and other build artifacts\n if (item === '.next' || item === 'node_modules' || item === 'dist') {\n continue;\n }\n\n const stat = await fs.stat(srcPath);\n if (stat.isDirectory()) {\n await fs.copy(srcPath, destPath);\n } else {\n await fs.copy(srcPath, destPath);\n }\n }\n\n s.stop(`Project exported to ${outputDir}/`);\n\n console.log('');\n console.log(chalk.green('✅ Export completed successfully!'));\n console.log('');\n console.log(chalk.blue('📁 To get started:'));\n console.log(chalk.gray(' cd'), chalk.white(outputDir));\n console.log(chalk.gray(' npm install'));\n console.log(chalk.gray(' npm run dev'));\n console.log('');\n } catch (error) {\n s.stop('Failed to export project');\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');\n throw error;\n }\n}\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n const { port, host, build, outputDir, path, export: exportFlag, openBrowser } = options;\n\n if (path) {\n const rt = resolveWebRuntime(true);\n // THIS IS INTENTIONAL, WE NEED TO READ PATH FROM STDOUT\n console.log(rt);\n return;\n }\n\n if (exportFlag) {\n await exportNextApp({ outputDir });\n return;\n }\n\n if (build) {\n await buildNextApp({ outputDir });\n return;\n }\n\n await startWebApp({ port, host, openBrowser });\n}\n"],"mappings":"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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","names":[],"sources":["../../src/commands/init.ts"],"sourcesContent":["import { existsSync, mkdirSync, readdirSync, writeFileSync } from 'node:fs';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport { checkKeychainAvailability, loadCredentials } from '../utils/credentials';\nimport {\n DEFAULT_PROFILES_CONFIG,\n LOCAL_REMOTE,\n type Profile,\n ProfileManager,\n type ProfilesConfig,\n} from '../utils/profiles';\nimport { loginCommand } from './login';\n\nexport interface InitOptions {\n path?: string;\n config?: string;\n interactive?: boolean;\n local?: boolean;\n}\n\n/**\n * Find the most appropriate directory for the config file by looking for\n * common project root indicators\n */\nfunction findProjectRoot(startPath: string): string {\n let currentPath = resolve(startPath);\n const root = dirname(currentPath);\n\n const rootIndicators = [\n 'package.json',\n '.git',\n '.gitignore',\n 'tsconfig.json',\n 'package-lock.json',\n 'yarn.lock',\n 'pnpm-lock.yaml',\n ];\n\n while (currentPath !== root) {\n const files = readdirSync(currentPath);\n\n if (rootIndicators.some((indicator) => files.includes(indicator))) {\n return currentPath;\n }\n\n const parentPath = dirname(currentPath);\n if (parentPath === currentPath) {\n break;\n }\n currentPath = parentPath;\n }\n\n return startPath;\n}\n\nexport async function initCommand(options?: InitOptions): Promise<void> {\n // Check if user wants local init (self-hosted) or cloud init\n if (options?.local) {\n await localInitCommand(options);\n return;\n }\n\n // Run cloud init wizard\n await cloudInitCommand(options);\n}\n\n/**\n * Full onboarding wizard for Inkeep Cloud customers\n */\nasync function cloudInitCommand(options?: InitOptions): Promise<void> {\n console.log();\n console.log(chalk.bold('Welcome to Inkeep!'));\n console.log();\n\n const s = p.spinner();\n const profileManager = new ProfileManager();\n\n // Step 1: Check authentication\n s.start('Checking authentication...');\n\n let isAuthenticated = false;\n let credentials: { accessToken: string; organizationId: string; userEmail: string } | null = null;\n\n // Check if keychain is available\n const { available: keychainAvailable } = await checkKeychainAvailability();\n\n if (keychainAvailable) {\n // Try to load existing credentials from default cloud profile\n try {\n const existingCreds = await loadCredentials('inkeep-cloud');\n if (existingCreds?.accessToken && existingCreds.organizationId) {\n credentials = {\n accessToken: existingCreds.accessToken,\n organizationId: existingCreds.organizationId,\n userEmail: existingCreds.userEmail,\n };\n isAuthenticated = true;\n s.stop(`Logged in as ${chalk.cyan(existingCreds.userEmail)}`);\n }\n } catch {\n // Credentials not found or invalid\n }\n }\n\n if (!isAuthenticated) {\n s.stop('Not logged in');\n console.log(chalk.yellow('→ Opening browser for login...'));\n console.log();\n\n // Run login flow\n await loginCommand({});\n\n // Re-check credentials after login\n const newCreds = await loadCredentials('inkeep-cloud');\n if (newCreds?.accessToken && newCreds.organizationId) {\n credentials = {\n accessToken: newCreds.accessToken,\n organizationId: newCreds.organizationId,\n userEmail: newCreds.userEmail,\n };\n isAuthenticated = true;\n } else {\n console.error(chalk.red('Login failed. Please try again.'));\n process.exit(1);\n }\n }\n\n // Step 2: Fetch tenants/organizations the user has access to\n s.start('Fetching your organizations...');\n\n let selectedTenantId: string;\n let selectedTenantName: string;\n\n try {\n const response = await fetch('https://api.pilot.inkeep.com/manage/api/cli/me', {\n headers: {\n Authorization: `Bearer ${credentials?.accessToken}`,\n },\n });\n\n if (!response.ok) {\n s.stop('Failed to fetch organizations');\n console.error(chalk.red('Could not fetch your organizations. Please try logging in again.'));\n process.exit(1);\n }\n\n const data = await response.json();\n\n // For now, we get the primary organization from the /me endpoint\n // In the future, this could be expanded to support multiple organizations\n selectedTenantId = data.organization.id;\n selectedTenantName = data.organization.name;\n\n s.stop(`Organization: ${chalk.cyan(selectedTenantName)}`);\n } catch {\n s.stop('Failed to fetch organizations');\n console.error(chalk.red('Network error. Please check your connection.'));\n process.exit(1);\n }\n\n // Step 3: Fetch projects for the organization\n s.start(`Fetching projects for ${selectedTenantName}...`);\n\n let projects: Array<{ id: string; name: string }> = [];\n\n try {\n const response = await fetch(\n `https://agents-api.inkeep.com/manage/tenants/${selectedTenantId}/projects?limit=100`,\n {\n headers: {\n Authorization: `Bearer ${credentials?.accessToken}`,\n },\n }\n );\n\n if (!response.ok) {\n s.stop('Failed to fetch projects');\n console.error(chalk.red('Could not fetch projects.'));\n process.exit(1);\n }\n\n const data = await response.json();\n projects = data.data || [];\n\n s.stop(`Found ${projects.length} project(s)`);\n } catch {\n s.stop('Failed to fetch projects');\n console.error(chalk.red('Network error. Please check your connection.'));\n process.exit(1);\n }\n\n // Step 4: Ask where to create project files\n let targetDir: string;\n\n if (options?.path) {\n targetDir = resolve(process.cwd(), options.path);\n } else {\n const suggestedPath = './inkeep-agents';\n\n const confirmedPath = await p.text({\n message: 'Where should we create the project files?',\n placeholder: suggestedPath,\n initialValue: suggestedPath,\n validate: (input) => {\n if (!input || input.trim() === '') {\n return 'Path is required';\n }\n return undefined;\n },\n });\n\n if (p.isCancel(confirmedPath)) {\n p.cancel('Setup cancelled');\n process.exit(0);\n }\n\n targetDir = resolve(process.cwd(), confirmedPath);\n }\n\n // Create target directory if it doesn't exist\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n\n // Step 5: Create project structure\n console.log();\n console.log(chalk.bold('Creating directory structure...'));\n\n const createdProjects: string[] = [];\n\n if (projects.length === 0) {\n // No projects, create a template project\n const templateDir = join(targetDir, 'my-agent');\n mkdirSync(templateDir, { recursive: true });\n\n const configContent = generateConfigFile(selectedTenantId, 'my-agent');\n writeFileSync(join(templateDir, 'inkeep.config.ts'), configContent);\n\n const indexContent = generateIndexFile('my-agent');\n writeFileSync(join(templateDir, 'index.ts'), indexContent);\n\n console.log(chalk.gray(` ${targetDir}/`));\n console.log(chalk.gray(` └── my-agent/`));\n console.log(chalk.gray(` ├── inkeep.config.ts`));\n console.log(chalk.gray(` └── index.ts`));\n\n createdProjects.push('my-agent');\n } else {\n console.log(chalk.gray(` ${targetDir}/`));\n\n for (const project of projects) {\n const projectDir = join(targetDir, sanitizeProjectName(project.name || project.id));\n mkdirSync(projectDir, { recursive: true });\n\n const configContent = generateConfigFile(selectedTenantId, project.id);\n writeFileSync(join(projectDir, 'inkeep.config.ts'), configContent);\n\n // Create a placeholder index.ts (will be populated by pull)\n const indexContent = generateIndexFile(project.id);\n writeFileSync(join(projectDir, 'index.ts'), indexContent);\n\n const displayName = sanitizeProjectName(project.name || project.id);\n console.log(chalk.gray(` ├── ${displayName}/`));\n console.log(chalk.gray(` │ ├── inkeep.config.ts`));\n console.log(chalk.gray(` │ └── index.ts`));\n\n createdProjects.push(displayName);\n }\n }\n\n console.log();\n console.log(chalk.green(`✓ Created ${createdProjects.length} project(s)`));\n\n // Step 6: Create environment templates\n console.log();\n console.log(chalk.bold('Creating environment templates...'));\n\n const envDevContent = generateEnvTemplate('development');\n const envProdContent = generateEnvTemplate('production');\n\n writeFileSync(join(targetDir, '.env.development'), envDevContent);\n writeFileSync(join(targetDir, '.env.production'), envProdContent);\n\n console.log(chalk.green(' ✓ .env.development'));\n console.log(chalk.green(' ✓ .env.production'));\n\n // Step 7: Set up profile\n if (!profileManager.profilesFileExists()) {\n console.log();\n console.log(chalk.bold('Setting up profile...'));\n\n profileManager.saveProfiles(DEFAULT_PROFILES_CONFIG);\n console.log(chalk.green(' ✓ Created cloud profile'));\n }\n\n // Step 8: Success message and next steps\n console.log();\n console.log(chalk.green.bold('Setup complete!'));\n console.log();\n console.log(chalk.bold('Next steps:'));\n console.log(chalk.gray(` 1. cd ${targetDir}`));\n console.log(chalk.gray(' 2. Add your API keys to .env.development'));\n\n if (projects.length > 0) {\n console.log(chalk.gray(' 3. Run: inkeep pull --all'));\n } else {\n console.log(chalk.gray(' 3. Define your agent in index.ts'));\n console.log(chalk.gray(' 4. Run: inkeep push'));\n }\n\n console.log();\n}\n\n/**\n * Simple local init for self-hosted deployments\n */\nasync function localInitCommand(options?: InitOptions): Promise<void> {\n let configPath: string;\n\n if (options?.path) {\n const resolvedPath = resolve(process.cwd(), options.path);\n if (options.path.endsWith('.ts') || options.path.endsWith('.js')) {\n configPath = resolvedPath;\n } else {\n configPath = join(resolvedPath, 'inkeep.config.ts');\n }\n } else {\n const projectRoot = findProjectRoot(process.cwd());\n const suggestedPath = join(projectRoot, 'inkeep.config.ts');\n\n if (options?.interactive === false) {\n configPath = suggestedPath;\n } else {\n const confirmedPath = await p.text({\n message: 'Where should the config file be created?',\n initialValue: suggestedPath,\n validate: (input) => {\n if (!input || input.trim() === '') {\n return 'Path is required';\n }\n const dir = input.endsWith('.ts') || input.endsWith('.js') ? dirname(input) : input;\n const resolvedDir = resolve(process.cwd(), dir);\n if (!existsSync(resolvedDir)) {\n return `Directory does not exist: ${resolvedDir}`;\n }\n return undefined;\n },\n });\n\n if (p.isCancel(confirmedPath)) {\n p.cancel('Operation cancelled');\n process.exit(0);\n }\n\n const resolvedPath = resolve(process.cwd(), confirmedPath);\n configPath =\n confirmedPath.endsWith('.ts') || confirmedPath.endsWith('.js')\n ? resolvedPath\n : join(resolvedPath, 'inkeep.config.ts');\n }\n }\n\n if (existsSync(configPath)) {\n if (options?.interactive === false) {\n console.log(chalk.yellow(`Config file already exists at ${configPath}, skipping creation.`));\n return;\n }\n\n const overwrite = await p.confirm({\n message: `${basename(configPath)} already exists. Overwrite?`,\n initialValue: false,\n });\n\n if (p.isCancel(overwrite)) {\n p.cancel('Operation cancelled');\n process.exit(0);\n }\n\n if (!overwrite) {\n console.log(chalk.yellow('Init cancelled.'));\n return;\n }\n }\n\n let tenantId: string;\n let apiUrl: string;\n\n if (options?.interactive === false) {\n tenantId = 'default';\n apiUrl = LOCAL_REMOTE.api;\n } else {\n const tenantIdInput = await p.text({\n message: 'Enter your tenant ID:',\n validate: (input) => {\n if (!input || input.trim() === '') {\n return 'Tenant ID is required';\n }\n return undefined;\n },\n });\n\n if (p.isCancel(tenantIdInput)) {\n p.cancel('Operation cancelled');\n process.exit(0);\n }\n\n tenantId = tenantIdInput;\n\n const validateUrl = (input: string) => {\n try {\n if (input && input.trim() !== '') {\n new URL(input);\n return undefined;\n }\n return undefined;\n } catch {\n return 'Please enter a valid URL';\n }\n };\n\n const apiUrlInput = await p.text({\n message: 'Enter the Agents API URL:',\n placeholder: LOCAL_REMOTE.api,\n initialValue: LOCAL_REMOTE.api,\n validate: validateUrl,\n });\n\n if (p.isCancel(apiUrlInput)) {\n p.cancel('Operation cancelled');\n process.exit(0);\n }\n\n apiUrl = apiUrlInput;\n }\n\n const configContent = `import { defineConfig } from '@inkeep/agents-cli/config';\n\nexport default defineConfig({\n tenantId: '${tenantId}',\n agentsApi: {\n url: '${apiUrl}',\n }\n});\n`;\n\n try {\n writeFileSync(configPath, configContent);\n console.log(chalk.green('✓'), `Created ${chalk.cyan(configPath)}`);\n\n // Set up local profile\n try {\n const profileManager = new ProfileManager();\n const localProfile: Profile = {\n remote: {\n api: apiUrl,\n manageUi: LOCAL_REMOTE.manageUi,\n },\n credential: 'none',\n environment: 'development',\n };\n\n if (profileManager.profilesFileExists()) {\n const config = profileManager.loadProfiles();\n\n if (config.profiles.local) {\n profileManager.setActiveProfile('local');\n console.log(chalk.green('✓'), 'Set local profile as active');\n } else {\n profileManager.addProfile('local', localProfile);\n profileManager.setActiveProfile('local');\n console.log(chalk.green('✓'), 'Created and activated local profile');\n }\n } else {\n const profilesConfig: ProfilesConfig = {\n activeProfile: 'local',\n profiles: {\n local: localProfile,\n },\n };\n\n profileManager.saveProfiles(profilesConfig);\n console.log(chalk.green('✓'), 'Created local profile');\n }\n } catch (profileError) {\n console.log(\n chalk.yellow('⚠'),\n 'Could not set up local profile:',\n profileError instanceof Error ? profileError.message : String(profileError)\n );\n }\n\n console.log(chalk.gray('\\nYou can now use the Inkeep CLI commands.'));\n\n const configDir = dirname(configPath);\n if (configDir !== process.cwd()) {\n console.log(chalk.gray(`\\nNote: Config file created in ${configDir}`));\n console.log(\n chalk.gray(`Use --config ${configPath} with commands, or run commands from that directory.`)\n );\n }\n } catch (error) {\n console.error(chalk.red('Failed to create config file:'), error);\n process.exit(1);\n }\n}\n\nfunction sanitizeProjectName(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9-_]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\nfunction generateConfigFile(tenantId: string, projectId: string): string {\n return `import { defineConfig } from '@inkeep/agents-cli/config';\n\nexport default defineConfig({\n tenantId: '${tenantId}',\n projectId: '${projectId}',\n agentsApi: {\n url: 'https://agents-api.inkeep.com',\n },\n});\n`;\n}\n\nfunction generateIndexFile(projectId: string): string {\n return `import { project } from '@inkeep/agents-sdk';\n\n// This file was auto-generated by 'inkeep init'\n// Run 'inkeep pull' to sync with your remote project\n\nexport default project({\n id: '${projectId}',\n name: '${projectId}',\n agents: {},\n tools: {},\n});\n`;\n}\n\nfunction generateEnvTemplate(environment: string): string {\n return `# ${environment.charAt(0).toUpperCase() + environment.slice(1)} Environment\n# Add your API keys and secrets here\n\n# OpenAI API Key\nOPENAI_API_KEY=sk-your-key-here\n\n# Anthropic API Key\nANTHROPIC_API_KEY=sk-ant-your-key-here\n\n# Add other provider keys as needed\n`;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-agents.js","names":[],"sources":["../../src/commands/list-agents.ts"],"sourcesContent":["import * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\nimport { ManagementApiClient } from '../api';\nimport { initializeCommand } from '../utils/cli-pipeline';\n\nexport interface ListAgentsOptions {\n project: string; // required project ID\n config?: string;\n configFilePath?: string; // deprecated, kept for backward compatibility\n}\n\nexport async function listAgentsCommand(options: ListAgentsOptions): Promise<void> {\n // Use standardized CLI pipeline for initialization\n const configPath = options.config || options.configFilePath;\n const { config } = await initializeCommand({\n configPath,\n showSpinner: false,\n logConfig: true,\n });\n\n console.log();\n\n const api = await ManagementApiClient.create(\n config.agentsApiUrl,\n configPath,\n config.tenantId,\n options.project, // pass project ID as projectIdOverride\n undefined,\n config.agentsApiKey\n );\n const s = p.spinner();\n s.start('Fetching agent...');\n\n try {\n const agents = await api.listAgents();\n s.stop(`Found ${agents.length} agent(s) in project \"${options.project}\"`);\n\n if (agents.length === 0) {\n console.log(\n chalk.gray(\n `No agent found in project \"${options.project}\". Define agent in your project and run: inkeep push`\n )\n );\n return;\n }\n\n // Create a table to display agent\n const table = new Table({\n head: [\n chalk.cyan('Agent ID'),\n chalk.cyan('Name'),\n chalk.cyan('Default Agent'),\n chalk.cyan('Created'),\n ],\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const agent of agents) {\n const createdDate = agent.createdAt\n ? new Date(agent.createdAt).toLocaleDateString()\n : 'Unknown';\n\n table.push([\n agent.id,\n agent.name,\n agent.defaultSubAgentId || chalk.gray('None'),\n createdDate,\n ]);\n }\n\n console.log(`\\n${table.toString()}`);\n } catch (error) {\n s.stop('Failed to fetch agent');\n console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,kBAAkB,SAA2C;CAEjF,MAAM,aAAa,QAAQ,UAAU,QAAQ;CAC7C,MAAM,EAAE,WAAW,MAAM,kBAAkB;EACzC;EACA,aAAa;EACb,WAAW;EACZ,CAAC;AAEF,SAAQ,KAAK;CAEb,MAAM,MAAM,MAAM,oBAAoB,OACpC,OAAO,cACP,YACA,OAAO,UACP,QAAQ,SACR,QACA,OAAO,aACR;CACD,MAAM,IAAI,EAAE,SAAS;AACrB,GAAE,MAAM,oBAAoB;AAE5B,KAAI;EACF,MAAM,SAAS,MAAM,IAAI,YAAY;AACrC,IAAE,KAAK,SAAS,OAAO,OAAO,wBAAwB,QAAQ,QAAQ,GAAG;AAEzE,MAAI,OAAO,WAAW,GAAG;AACvB,WAAQ,IACN,MAAM,KACJ,8BAA8B,QAAQ,QAAQ,sDAC/C,CACF;AACD;;EAIF,MAAM,QAAQ,IAAI,MAAM;GACtB,MAAM;IACJ,MAAM,KAAK,WAAW;IACtB,MAAM,KAAK,OAAO;IAClB,MAAM,KAAK,gBAAgB;IAC3B,MAAM,KAAK,UAAU;IACtB;GACD,OAAO;IACL,MAAM,EAAE;IACR,QAAQ,EAAE;IACX;GACF,CAAC;AAEF,OAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,cAAc,MAAM,YACtB,IAAI,KAAK,MAAM,UAAU,CAAC,oBAAoB,GAC9C;AAEJ,SAAM,KAAK;IACT,MAAM;IACN,MAAM;IACN,MAAM,qBAAqB,MAAM,KAAK,OAAO;IAC7C;IACD,CAAC;;AAGJ,UAAQ,IAAI,KAAK,MAAM,UAAU,GAAG;UAC7B,OAAO;AACd,IAAE,KAAK,wBAAwB;AAC/B,UAAQ,MAAM,MAAM,IAAI,SAAS,EAAE,iBAAiB,QAAQ,MAAM,UAAU,MAAM;AAClF,UAAQ,KAAK,EAAE"}
|
package/dist/commands/login.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","names":[],"sources":["../../src/commands/login.ts"],"sourcesContent":["import * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport open from 'open';\nimport {\n checkKeychainAvailability,\n getKeychainUnavailableMessage,\n loadCredentials,\n saveCredentials,\n} from '../utils/credentials';\nimport { ProfileManager } from '../utils/profiles';\n\nexport interface LoginOptions {\n profile?: string;\n}\n\n/**\n * Format user code as XXXX-XXXX for display\n */\nfunction formatUserCode(code: string): string {\n const cleaned = code.replace(/[^A-Z0-9]/gi, '').toUpperCase();\n if (cleaned.length === 8) {\n return `${cleaned.slice(0, 4)}-${cleaned.slice(4)}`;\n }\n return cleaned;\n}\n\n/**\n * Sleep for a specified number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Poll the device token endpoint until authorization is complete\n */\nasync function pollForToken(\n cloudUrl: string,\n deviceCode: string,\n clientId: string,\n initialInterval: number\n): Promise<string> {\n let interval = initialInterval;\n\n while (true) {\n await sleep(interval * 1000);\n\n const response = await fetch(`${cloudUrl}/api/auth/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: clientId,\n }),\n });\n\n const data = await response.json();\n\n if (data.access_token) {\n return data.access_token;\n }\n\n if (data.error === 'authorization_pending') {\n // User hasn't approved yet, keep polling\n continue;\n }\n\n if (data.error === 'slow_down') {\n // Back off polling interval\n interval += 5;\n continue;\n }\n\n if (data.error === 'expired_token') {\n throw new Error('Device code expired. Please try again.');\n }\n\n if (data.error === 'access_denied') {\n throw new Error('Authorization denied.');\n }\n\n throw new Error(data.error || data.message || 'Unknown error during authorization');\n }\n}\n\n/**\n * Fetch user info and organization after authentication\n */\nasync function fetchUserInfo(\n cloudUrl: string,\n accessToken: string\n): Promise<{\n user: { id: string; email: string; name?: string };\n organization: { id: string; name: string; slug: string };\n}> {\n // First, get the session to get user info\n const sessionResponse = await fetch(`${cloudUrl}/api/auth/get-session`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!sessionResponse.ok) {\n throw new Error('Failed to fetch user session');\n }\n\n const sessionData = await sessionResponse.json();\n const user = sessionData.user;\n\n if (!user) {\n throw new Error('No user found in session');\n }\n\n // Get user's organization\n const orgResponse = await fetch(`${cloudUrl}/manage/api/cli/me`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!orgResponse.ok) {\n throw new Error(\n 'Failed to fetch organization info. Please ensure that you are a member of an organization.'\n );\n }\n\n const orgData = await orgResponse.json();\n\n return {\n user: {\n id: user.id,\n email: user.email,\n name: user.name,\n },\n organization: orgData.organization,\n };\n}\n\nexport async function loginCommand(options: LoginOptions = {}): Promise<void> {\n const profileManager = new ProfileManager();\n\n // Resolve profile to use\n let profileName: string;\n let credentialKey: string;\n let manageApiUrl: string;\n let manageUiUrl: string;\n\n try {\n if (options.profile) {\n const profile = profileManager.getProfile(options.profile);\n if (!profile) {\n console.error(chalk.red(`Profile '${options.profile}' not found.`));\n console.log(chalk.gray('Run \"inkeep profile list\" to see available profiles.'));\n process.exit(1);\n }\n profileName = options.profile;\n credentialKey = profile.credential;\n manageApiUrl = profile.remote.api;\n manageUiUrl = profile.remote.manageUi;\n } else {\n const activeProfile = profileManager.getActiveProfile();\n profileName = activeProfile.name;\n credentialKey = activeProfile.credential;\n manageApiUrl = activeProfile.remote.api;\n manageUiUrl = activeProfile.remote.manageUi;\n }\n } catch {\n // No profile configured, use defaults\n profileName = 'default';\n credentialKey = 'inkeep-cloud';\n manageApiUrl = 'https://agents-api.inkeep.com';\n manageUiUrl = 'https://manage.inkeep.com';\n }\n\n console.log(chalk.gray(`Using profile: ${profileName}`));\n\n // Check if keychain is available\n const { available, reason } = await checkKeychainAvailability();\n if (!available) {\n console.error(chalk.red('Error:'), getKeychainUnavailableMessage(reason));\n console.log();\n console.log(chalk.yellow('For CI/CD environments without keychain access:'));\n console.log(chalk.gray(' Set INKEEP_API_KEY environment variable instead of using login.'));\n console.log(chalk.gray(' See: https://docs.inkeep.com/cli/cicd'));\n process.exit(1);\n }\n\n // Check if already logged in for this profile\n const existingCredentials = await loadCredentials(credentialKey);\n if (existingCredentials) {\n const continueLogin = await p.confirm({\n message: `Already logged in as ${chalk.cyan(existingCredentials.userEmail)} for profile '${profileName}'. Continue with new login?`,\n initialValue: false,\n });\n\n if (p.isCancel(continueLogin)) {\n p.cancel('Login cancelled');\n process.exit(0);\n }\n\n if (!continueLogin) {\n console.log(chalk.gray('Login cancelled. You are still logged in.'));\n return;\n }\n }\n\n const s = p.spinner();\n\n try {\n // Request device code\n s.start('Requesting device code...');\n\n const deviceCodeResponse = await fetch(`${manageApiUrl}/api/auth/device/code`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ client_id: 'inkeep-cli' }),\n });\n\n if (!deviceCodeResponse.ok) {\n const errorData = await deviceCodeResponse.json().catch(() => ({}));\n throw new Error(\n errorData.message || `Failed to get device code: ${deviceCodeResponse.statusText}`\n );\n }\n\n const { device_code, user_code, interval } = await deviceCodeResponse.json();\n\n s.stop('Device code received');\n\n // Display instructions\n console.log();\n console.log(chalk.bold('To authenticate, visit:'));\n console.log(chalk.cyan(` ${manageUiUrl}/device?user_code=${user_code}`));\n console.log();\n console.log(chalk.bold('And enter code:'));\n console.log(chalk.yellow.bold(` ${formatUserCode(user_code)}`));\n console.log();\n\n // Try to open browser automatically\n try {\n await open(`${manageUiUrl}/device?user_code=${user_code}`);\n console.log(chalk.gray(' (Browser opened automatically)'));\n console.log();\n } catch {\n // Browser opening failed, user can copy the URL manually\n }\n\n // Poll for token\n s.start('Waiting for authorization...');\n const accessToken = await pollForToken(manageApiUrl, device_code, 'inkeep-cli', interval || 5);\n s.stop('Authorized!');\n\n // Fetch user info and organization\n s.start('Fetching account info...');\n const userInfo = await fetchUserInfo(manageApiUrl, accessToken);\n s.stop('Account info retrieved');\n\n // Store credentials under the profile's credential key\n await saveCredentials(\n {\n accessToken,\n userId: userInfo.user.id,\n userEmail: userInfo.user.email,\n organizationId: userInfo.organization.id,\n organizationName: userInfo.organization.name,\n createdAt: new Date().toISOString(),\n },\n credentialKey\n );\n\n // Success message\n console.log();\n console.log(chalk.green('✓'), `Logged in as ${chalk.cyan(userInfo.user.email)}`);\n console.log(chalk.green('✓'), `Organization: ${chalk.cyan(userInfo.organization.name)}`);\n console.log(chalk.green('✓'), `Profile: ${chalk.cyan(profileName)}`);\n } catch (error) {\n s.stop('Login failed');\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n console.error(chalk.red('Error:'), errorMessage);\n process.exit(1);\n }\n}\n"],"mappings":"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"}
|
package/dist/commands/logout.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","names":[],"sources":["../../src/commands/logout.ts"],"sourcesContent":["import * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport { clearCredentials, loadCredentials } from '../utils/credentials';\nimport { ProfileManager } from '../utils/profiles';\n\nexport interface LogoutOptions {\n profile?: string;\n}\n\nexport async function logoutCommand(options: LogoutOptions = {}): Promise<void> {\n const profileManager = new ProfileManager();\n const s = p.spinner();\n\n // Resolve profile to use\n let profileName: string;\n let credentialKey: string;\n\n try {\n if (options.profile) {\n const profile = profileManager.getProfile(options.profile);\n if (!profile) {\n console.error(chalk.red(`Profile '${options.profile}' not found.`));\n console.log(chalk.gray('Run \"inkeep profile list\" to see available profiles.'));\n process.exit(1);\n }\n profileName = options.profile;\n credentialKey = profile.credential;\n } else {\n const activeProfile = profileManager.getActiveProfile();\n profileName = activeProfile.name;\n credentialKey = activeProfile.credential;\n }\n } catch {\n // No profile configured, use default\n profileName = 'default';\n credentialKey = 'inkeep-cloud';\n }\n\n console.log(chalk.gray(`Using profile: ${profileName}`));\n\n // Check if logged in for this profile\n const credentials = await loadCredentials(credentialKey);\n if (!credentials) {\n console.log(chalk.yellow(`Not logged in for profile '${profileName}'.`));\n return;\n }\n\n s.start('Logging out...');\n\n try {\n const cleared = await clearCredentials(credentialKey);\n\n if (cleared) {\n s.stop('Logged out successfully');\n console.log(chalk.green('✓'), `Logged out from profile '${chalk.cyan(profileName)}'.`);\n console.log(chalk.gray(` • Credential '${credentialKey}' removed from keychain.`));\n } else {\n s.stop('Logout completed');\n console.log(chalk.gray('No credentials were stored.'));\n }\n } catch (error) {\n s.stop('Logout failed');\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n console.error(chalk.red('Error:'), errorMessage);\n process.exit(1);\n }\n}\n"],"mappings":";;;;;;;AASA,eAAsB,cAAc,UAAyB,EAAE,EAAiB;CAC9E,MAAM,iBAAiB,IAAI,gBAAgB;CAC3C,MAAM,IAAI,EAAE,SAAS;CAGrB,IAAI;CACJ,IAAI;AAEJ,KAAI;AACF,MAAI,QAAQ,SAAS;GACnB,MAAM,UAAU,eAAe,WAAW,QAAQ,QAAQ;AAC1D,OAAI,CAAC,SAAS;AACZ,YAAQ,MAAM,MAAM,IAAI,YAAY,QAAQ,QAAQ,cAAc,CAAC;AACnE,YAAQ,IAAI,MAAM,KAAK,yDAAuD,CAAC;AAC/E,YAAQ,KAAK,EAAE;;AAEjB,iBAAc,QAAQ;AACtB,mBAAgB,QAAQ;SACnB;GACL,MAAM,gBAAgB,eAAe,kBAAkB;AACvD,iBAAc,cAAc;AAC5B,mBAAgB,cAAc;;SAE1B;AAEN,gBAAc;AACd,kBAAgB;;AAGlB,SAAQ,IAAI,MAAM,KAAK,kBAAkB,cAAc,CAAC;AAIxD,KAAI,CADgB,MAAM,gBAAgB,cAAc,EACtC;AAChB,UAAQ,IAAI,MAAM,OAAO,8BAA8B,YAAY,IAAI,CAAC;AACxE;;AAGF,GAAE,MAAM,iBAAiB;AAEzB,KAAI;AAGF,MAFgB,MAAM,iBAAiB,cAAc,EAExC;AACX,KAAE,KAAK,0BAA0B;AACjC,WAAQ,IAAI,MAAM,MAAM,IAAI,EAAE,4BAA4B,MAAM,KAAK,YAAY,CAAC,IAAI;AACtF,WAAQ,IAAI,MAAM,KAAK,mBAAmB,cAAc,0BAA0B,CAAC;SAC9E;AACL,KAAE,KAAK,mBAAmB;AAC1B,WAAQ,IAAI,MAAM,KAAK,8BAA8B,CAAC;;UAEjD,OAAO;AACd,IAAE,KAAK,gBAAgB;EACvB,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU;AAC9D,UAAQ,MAAM,MAAM,IAAI,SAAS,EAAE,aAAa;AAChD,UAAQ,KAAK,EAAE"}
|
package/dist/commands/profile.js
CHANGED
|
@@ -274,4 +274,5 @@ function handleProfileError(error) {
|
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
//#endregion
|
|
277
|
-
export { profileAddCommand, profileCurrentCommand, profileListCommand, profileRemoveCommand, profileUseCommand };
|
|
277
|
+
export { profileAddCommand, profileCurrentCommand, profileListCommand, profileRemoveCommand, profileUseCommand };
|
|
278
|
+
//# sourceMappingURL=profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.js","names":[],"sources":["../../src/commands/profile.ts"],"sourcesContent":["import * as p from '@clack/prompts';\nimport chalk from 'chalk';\nimport { LOCAL_REMOTE, type Profile, ProfileError, ProfileManager } from '../utils/profiles';\n\nconst profileManager = new ProfileManager();\n\n/**\n * List all profiles and show which one is active\n */\nexport async function profileListCommand(): Promise<void> {\n try {\n const { profiles, activeProfile } = profileManager.listProfiles();\n\n if (profiles.length === 0) {\n console.log(chalk.yellow('No profiles configured.'));\n console.log(chalk.gray('Run \"inkeep profile add <name>\" to create one.'));\n return;\n }\n\n console.log(chalk.bold('Profiles:\\n'));\n\n for (const profile of profiles) {\n const isActive = profile.name === activeProfile;\n const marker = isActive ? chalk.green('* ') : ' ';\n const name = isActive ? chalk.green.bold(profile.name) : profile.name;\n\n console.log(`${marker}${name}`);\n console.log(chalk.gray(` Remote: ${profile.remote.api}`));\n console.log(chalk.gray(` Environment: ${profile.environment}`));\n console.log(chalk.gray(` Credential: ${profile.credential}`));\n console.log();\n }\n } catch (error) {\n handleProfileError(error);\n }\n}\n\n/**\n * Add a new profile interactively\n */\nexport async function profileAddCommand(name?: string): Promise<void> {\n try {\n // Get profile name if not provided\n let profileName = name;\n if (!profileName) {\n const result = await p.text({\n message: 'Profile name:',\n placeholder: 'my-profile',\n validate: (value) => {\n if (!value) return 'Profile name is required';\n if (!/^[a-z0-9-]+$/.test(value)) {\n return 'Profile name must be lowercase alphanumeric with hyphens only';\n }\n return undefined;\n },\n });\n\n if (p.isCancel(result)) {\n p.cancel('Profile creation cancelled');\n process.exit(0);\n }\n\n profileName = result;\n }\n\n // Check if profile already exists\n const existing = profileManager.getProfile(profileName);\n if (existing) {\n console.error(chalk.red(`Profile '${profileName}' already exists.`));\n process.exit(1);\n }\n\n // Select remote type\n const remoteType = await p.select({\n message: 'Remote type:',\n options: [\n { value: 'cloud', label: 'Inkeep Cloud', hint: 'Default cloud deployment' },\n { value: 'local', label: 'Local', hint: 'Local development (localhost, no auth)' },\n { value: 'custom', label: 'Custom', hint: 'Self-hosted or staging deployment' },\n ],\n });\n\n if (p.isCancel(remoteType)) {\n p.cancel('Profile creation cancelled');\n process.exit(0);\n }\n\n let remote: Profile['remote'];\n\n if (remoteType === 'cloud') {\n remote = 'cloud';\n } else if (remoteType === 'local') {\n remote = { ...LOCAL_REMOTE };\n } else {\n const api = await p.text({\n message: 'Agents API URL:',\n placeholder: 'https://your-agents-api.example.com',\n validate: (value) => {\n if (!value?.trim()) return 'URL is required';\n try {\n new URL(value);\n return undefined;\n } catch {\n return 'Invalid URL format';\n }\n },\n });\n\n if (p.isCancel(api)) {\n p.cancel('Profile creation cancelled');\n process.exit(0);\n }\n\n const manageUi = await p.text({\n message: 'Manage UI URL:',\n placeholder: 'https://your-manage-ui.example.com',\n validate: (value) => {\n if (!value?.trim()) return 'URL is required';\n try {\n new URL(value);\n return undefined;\n } catch {\n return 'Invalid URL format';\n }\n },\n });\n\n if (p.isCancel(manageUi)) {\n p.cancel('Profile creation cancelled');\n process.exit(0);\n }\n\n remote = {\n api,\n manageUi,\n };\n }\n\n // Cloud and custom (self-hosted/staging) default to 'production'; only local dev defaults to 'development'\n const envDefault = remoteType === 'local' ? 'development' : 'production';\n const environment = await p.text({\n message: 'Environment name:',\n placeholder: envDefault,\n initialValue: envDefault,\n validate: (value) => {\n if (!value) return 'Environment is required';\n return undefined;\n },\n });\n\n if (p.isCancel(environment)) {\n p.cancel('Profile creation cancelled');\n process.exit(0);\n }\n\n // Generate credential reference name\n let credential: string;\n\n if (remoteType === 'local') {\n credential = 'none';\n } else {\n const credentialDefault = `inkeep-${profileName}`;\n const credentialInput = await p.text({\n message: 'Credential reference:',\n placeholder: credentialDefault,\n initialValue: credentialDefault,\n validate: (value) => {\n if (!value) return 'Credential reference is required';\n return undefined;\n },\n });\n\n if (p.isCancel(credentialInput)) {\n p.cancel('Profile creation cancelled');\n process.exit(0);\n }\n\n credential = credentialInput;\n }\n\n // Create the profile\n const profile: Profile = {\n remote,\n credential,\n environment,\n };\n\n profileManager.addProfile(profileName, profile);\n\n console.log();\n console.log(chalk.green('✓'), `Profile '${chalk.cyan(profileName)}' created successfully.`);\n\n // Check if credential exists and warn if not (skip for 'none')\n if (credential !== 'none') {\n const credentialExists = await profileManager.checkCredentialExists(credential);\n if (!credentialExists) {\n console.log();\n console.log(chalk.yellow('⚠'), `Credential '${credential}' not found in keychain.`);\n console.log(chalk.gray(' Run \"inkeep login\" to authenticate and store credentials.'));\n }\n }\n\n // Ask if user wants to switch to this profile\n const switchProfile = await p.confirm({\n message: `Switch to profile '${profileName}'?`,\n initialValue: false,\n });\n\n if (!p.isCancel(switchProfile) && switchProfile) {\n profileManager.setActiveProfile(profileName);\n console.log(chalk.green('✓'), `Switched to profile '${chalk.cyan(profileName)}'.`);\n }\n } catch (error) {\n handleProfileError(error);\n }\n}\n\n/**\n * Set the active profile\n */\nexport async function profileUseCommand(name: string): Promise<void> {\n try {\n if (!name) {\n console.error(chalk.red('Profile name is required.'));\n console.log(chalk.gray('Usage: inkeep profile use <name>'));\n process.exit(1);\n }\n\n profileManager.setActiveProfile(name);\n console.log(chalk.green('✓'), `Switched to profile '${chalk.cyan(name)}'.`);\n } catch (error) {\n handleProfileError(error);\n }\n}\n\n/**\n * Display the current active profile details\n */\nexport async function profileCurrentCommand(): Promise<void> {\n try {\n const profile = profileManager.getActiveProfile();\n\n console.log(chalk.bold('Active Profile:\\n'));\n console.log(chalk.cyan(` Name: ${profile.name}`));\n console.log();\n console.log(chalk.gray(' Remote URLs:'));\n console.log(` Agents API: ${profile.remote.api}`);\n console.log(` Manage UI: ${profile.remote.manageUi}`);\n console.log();\n console.log(` Environment: ${profile.environment}`);\n console.log(` Credential: ${profile.credential}`);\n\n // Check if credential exists and warn if not (skip for 'none')\n if (profile.credential !== 'none') {\n const credentialExists = await profileManager.checkCredentialExists(profile.credential);\n if (!credentialExists) {\n console.log();\n console.log(chalk.yellow('⚠'), `Credential '${profile.credential}' not found in keychain.`);\n console.log(chalk.gray(' Run \"inkeep login\" to authenticate.'));\n }\n }\n } catch (error) {\n handleProfileError(error);\n }\n}\n\n/**\n * Remove a profile\n */\nexport async function profileRemoveCommand(name: string): Promise<void> {\n try {\n if (!name) {\n console.error(chalk.red('Profile name is required.'));\n console.log(chalk.gray('Usage: inkeep profile remove <name>'));\n process.exit(1);\n }\n\n // Confirm deletion\n const confirm = await p.confirm({\n message: `Remove profile '${name}'?`,\n initialValue: false,\n });\n\n if (p.isCancel(confirm) || !confirm) {\n console.log(chalk.gray('Profile removal cancelled.'));\n return;\n }\n\n profileManager.removeProfile(name);\n console.log(chalk.green('✓'), `Profile '${chalk.cyan(name)}' removed.`);\n } catch (error) {\n handleProfileError(error);\n }\n}\n\n/**\n * Handle profile errors with user-friendly messages\n */\nfunction handleProfileError(error: unknown): never {\n if (error instanceof ProfileError) {\n console.error(chalk.red('Error:'), error.message);\n\n // Provide helpful hints based on error code\n switch (error.code) {\n case 'PROFILE_NOT_FOUND':\n console.log(chalk.gray('\\nRun \"inkeep profile list\" to see available profiles.'));\n break;\n case 'PROFILE_EXISTS':\n console.log(chalk.gray('\\nUse a different name or remove the existing profile first.'));\n break;\n case 'ACTIVE_PROFILE_DELETE':\n console.log(chalk.gray('\\nRun \"inkeep profile use <other-profile>\" first.'));\n break;\n case 'VALIDATION_ERROR':\n console.log(chalk.gray('\\nCheck your profiles.yaml file for syntax errors.'));\n break;\n }\n\n process.exit(1);\n }\n\n // Re-throw unknown errors\n throw error;\n}\n"],"mappings":"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"}
|
|
@@ -295,4 +295,5 @@ function getAllLocalComponentIds(projectRoot) {
|
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
//#endregion
|
|
298
|
-
export { buildComponentRegistryFromParsing, findComponentById, getAllLocalComponentIds };
|
|
298
|
+
export { buildComponentRegistryFromParsing, findComponentById, getAllLocalComponentIds };
|
|
299
|
+
//# sourceMappingURL=component-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-parser.js","names":["args"],"sources":["../../../src/commands/pull-v4/component-parser.ts"],"sourcesContent":["/**\n * Component Parser - Find all component definitions (exported and inline)\n * Uses AST parsing to handle complex components including those with render attributes\n * Maps components by looking for patterns like:\n * - export const myTool = tool({id: 'tool-id', ...})\n * - dataComponent({id: 'data-id', ...}) (inline)\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { extname, join, relative } from 'node:path';\nimport { type CallExpression, Node, type ObjectLiteralExpression } from 'ts-morph';\nimport { ComponentRegistry, type ComponentType } from './component-registry';\nimport { createInMemoryProject } from './utils';\n\ninterface ComponentMatch {\n id: string;\n type: ComponentType;\n filePath: string;\n variableName?: string; // If exported\n startLine: number;\n isInline: boolean; // true if not exported, false if exported\n overrideExisting?: boolean; // true if this should override an existing component\n}\n\n/**\n * Valid plural component types for parsing\n */\nconst VALID_COMPONENT_TYPES = new Set<ComponentType>([\n 'project',\n 'agents',\n 'subAgents',\n 'tools',\n 'functionTools',\n 'dataComponents',\n 'artifactComponents',\n 'statusComponents',\n 'externalAgents',\n 'credentials',\n 'contextConfigs',\n 'fetchDefinitions',\n 'headers',\n]);\n\n/**\n * Mapping from SDK function names to ComponentTypes\n */\nconst FUNCTION_NAME_TO_TYPE: Record<string, ComponentType> = {\n project: 'project',\n agent: 'agents',\n subAgent: 'subAgents',\n tool: 'tools',\n functionTool: 'functionTools',\n dataComponent: 'dataComponents',\n artifactComponent: 'artifactComponents',\n statusComponent: 'statusComponents',\n externalAgent: 'externalAgents',\n credential: 'credentials',\n contextConfig: 'contextConfigs',\n fetchDefinition: 'fetchDefinitions',\n header: 'headers',\n mcpTool: 'tools',\n};\n\n/**\n * Parse a single file for all component definitions using AST parsing\n * Handles all patterns: exported, declared+exported, declared-only, and inline\n */\nfunction parseFileForComponents(\n filePath: string,\n projectRoot: string,\n debug = false\n): ComponentMatch[] {\n if (!existsSync(filePath)) {\n return [];\n }\n\n const components: ComponentMatch[] = [];\n const relativePath = relative(projectRoot, filePath);\n\n try {\n const content = readFileSync(filePath, 'utf8');\n\n // Create a temporary ts-morph project for parsing\n const project = createInMemoryProject();\n\n // Add the file to the project\n const sourceFile = project.createSourceFile('temp.ts', content);\n\n // Pattern 1: Direct exports (export const name = func({...}))\n const exportedVariableDeclarations = sourceFile\n .getVariableStatements()\n .filter((statement) => statement.hasExportKeyword())\n .flatMap((statement) => statement.getDeclarationList().getDeclarations());\n\n for (const declaration of exportedVariableDeclarations) {\n const variableName = declaration.getName();\n const initializer = declaration.getInitializer();\n\n if (Node.isCallExpression(initializer)) {\n const componentMatch = parseCallExpression(initializer, variableName, false, relativePath);\n if (componentMatch) {\n components.push(componentMatch);\n }\n }\n }\n\n // Pattern 2: Separate declaration + export (const name = func({...}) + export { name })\n // First, collect all exported names from export declarations\n const exportedNames = new Set<string>();\n sourceFile.getExportDeclarations().forEach((exportDecl) => {\n const namedExports = exportDecl.getNamedExports();\n namedExports.forEach((namedExport) => {\n exportedNames.add(namedExport.getName());\n });\n });\n\n // Find variable declarations that are exported via separate export statements\n const allVariableDeclarations = sourceFile\n .getVariableStatements()\n .filter((statement) => !statement.hasExportKeyword()) // Not direct exports\n .flatMap((statement) => statement.getDeclarationList().getDeclarations());\n\n for (const declaration of allVariableDeclarations) {\n const variableName = declaration.getName();\n const initializer = declaration.getInitializer();\n\n if (Node.isCallExpression(initializer)) {\n const isExported = exportedNames.has(variableName);\n const isInline = !isExported;\n\n const componentMatch = parseCallExpression(\n initializer,\n variableName,\n isInline,\n relativePath\n );\n if (componentMatch) {\n components.push(componentMatch);\n }\n }\n }\n\n // Pattern 3: Truly inline components (function calls without variable assignment)\n // Walk the AST to find all call expressions that aren't part of variable declarations\n sourceFile.forEachDescendant((node) => {\n if (Node.isCallExpression(node)) {\n // Check if this call expression is NOT the initializer of a variable declaration\n const parent = node.getParent();\n const isVariableInitializer =\n Node.isVariableDeclaration(parent) && parent.getInitializer() === node;\n\n if (!isVariableInitializer) {\n const componentMatch = parseCallExpression(node, undefined, true, relativePath);\n if (componentMatch) {\n components.push(componentMatch);\n }\n }\n }\n });\n\n // Pattern 4: Environment-based credentials within registerEnvironmentSettings\n // export const development = registerEnvironmentSettings({\n // credentials: {\n // stripe_api_key: {\n // id: 'stripe-api-key',\n // name: 'Stripe API Key',\n // ...\n // }\n // }\n // });\n sourceFile.forEachDescendant((node) => {\n if (Node.isCallExpression(node)) {\n const expression = node.getExpression();\n\n // Check if this is a registerEnvironmentSettings call\n if (\n Node.isIdentifier(expression) &&\n expression.getText() === 'registerEnvironmentSettings'\n ) {\n const args = node.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {\n const configObject = args[0];\n\n // Look for credentials property\n const credentialsProperty = configObject.getProperty('credentials');\n if (credentialsProperty && Node.isPropertyAssignment(credentialsProperty)) {\n const credentialsValue = credentialsProperty.getInitializer();\n\n if (Node.isObjectLiteralExpression(credentialsValue)) {\n // Parse each credential in the credentials object\n credentialsValue.getProperties().forEach((property) => {\n if (Node.isPropertyAssignment(property)) {\n const credentialKey = property.getName(); // e.g., \"stripe_api_key\"\n const credentialConfig = property.getInitializer();\n\n if (Node.isObjectLiteralExpression(credentialConfig)) {\n // Inline credential definition - Look for the 'id' property in the credential config\n const idProperty = credentialConfig.getProperty('id');\n if (idProperty && Node.isPropertyAssignment(idProperty)) {\n const idValue = idProperty.getInitializer();\n if (Node.isStringLiteral(idValue)) {\n const credentialId = idValue.getLiteralValue(); // e.g., \"stripe-api-key\"\n const startLine = node.getStartLineNumber();\n\n components.push({\n id: credentialId,\n type: 'credentials',\n filePath: relativePath,\n variableName: credentialKey, // Use the key name as variable name\n startLine,\n isInline: true, // It's nested within environment settings\n });\n }\n }\n } else if (Node.isIdentifier(credentialConfig)) {\n // Variable reference - need to find the credential ID from the variable\n // This handles cases like: stripe_api_key: stripeApiKey\n const variableName = credentialConfig.getText();\n\n // Look for the credential variable definition in this file\n sourceFile.forEachDescendant((varNode) => {\n if (\n Node.isVariableDeclaration(varNode) &&\n varNode.getName() === variableName\n ) {\n const initializer = varNode.getInitializer();\n if (Node.isCallExpression(initializer)) {\n const callExpression = initializer.getExpression();\n if (\n Node.isIdentifier(callExpression) &&\n callExpression.getText() === 'credential'\n ) {\n const args = initializer.getArguments();\n if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {\n const configObject = args[0];\n const idProperty = configObject.getProperty('id');\n if (idProperty && Node.isPropertyAssignment(idProperty)) {\n const idValue = idProperty.getInitializer();\n if (Node.isStringLiteral(idValue)) {\n const credentialId = idValue.getLiteralValue();\n const startLine = node.getStartLineNumber();\n\n components.push({\n id: credentialId,\n type: 'credentials',\n filePath: relativePath,\n variableName: credentialKey, // Use the env settings key as variable name\n startLine,\n isInline: true,\n overrideExisting: true, // Mark this to override any existing registration\n });\n }\n }\n }\n }\n }\n }\n });\n }\n }\n });\n }\n }\n }\n }\n }\n });\n\n return components;\n } catch (error) {\n if (debug) {\n console.warn(`Failed to parse file ${relativePath}: ${error}`);\n }\n return [];\n }\n}\n\n/**\n * Parse a call expression to extract component information\n * Handles the same logic as the original regex patterns\n */\nfunction parseCallExpression(\n callExpression: CallExpression,\n variableName: string | undefined,\n isInline: boolean,\n relativePath: string\n): ComponentMatch | null {\n const expression = callExpression.getExpression();\n\n // Get the function name (e.g., 'dataComponent', 'tool', etc.)\n let functionName: string;\n if (Node.isIdentifier(expression)) {\n functionName = expression.getText();\n } else {\n return null;\n }\n\n // Map function name to component type\n const componentType = FUNCTION_NAME_TO_TYPE[functionName];\n if (!componentType || !VALID_COMPONENT_TYPES.has(componentType)) {\n return null;\n }\n\n // Get the first argument (should be an object literal)\n const args = callExpression.getArguments();\n if (args.length === 0 || !Node.isObjectLiteralExpression(args[0])) {\n return null;\n }\n\n const configObject = args[0] as ObjectLiteralExpression;\n\n // Extract the component ID using the same rules as regex parser\n let componentId: string | null = null;\n\n // Look for 'id' property first (most common case)\n const idProperty = configObject.getProperty('id');\n if (idProperty && Node.isPropertyAssignment(idProperty)) {\n const idValue = idProperty.getInitializer();\n if (Node.isStringLiteral(idValue)) {\n componentId = idValue.getLiteralValue();\n }\n }\n\n // For statusComponents, look for 'type' property if 'id' not found (matches regex logic)\n if (!componentId && componentType === 'statusComponents') {\n const typeProperty = configObject.getProperty('type');\n if (typeProperty && Node.isPropertyAssignment(typeProperty)) {\n const typeValue = typeProperty.getInitializer();\n if (Node.isStringLiteral(typeValue)) {\n componentId = typeValue.getLiteralValue();\n }\n }\n }\n\n // For functionTools, look for 'name' property if 'id' not found (matches regex logic)\n if (!componentId && componentType === 'functionTools') {\n const nameProperty = configObject.getProperty('name');\n if (nameProperty && Node.isPropertyAssignment(nameProperty)) {\n const nameValue = nameProperty.getInitializer();\n if (Node.isStringLiteral(nameValue)) {\n componentId = nameValue.getLiteralValue();\n }\n }\n }\n\n if (!componentId) {\n return null;\n }\n\n const startLine = callExpression.getStartLineNumber();\n\n return {\n id: componentId,\n type: componentType,\n filePath: relativePath,\n variableName: variableName,\n startLine,\n isInline,\n };\n}\n\n/**\n * Scan project directory for all components\n */\nfunction scanProjectForComponents(projectRoot: string, debug: boolean = false): ComponentMatch[] {\n const allComponents: ComponentMatch[] = [];\n\n if (!existsSync(projectRoot)) {\n return allComponents;\n }\n\n const scanDir = (dir: string) => {\n try {\n const items = readdirSync(dir);\n for (const item of items) {\n const fullPath = join(dir, item);\n const stat = statSync(fullPath);\n\n if (stat.isDirectory()) {\n // Skip node_modules, build directories, and temp validation directories\n if (\n !['node_modules', '.next', '.git', 'dist', 'build'].includes(item) &&\n !item.startsWith('.temp-validation-')\n ) {\n scanDir(fullPath);\n }\n } else if (stat.isFile() && ['.ts', '.tsx', '.js', '.jsx'].includes(extname(item))) {\n const fileComponents = parseFileForComponents(fullPath, projectRoot, debug);\n allComponents.push(...fileComponents);\n }\n }\n } catch (error) {\n if (debug) {\n console.warn(`Failed to scan directory ${dir}: ${error}`);\n }\n }\n };\n\n scanDir(projectRoot);\n\n return allComponents;\n}\n\n/**\n * Build component registry from project parsing\n */\nexport function buildComponentRegistryFromParsing(\n projectRoot: string,\n debug: boolean = false\n): ComponentRegistry {\n const registry = new ComponentRegistry();\n\n const allComponents = scanProjectForComponents(projectRoot, debug);\n\n // Sort components to prioritize exported over inline (in case of duplicates)\n allComponents.sort((a, b) => {\n if (a.id === b.id) {\n // Same ID: prioritize exported (false) over inline (true)\n return Number(a.isInline) - Number(b.isInline);\n }\n return 0; // Keep original order for different IDs\n });\n\n // Register components with registry (avoid duplicates by ID)\n const stats = {\n exported: 0,\n inline: 0,\n byType: {} as Record<string, number>,\n };\n\n const registeredTypeIds = new Set<string>(); // Use type:id instead of just id\n\n for (const component of allComponents) {\n const typeId = `${component.type}:${component.id}`;\n\n // Skip if already registered, unless this component should override existing\n if (registeredTypeIds.has(typeId) && !component.overrideExisting) {\n continue;\n }\n\n registeredTypeIds.add(typeId);\n\n if (component.variableName) {\n // Component has an actual variable name (declared with const/export const), use it\n\n if (component.overrideExisting && component.type === 'credentials') {\n // Use override method for credentials with env settings keys\n registry.overrideCredentialWithEnvKey(\n component.id,\n component.filePath,\n component.variableName\n );\n } else {\n registry.register(\n component.id,\n component.type,\n component.filePath,\n component.variableName,\n component.isInline\n );\n }\n } else {\n // Truly inline component with no variable name, let registry generate unique name\n registry.register(\n component.id,\n component.type,\n component.filePath,\n undefined, // Let registry handle naming with conflict resolution\n true // isInline = true\n );\n }\n\n // Update stats\n if (component.isInline) {\n stats.inline++;\n } else {\n stats.exported++;\n }\n stats.byType[component.type] = (stats.byType[component.type] || 0) + 1;\n }\n return registry;\n}\n\n/**\n * Get component location info for a specific component ID\n */\nexport function findComponentById(componentId: string, projectRoot: string): ComponentMatch | null {\n const allComponents = scanProjectForComponents(projectRoot, false);\n return allComponents.find((comp) => comp.id === componentId) || null;\n}\n\n/**\n * Get all local component IDs\n */\nexport function getAllLocalComponentIds(projectRoot: string): Set<string> {\n const allComponents = scanProjectForComponents(projectRoot, false);\n return new Set(allComponents.map((comp) => comp.id));\n}\n"],"mappings":"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"}
|
|
@@ -369,4 +369,5 @@ function findSubAgentWithParent(project, subAgentId) {
|
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
//#endregion
|
|
372
|
-
export { ComponentRegistry, extractSubAgents, findSubAgentWithParent, registerAllComponents };
|
|
372
|
+
export { ComponentRegistry, extractSubAgents, findSubAgentWithParent, registerAllComponents };
|
|
373
|
+
//# sourceMappingURL=component-registry.js.map
|