@inkeep/agents-cli 0.1.2 → 0.1.3

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/config.d.ts CHANGED
@@ -5,6 +5,7 @@ interface InkeepConfig {
5
5
  projectId: string;
6
6
  managementApiUrl: string;
7
7
  executionApiUrl: string;
8
+ manageUiUrl?: string;
8
9
  outputDirectory?: string;
9
10
  modelSettings?: ModelSettings;
10
11
  }
package/dist/index.js CHANGED
@@ -78,8 +78,8 @@ var init_tsx_loader = __esm({
78
78
  });
79
79
 
80
80
  // src/utils/config.ts
81
- import { existsSync as existsSync3 } from "fs";
82
- import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
81
+ import { existsSync as existsSync4 } from "fs";
82
+ import { dirname as dirname3, join as join4, resolve as resolve2 } from "path";
83
83
  import dotenv from "dotenv";
84
84
  function findConfigFile(startPath = process.cwd()) {
85
85
  let currentPath = resolve2(startPath);
@@ -87,12 +87,12 @@ function findConfigFile(startPath = process.cwd()) {
87
87
  const configNames = ["inkeep.config.ts", "inkeep.config.js", ".inkeeprc.ts", ".inkeeprc.js"];
88
88
  while (currentPath !== root) {
89
89
  for (const configName of configNames) {
90
- const configPath = join3(currentPath, configName);
91
- if (existsSync3(configPath)) {
90
+ const configPath = join4(currentPath, configName);
91
+ if (existsSync4(configPath)) {
92
92
  return configPath;
93
93
  }
94
94
  }
95
- const parentPath = dirname2(currentPath);
95
+ const parentPath = dirname3(currentPath);
96
96
  if (parentPath === currentPath) {
97
97
  break;
98
98
  }
@@ -104,7 +104,7 @@ async function loadConfigFromFile(configPath) {
104
104
  let resolvedPath;
105
105
  if (configPath) {
106
106
  resolvedPath = resolve2(process.cwd(), configPath);
107
- if (!existsSync3(resolvedPath)) {
107
+ if (!existsSync4(resolvedPath)) {
108
108
  throw new Error(`Config file not found: ${resolvedPath}`);
109
109
  }
110
110
  } else {
@@ -128,7 +128,8 @@ async function loadConfigFromFile(configPath) {
128
128
  async function loadConfig(configPath) {
129
129
  const config3 = {
130
130
  managementApiUrl: "http://localhost:3002",
131
- executionApiUrl: "http://localhost:3003"
131
+ executionApiUrl: "http://localhost:3003",
132
+ manageUiUrl: "http://localhost:3000"
132
133
  };
133
134
  const fileConfig = await loadConfigFromFile(configPath);
134
135
  if (fileConfig) {
@@ -206,8 +207,8 @@ Please ensure your config file exports a valid configuration with executionApiUr
206
207
  projectId: projectId2,
207
208
  managementApiUrl: managementApiUrl2,
208
209
  executionApiUrl: executionApiUrl2,
210
+ manageUiUrl: config4.manageUiUrl,
209
211
  modelSettings: config4.modelSettings || void 0,
210
- outputDirectory: config4.outputDirectory,
211
212
  sources: sources2
212
213
  };
213
214
  }
@@ -223,6 +224,7 @@ Please ensure your config file exports a valid configuration with executionApiUr
223
224
  projectId: "default",
224
225
  managementApiUrl: managementApiUrlFlag,
225
226
  executionApiUrl: executionApiUrlFlag,
227
+ manageUiUrl: void 0,
226
228
  modelSettings: void 0,
227
229
  sources: sources2
228
230
  };
@@ -292,8 +294,8 @@ Please either:
292
294
  projectId,
293
295
  managementApiUrl,
294
296
  executionApiUrl,
297
+ manageUiUrl: config3.manageUiUrl,
295
298
  modelSettings: config3.modelSettings || void 0,
296
- outputDirectory: config3.outputDirectory,
297
299
  sources
298
300
  };
299
301
  }
@@ -14706,9 +14708,9 @@ __export(chat_enhanced_exports, {
14706
14708
  chatCommandEnhanced: () => chatCommandEnhanced
14707
14709
  });
14708
14710
  import * as readline from "readline";
14709
- import chalk6 from "chalk";
14711
+ import chalk7 from "chalk";
14710
14712
  import inquirer3 from "inquirer";
14711
- import ora4 from "ora";
14713
+ import ora5 from "ora";
14712
14714
  async function chatCommandEnhanced(graphIdInput, options) {
14713
14715
  let config3;
14714
14716
  try {
@@ -14719,13 +14721,13 @@ async function chatCommandEnhanced(graphIdInput, options) {
14719
14721
  options?.configFilePath
14720
14722
  );
14721
14723
  } catch (error43) {
14722
- console.error(chalk6.red(error43.message));
14724
+ console.error(chalk7.red(error43.message));
14723
14725
  process.exit(1);
14724
14726
  }
14725
- console.log(chalk6.gray("Using configuration:"));
14726
- console.log(chalk6.gray(` \u2022 Tenant ID: ${config3.sources.tenantId}`));
14727
- console.log(chalk6.gray(` \u2022 Management API: ${config3.sources.managementApiUrl}`));
14728
- console.log(chalk6.gray(` \u2022 Execution API: ${config3.sources.executionApiUrl}`));
14727
+ console.log(chalk7.gray("Using configuration:"));
14728
+ console.log(chalk7.gray(` \u2022 Tenant ID: ${config3.sources.tenantId}`));
14729
+ console.log(chalk7.gray(` \u2022 Management API: ${config3.sources.managementApiUrl}`));
14730
+ console.log(chalk7.gray(` \u2022 Execution API: ${config3.sources.executionApiUrl}`));
14729
14731
  console.log();
14730
14732
  const managementApi = await ManagementApiClient.create(
14731
14733
  config3.managementApiUrl,
@@ -14739,18 +14741,18 @@ async function chatCommandEnhanced(graphIdInput, options) {
14739
14741
  );
14740
14742
  let graphId = graphIdInput;
14741
14743
  if (!graphId) {
14742
- const spinner2 = ora4("Fetching available graphs...").start();
14744
+ const spinner2 = ora5("Fetching available graphs...").start();
14743
14745
  try {
14744
14746
  const graphs = await managementApi.listGraphs();
14745
14747
  spinner2.stop();
14746
14748
  if (graphs.length === 0) {
14747
14749
  console.error(
14748
- chalk6.red("No graphs available. Push a graph first with: inkeep push <graph-path>")
14750
+ chalk7.red("No graphs available. Push a graph first with: inkeep push <graph-path>")
14749
14751
  );
14750
14752
  process.exit(1);
14751
14753
  }
14752
14754
  const graphChoices = graphs.map((g) => ({
14753
- name: `${chalk6.cyan(g.id)} - ${g.name || "Unnamed Graph"}`,
14755
+ name: `${chalk7.cyan(g.id)} - ${g.name || "Unnamed Graph"}`,
14754
14756
  value: g.id,
14755
14757
  short: g.id,
14756
14758
  searchText: `${g.id} ${g.name || ""}`.toLowerCase()
@@ -14767,50 +14769,50 @@ async function chatCommandEnhanced(graphIdInput, options) {
14767
14769
  graphId = answer.graphId;
14768
14770
  } catch (error43) {
14769
14771
  spinner2.fail("Failed to fetch graphs");
14770
- console.error(chalk6.red("Error:"), error43 instanceof Error ? error43.message : error43);
14772
+ console.error(chalk7.red("Error:"), error43 instanceof Error ? error43.message : error43);
14771
14773
  process.exit(1);
14772
14774
  }
14773
14775
  }
14774
- const spinner = ora4("Connecting to graph...").start();
14776
+ const spinner = ora5("Connecting to graph...").start();
14775
14777
  try {
14776
14778
  const graph = await managementApi.getGraph(graphId);
14777
14779
  if (!graph) {
14778
14780
  spinner.fail(`Graph "${graphId}" not found`);
14779
14781
  const graphs = await managementApi.listGraphs();
14780
14782
  if (graphs.length > 0) {
14781
- console.log(chalk6.yellow("\nAvailable graphs:"));
14783
+ console.log(chalk7.yellow("\nAvailable graphs:"));
14782
14784
  graphs.forEach((g) => {
14783
- console.log(chalk6.gray(` \u2022 ${g.id} - ${g.name || "Unnamed"}`));
14785
+ console.log(chalk7.gray(` \u2022 ${g.id} - ${g.name || "Unnamed"}`));
14784
14786
  });
14785
- console.log(chalk6.gray('\nRun "inkeep chat" without arguments for interactive selection'));
14787
+ console.log(chalk7.gray('\nRun "inkeep chat" without arguments for interactive selection'));
14786
14788
  } else {
14787
- console.log(chalk6.yellow("\nNo graphs found. Please create and push a graph first."));
14788
- console.log(chalk6.gray("Example: inkeep push ./my-graph.js"));
14789
+ console.log(chalk7.yellow("\nNo graphs found. Please create and push a graph first."));
14790
+ console.log(chalk7.gray("Example: inkeep push ./my-graph.js"));
14789
14791
  }
14790
14792
  process.exit(1);
14791
14793
  }
14792
- spinner.succeed(`Connected to graph: ${chalk6.green(graph.name || graphId)}`);
14794
+ spinner.succeed(`Connected to graph: ${chalk7.green(graph.name || graphId)}`);
14793
14795
  if (graph.description) {
14794
- console.log(chalk6.gray(`Description: ${graph.description}`));
14796
+ console.log(chalk7.gray(`Description: ${graph.description}`));
14795
14797
  }
14796
14798
  if (graph.defaultAgentId || graph.default_agent_id) {
14797
- console.log(chalk6.gray(`Default Agent: ${graph.defaultAgentId || graph.default_agent_id}`));
14799
+ console.log(chalk7.gray(`Default Agent: ${graph.defaultAgentId || graph.default_agent_id}`));
14798
14800
  }
14799
14801
  } catch (error43) {
14800
14802
  spinner.fail("Failed to connect to graph");
14801
- console.error(chalk6.red("Error:"), error43 instanceof Error ? error43.message : error43);
14803
+ console.error(chalk7.red("Error:"), error43 instanceof Error ? error43.message : error43);
14802
14804
  process.exit(1);
14803
14805
  }
14804
14806
  const rl = readline.createInterface({
14805
14807
  input: process.stdin,
14806
14808
  output: process.stdout,
14807
- prompt: chalk6.cyan("You> ")
14809
+ prompt: chalk7.cyan("You> ")
14808
14810
  });
14809
14811
  const conversationId = `cli-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
14810
14812
  const messages2 = [];
14811
14813
  let debugMode = false;
14812
- console.log(chalk6.gray('\n\u{1F4AC} Chat session started. Type "exit" or press Ctrl+C to quit.'));
14813
- console.log(chalk6.gray("Commands: help, clear, history, reset, debug\n"));
14814
+ console.log(chalk7.gray('\n\u{1F4AC} Chat session started. Type "exit" or press Ctrl+C to quit.'));
14815
+ console.log(chalk7.gray("Commands: help, clear, history, reset, debug\n"));
14814
14816
  async function handleStreamingResponse(stream, showDebug = false) {
14815
14817
  const decoder = new TextDecoder();
14816
14818
  const reader = stream.getReader();
@@ -14866,12 +14868,12 @@ async function chatCommandEnhanced(graphIdInput, options) {
14866
14868
  if (opType === "completion" && hasStartedResponse) {
14867
14869
  console.log("");
14868
14870
  }
14869
- console.log(chalk6.gray(` [${opType}] ${ctxDisplay}`));
14871
+ console.log(chalk7.gray(` [${opType}] ${ctxDisplay}`));
14870
14872
  }
14871
14873
  currentPos = jsonEnd;
14872
14874
  } catch {
14873
14875
  if (!hasStartedResponse) {
14874
- process.stdout.write(chalk6.green("Assistant> "));
14876
+ process.stdout.write(chalk7.green("Assistant> "));
14875
14877
  hasStartedResponse = true;
14876
14878
  }
14877
14879
  process.stdout.write(content[currentPos]);
@@ -14880,7 +14882,7 @@ async function chatCommandEnhanced(graphIdInput, options) {
14880
14882
  }
14881
14883
  } else {
14882
14884
  if (!hasStartedResponse) {
14883
- process.stdout.write(chalk6.green("Assistant> "));
14885
+ process.stdout.write(chalk7.green("Assistant> "));
14884
14886
  hasStartedResponse = true;
14885
14887
  }
14886
14888
  process.stdout.write(content[currentPos]);
@@ -14900,7 +14902,7 @@ async function chatCommandEnhanced(graphIdInput, options) {
14900
14902
  if (hasStartedResponse) {
14901
14903
  console.log("\n");
14902
14904
  } else {
14903
- console.log(chalk6.green("Assistant> ") + chalk6.gray("(no response)") + "\n");
14905
+ console.log(chalk7.green("Assistant> ") + chalk7.gray("(no response)") + "\n");
14904
14906
  }
14905
14907
  return responseContent;
14906
14908
  }
@@ -14908,47 +14910,47 @@ async function chatCommandEnhanced(graphIdInput, options) {
14908
14910
  const trimmedInput = input.trim();
14909
14911
  const command = trimmedInput.toLowerCase().replace(/^\//, "");
14910
14912
  if (command === "exit") {
14911
- console.log(chalk6.gray("Goodbye! \u{1F44B}"));
14913
+ console.log(chalk7.gray("Goodbye! \u{1F44B}"));
14912
14914
  rl.close();
14913
14915
  process.exit(0);
14914
14916
  }
14915
14917
  if (command === "clear") {
14916
14918
  console.clear();
14917
- console.log(chalk6.gray("Screen cleared. Conversation context preserved.\n"));
14919
+ console.log(chalk7.gray("Screen cleared. Conversation context preserved.\n"));
14918
14920
  rl.prompt();
14919
14921
  return;
14920
14922
  }
14921
14923
  if (command === "help") {
14922
- console.log(chalk6.cyan("\n\u{1F4DA} Available commands:"));
14923
- console.log(chalk6.gray(" \u2022 exit - End the chat session"));
14924
- console.log(chalk6.gray(" \u2022 clear - Clear the screen (preserves context)"));
14925
- console.log(chalk6.gray(" \u2022 history - Show conversation history"));
14926
- console.log(chalk6.gray(" \u2022 reset - Reset conversation context"));
14927
- console.log(chalk6.gray(" \u2022 debug - Toggle debug mode (show/hide data operations)"));
14928
- console.log(chalk6.gray(" \u2022 help - Show this help message"));
14929
- console.log(chalk6.gray("\n Commands can be prefixed with / (e.g., /help)\n"));
14924
+ console.log(chalk7.cyan("\n\u{1F4DA} Available commands:"));
14925
+ console.log(chalk7.gray(" \u2022 exit - End the chat session"));
14926
+ console.log(chalk7.gray(" \u2022 clear - Clear the screen (preserves context)"));
14927
+ console.log(chalk7.gray(" \u2022 history - Show conversation history"));
14928
+ console.log(chalk7.gray(" \u2022 reset - Reset conversation context"));
14929
+ console.log(chalk7.gray(" \u2022 debug - Toggle debug mode (show/hide data operations)"));
14930
+ console.log(chalk7.gray(" \u2022 help - Show this help message"));
14931
+ console.log(chalk7.gray("\n Commands can be prefixed with / (e.g., /help)\n"));
14930
14932
  rl.prompt();
14931
14933
  return;
14932
14934
  }
14933
14935
  if (command === "debug") {
14934
14936
  debugMode = !debugMode;
14935
- console.log(chalk6.yellow(`
14937
+ console.log(chalk7.yellow(`
14936
14938
  \u{1F527} Debug mode: ${debugMode ? "ON" : "OFF"}`));
14937
14939
  if (debugMode) {
14938
- console.log(chalk6.gray("Data operations will be shown during responses.\n"));
14940
+ console.log(chalk7.gray("Data operations will be shown during responses.\n"));
14939
14941
  } else {
14940
- console.log(chalk6.gray("Data operations are hidden.\n"));
14942
+ console.log(chalk7.gray("Data operations are hidden.\n"));
14941
14943
  }
14942
14944
  rl.prompt();
14943
14945
  return;
14944
14946
  }
14945
14947
  if (command === "history") {
14946
- console.log(chalk6.cyan("\n\u{1F4DC} Conversation History:"));
14948
+ console.log(chalk7.cyan("\n\u{1F4DC} Conversation History:"));
14947
14949
  if (messages2.length === 0) {
14948
- console.log(chalk6.gray(" (No messages yet)\n"));
14950
+ console.log(chalk7.gray(" (No messages yet)\n"));
14949
14951
  } else {
14950
14952
  messages2.forEach((msg, idx) => {
14951
- const role = msg.role === "user" ? chalk6.blue("You") : chalk6.green("Assistant");
14953
+ const role = msg.role === "user" ? chalk7.blue("You") : chalk7.green("Assistant");
14952
14954
  const preview = msg.content.substring(0, 100);
14953
14955
  const suffix = msg.content.length > 100 ? "..." : "";
14954
14956
  console.log(` ${idx + 1}. ${role}: ${preview}${suffix}`);
@@ -14960,7 +14962,7 @@ async function chatCommandEnhanced(graphIdInput, options) {
14960
14962
  }
14961
14963
  if (command === "reset") {
14962
14964
  messages2.length = 0;
14963
- console.log(chalk6.yellow("\u26A0\uFE0F Conversation context has been reset.\n"));
14965
+ console.log(chalk7.yellow("\u26A0\uFE0F Conversation context has been reset.\n"));
14964
14966
  rl.prompt();
14965
14967
  return;
14966
14968
  }
@@ -14973,23 +14975,23 @@ async function chatCommandEnhanced(graphIdInput, options) {
14973
14975
  const response = await executionApi.chatCompletion(graphId, messages2, conversationId);
14974
14976
  let assistantResponse;
14975
14977
  if (typeof response === "string") {
14976
- console.log(chalk6.green("Assistant>"), response);
14978
+ console.log(chalk7.green("Assistant>"), response);
14977
14979
  assistantResponse = response;
14978
14980
  } else {
14979
14981
  assistantResponse = await handleStreamingResponse(response, debugMode);
14980
14982
  }
14981
14983
  messages2.push({ role: "assistant", content: assistantResponse });
14982
14984
  } catch (error43) {
14983
- console.error(chalk6.red("Error:"), error43 instanceof Error ? error43.message : error43);
14985
+ console.error(chalk7.red("Error:"), error43 instanceof Error ? error43.message : error43);
14984
14986
  }
14985
14987
  rl.prompt();
14986
14988
  });
14987
14989
  rl.on("close", () => {
14988
- console.log(chalk6.gray("\n\u{1F4CA} Session Summary:"));
14989
- console.log(chalk6.gray(` \u2022 Graph: ${graphId}`));
14990
- console.log(chalk6.gray(` \u2022 Messages: ${messages2.length}`));
14991
- console.log(chalk6.gray(` \u2022 Duration: ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}`));
14992
- console.log(chalk6.gray("\nChat session ended."));
14990
+ console.log(chalk7.gray("\n\u{1F4CA} Session Summary:"));
14991
+ console.log(chalk7.gray(` \u2022 Graph: ${graphId}`));
14992
+ console.log(chalk7.gray(` \u2022 Messages: ${messages2.length}`));
14993
+ console.log(chalk7.gray(` \u2022 Duration: ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}`));
14994
+ console.log(chalk7.gray("\nChat session ended."));
14993
14995
  process.exit(0);
14994
14996
  });
14995
14997
  rl.prompt();
@@ -15006,7 +15008,7 @@ var init_chat_enhanced = __esm({
15006
15008
  // src/index.ts
15007
15009
  init_esm_shims();
15008
15010
  import { readFileSync as readFileSync2 } from "fs";
15009
- import { dirname as dirname4, join as join5 } from "path";
15011
+ import { dirname as dirname5, join as join6 } from "path";
15010
15012
  import { fileURLToPath as fileURLToPath2 } from "url";
15011
15013
  import { Command } from "commander";
15012
15014
 
@@ -15131,15 +15133,86 @@ async function configListCommand(options) {
15131
15133
  await configGetCommand(void 0, options);
15132
15134
  }
15133
15135
 
15134
- // src/commands/init.ts
15136
+ // src/commands/dev.ts
15135
15137
  init_esm_shims();
15136
- import { existsSync as existsSync2, readdirSync, writeFileSync as writeFileSync2 } from "fs";
15137
- import { basename, dirname, join as join2, resolve } from "path";
15138
+ import { fork } from "child_process";
15139
+ import { existsSync as existsSync2 } from "fs";
15140
+ import { createRequire } from "module";
15141
+ import { dirname, join as join2 } from "path";
15138
15142
  import chalk2 from "chalk";
15143
+ import ora from "ora";
15144
+ var require2 = createRequire(import.meta.url);
15145
+ function resolveWebRuntime() {
15146
+ try {
15147
+ const pkg = require2.resolve("@inkeep/agents-manage-ui/package.json");
15148
+ const root = dirname(pkg);
15149
+ return join2(root, ".next/standalone/agents-manage-ui");
15150
+ } catch (err) {
15151
+ throw new Error(`Could not find @inkeep/agents-manage-ui package. ${err}`);
15152
+ }
15153
+ }
15154
+ function startWebApp({ port = 3e3, host = "127.0.0.1" }) {
15155
+ const spinner = ora("Starting dashboard server...").start();
15156
+ try {
15157
+ const rt = resolveWebRuntime();
15158
+ const entry = join2(rt, "server.js");
15159
+ console.log(entry);
15160
+ if (!existsSync2(entry)) {
15161
+ spinner.fail("Dashboard server not found");
15162
+ console.error(
15163
+ chalk2.red("The dashboard server has not been built yet. Please run the following commands:")
15164
+ );
15165
+ console.error(chalk2.yellow(" cd agents-manage-ui"));
15166
+ console.error(chalk2.yellow(" pnpm build"));
15167
+ console.error(chalk2.yellow(" pnpm start"));
15168
+ process.exit(1);
15169
+ }
15170
+ spinner.succeed("Starting dashboard server...");
15171
+ const child = fork(entry, [], {
15172
+ cwd: rt,
15173
+ env: {
15174
+ ...process.env,
15175
+ NODE_ENV: "production",
15176
+ PORT: String(port),
15177
+ HOSTNAME: host
15178
+ },
15179
+ stdio: "inherit"
15180
+ });
15181
+ console.log(chalk2.green(`\u{1F680} Dashboard server started at http://${host}:${port}`));
15182
+ console.log(chalk2.gray("Press Ctrl+C to stop the server"));
15183
+ process.on("SIGINT", () => {
15184
+ console.log(chalk2.yellow("\n\u{1F6D1} Stopping dashboard server..."));
15185
+ child.kill("SIGINT");
15186
+ process.exit(0);
15187
+ });
15188
+ process.on("SIGTERM", () => {
15189
+ child.kill("SIGTERM");
15190
+ process.exit(0);
15191
+ });
15192
+ return child;
15193
+ } catch (error43) {
15194
+ spinner.fail("Failed to start dashboard server");
15195
+ console.error(chalk2.red("Error:"), error43 instanceof Error ? error43.message : "Unknown error");
15196
+ process.exit(1);
15197
+ }
15198
+ }
15199
+ async function devCommand(options) {
15200
+ const { port = 3e3, host = "127.0.0.1" } = options;
15201
+ console.log(chalk2.blue("Inkeep Dashboard Server"));
15202
+ console.log(chalk2.gray(`Starting server on ${host}:${port}`));
15203
+ console.log("");
15204
+ startWebApp({ port, host });
15205
+ }
15206
+
15207
+ // src/commands/init.ts
15208
+ init_esm_shims();
15209
+ import { existsSync as existsSync3, readdirSync, writeFileSync as writeFileSync2 } from "fs";
15210
+ import { basename, dirname as dirname2, join as join3, resolve } from "path";
15211
+ import chalk3 from "chalk";
15139
15212
  import inquirer from "inquirer";
15140
15213
  function findProjectRoot(startPath) {
15141
15214
  let currentPath = resolve(startPath);
15142
- const root = dirname(currentPath);
15215
+ const root = dirname2(currentPath);
15143
15216
  const rootIndicators = [
15144
15217
  "package.json",
15145
15218
  ".git",
@@ -15154,7 +15227,7 @@ function findProjectRoot(startPath) {
15154
15227
  if (rootIndicators.some((indicator) => files.includes(indicator))) {
15155
15228
  return currentPath;
15156
15229
  }
15157
- const parentPath = dirname(currentPath);
15230
+ const parentPath = dirname2(currentPath);
15158
15231
  if (parentPath === currentPath) {
15159
15232
  break;
15160
15233
  }
@@ -15169,11 +15242,11 @@ async function initCommand(options) {
15169
15242
  if (options.path.endsWith(".ts") || options.path.endsWith(".js")) {
15170
15243
  configPath = resolvedPath;
15171
15244
  } else {
15172
- configPath = join2(resolvedPath, "inkeep.config.ts");
15245
+ configPath = join3(resolvedPath, "inkeep.config.ts");
15173
15246
  }
15174
15247
  } else {
15175
15248
  const projectRoot = findProjectRoot(process.cwd());
15176
- const suggestedPath = join2(projectRoot, "inkeep.config.ts");
15249
+ const suggestedPath = join3(projectRoot, "inkeep.config.ts");
15177
15250
  if (options?.interactive === false) {
15178
15251
  configPath = suggestedPath;
15179
15252
  } else {
@@ -15187,9 +15260,9 @@ async function initCommand(options) {
15187
15260
  if (!input || input.trim() === "") {
15188
15261
  return "Path is required";
15189
15262
  }
15190
- const dir = input.endsWith(".ts") || input.endsWith(".js") ? dirname(input) : input;
15263
+ const dir = input.endsWith(".ts") || input.endsWith(".js") ? dirname2(input) : input;
15191
15264
  const resolvedDir = resolve(process.cwd(), dir);
15192
- if (!existsSync2(resolvedDir)) {
15265
+ if (!existsSync3(resolvedDir)) {
15193
15266
  return `Directory does not exist: ${resolvedDir}`;
15194
15267
  }
15195
15268
  return true;
@@ -15197,10 +15270,10 @@ async function initCommand(options) {
15197
15270
  }
15198
15271
  ]);
15199
15272
  const resolvedPath = resolve(process.cwd(), confirmedPath);
15200
- configPath = confirmedPath.endsWith(".ts") || confirmedPath.endsWith(".js") ? resolvedPath : join2(resolvedPath, "inkeep.config.ts");
15273
+ configPath = confirmedPath.endsWith(".ts") || confirmedPath.endsWith(".js") ? resolvedPath : join3(resolvedPath, "inkeep.config.ts");
15201
15274
  }
15202
15275
  }
15203
- if (existsSync2(configPath)) {
15276
+ if (existsSync3(configPath)) {
15204
15277
  const { overwrite } = await inquirer.prompt([
15205
15278
  {
15206
15279
  type: "confirm",
@@ -15210,7 +15283,7 @@ async function initCommand(options) {
15210
15283
  }
15211
15284
  ]);
15212
15285
  if (!overwrite) {
15213
- console.log(chalk2.yellow("Init cancelled."));
15286
+ console.log(chalk3.yellow("Init cancelled."));
15214
15287
  return;
15215
15288
  }
15216
15289
  }
@@ -15263,19 +15336,19 @@ export default defineConfig({
15263
15336
  `;
15264
15337
  try {
15265
15338
  writeFileSync2(configPath, configContent);
15266
- console.log(chalk2.green("\u2713"), `Created ${chalk2.cyan(configPath)}`);
15267
- console.log(chalk2.gray("\nYou can now use the Inkeep CLI commands."));
15268
- console.log(chalk2.gray("For example: inkeep list-graphs"));
15269
- const configDir = dirname(configPath);
15339
+ console.log(chalk3.green("\u2713"), `Created ${chalk3.cyan(configPath)}`);
15340
+ console.log(chalk3.gray("\nYou can now use the Inkeep CLI commands."));
15341
+ console.log(chalk3.gray("For example: inkeep list-graphs"));
15342
+ const configDir = dirname2(configPath);
15270
15343
  if (configDir !== process.cwd()) {
15271
- console.log(chalk2.gray(`
15344
+ console.log(chalk3.gray(`
15272
15345
  Note: Config file created in ${configDir}`));
15273
15346
  console.log(
15274
- chalk2.gray(`Use --config ${configPath} with commands, or run commands from that directory.`)
15347
+ chalk3.gray(`Use --config ${configPath} with commands, or run commands from that directory.`)
15275
15348
  );
15276
15349
  }
15277
15350
  } catch (error43) {
15278
- console.error(chalk2.red("Failed to create config file:"), error43);
15351
+ console.error(chalk3.red("Failed to create config file:"), error43);
15279
15352
  process.exit(1);
15280
15353
  }
15281
15354
  }
@@ -15284,9 +15357,9 @@ Note: Config file created in ${configDir}`));
15284
15357
  init_esm_shims();
15285
15358
  init_api();
15286
15359
  init_config();
15287
- import chalk3 from "chalk";
15360
+ import chalk4 from "chalk";
15288
15361
  import Table from "cli-table3";
15289
- import ora from "ora";
15362
+ import ora2 from "ora";
15290
15363
  async function listGraphsCommand(options) {
15291
15364
  let config3;
15292
15365
  try {
@@ -15298,32 +15371,32 @@ async function listGraphsCommand(options) {
15298
15371
  options.configFilePath
15299
15372
  );
15300
15373
  } catch (error43) {
15301
- console.error(chalk3.red(error43.message));
15374
+ console.error(chalk4.red(error43.message));
15302
15375
  process.exit(1);
15303
15376
  }
15304
- console.log(chalk3.gray("Using configuration:"));
15305
- console.log(chalk3.gray(` \u2022 Tenant ID: ${config3.sources.tenantId}`));
15306
- console.log(chalk3.gray(` \u2022 API URL: ${config3.sources.managementApiUrl}`));
15377
+ console.log(chalk4.gray("Using configuration:"));
15378
+ console.log(chalk4.gray(` \u2022 Tenant ID: ${config3.sources.tenantId}`));
15379
+ console.log(chalk4.gray(` \u2022 API URL: ${config3.sources.managementApiUrl}`));
15307
15380
  console.log();
15308
15381
  const api = await ManagementApiClient.create(
15309
15382
  config3.managementApiUrl,
15310
15383
  options.configFilePath,
15311
15384
  config3.tenantId
15312
15385
  );
15313
- const spinner = ora("Fetching graphs...").start();
15386
+ const spinner = ora2("Fetching graphs...").start();
15314
15387
  try {
15315
15388
  const graphs = await api.listGraphs();
15316
15389
  spinner.succeed(`Found ${graphs.length} graph(s)`);
15317
15390
  if (graphs.length === 0) {
15318
- console.log(chalk3.gray("No graphs found. Push a graph with: inkeep push <graph-path>"));
15391
+ console.log(chalk4.gray("No graphs found. Push a graph with: inkeep push <graph-path>"));
15319
15392
  return;
15320
15393
  }
15321
15394
  const table = new Table({
15322
15395
  head: [
15323
- chalk3.cyan("Graph ID"),
15324
- chalk3.cyan("Name"),
15325
- chalk3.cyan("Default Agent"),
15326
- chalk3.cyan("Created")
15396
+ chalk4.cyan("Graph ID"),
15397
+ chalk4.cyan("Name"),
15398
+ chalk4.cyan("Default Agent"),
15399
+ chalk4.cyan("Created")
15327
15400
  ],
15328
15401
  style: {
15329
15402
  head: [],
@@ -15335,14 +15408,14 @@ async function listGraphsCommand(options) {
15335
15408
  table.push([
15336
15409
  graph.id || "",
15337
15410
  graph.name || graph.id || "",
15338
- graph.defaultAgentId || chalk3.gray("None"),
15411
+ graph.defaultAgentId || chalk4.gray("None"),
15339
15412
  createdDate
15340
15413
  ]);
15341
15414
  }
15342
15415
  console.log("\n" + table.toString());
15343
15416
  } catch (error43) {
15344
15417
  spinner.fail("Failed to fetch graphs");
15345
- console.error(chalk3.red("Error:"), error43 instanceof Error ? error43.message : error43);
15418
+ console.error(chalk4.red("Error:"), error43 instanceof Error ? error43.message : error43);
15346
15419
  process.exit(1);
15347
15420
  }
15348
15421
  }
@@ -15350,10 +15423,10 @@ async function listGraphsCommand(options) {
15350
15423
  // src/commands/pull.ts
15351
15424
  init_esm_shims();
15352
15425
  init_config();
15353
- import { existsSync as existsSync4, mkdirSync, writeFileSync as writeFileSync3 } from "fs";
15354
- import { join as join4, resolve as resolve3 } from "path";
15355
- import chalk4 from "chalk";
15356
- import ora2 from "ora";
15426
+ import { existsSync as existsSync5, mkdirSync, statSync, writeFileSync as writeFileSync3 } from "fs";
15427
+ import { dirname as dirname4, extname as extname2, join as join5, resolve as resolve3 } from "path";
15428
+ import chalk5 from "chalk";
15429
+ import ora3 from "ora";
15357
15430
 
15358
15431
  // src/utils/json-comparator.ts
15359
15432
  init_esm_shims();
@@ -15700,9 +15773,48 @@ CRITICAL: Return ONLY the raw TypeScript code. Do NOT wrap it in markdown code b
15700
15773
  }
15701
15774
 
15702
15775
  // src/commands/pull.ts
15776
+ function resolveOutputFilePath(outputPath, graphId, isJson) {
15777
+ const absoluteOutputPath = resolve3(process.cwd(), outputPath);
15778
+ if (existsSync5(absoluteOutputPath)) {
15779
+ const stats = statSync(absoluteOutputPath);
15780
+ if (stats.isDirectory()) {
15781
+ const extension = isJson ? ".json" : ".graph.ts";
15782
+ const filePath = join5(absoluteOutputPath, `${graphId}${extension}`);
15783
+ return {
15784
+ filePath,
15785
+ isExistingFile: existsSync5(filePath)
15786
+ };
15787
+ } else {
15788
+ return {
15789
+ filePath: absoluteOutputPath,
15790
+ isExistingFile: true
15791
+ };
15792
+ }
15793
+ } else {
15794
+ const extension = extname2(absoluteOutputPath);
15795
+ if (extension) {
15796
+ const parentDir = dirname4(absoluteOutputPath);
15797
+ if (!existsSync5(parentDir)) {
15798
+ mkdirSync(parentDir, { recursive: true });
15799
+ }
15800
+ return {
15801
+ filePath: absoluteOutputPath,
15802
+ isExistingFile: false
15803
+ };
15804
+ } else {
15805
+ mkdirSync(absoluteOutputPath, { recursive: true });
15806
+ const extension2 = isJson ? ".json" : ".graph.ts";
15807
+ const filePath = join5(absoluteOutputPath, `${graphId}${extension2}`);
15808
+ return {
15809
+ filePath,
15810
+ isExistingFile: false
15811
+ };
15812
+ }
15813
+ }
15814
+ }
15703
15815
  async function convertTypeScriptToJson(graphPath) {
15704
15816
  const absolutePath = resolve3(process.cwd(), graphPath);
15705
- if (!existsSync4(absolutePath)) {
15817
+ if (!existsSync5(absolutePath)) {
15706
15818
  throw new Error(`File not found: ${absolutePath}`);
15707
15819
  }
15708
15820
  const module = await importWithTypeScriptSupport(absolutePath);
@@ -15724,7 +15836,7 @@ async function convertTypeScriptToJson(graphPath) {
15724
15836
  return await graph.toFullGraphDefinition();
15725
15837
  }
15726
15838
  async function pullCommand(graphId, options) {
15727
- const spinner = ora2("Loading configuration...").start();
15839
+ const spinner = ora3("Loading configuration...").start();
15728
15840
  try {
15729
15841
  let config3;
15730
15842
  try {
@@ -15735,14 +15847,15 @@ async function pullCommand(graphId, options) {
15735
15847
  );
15736
15848
  } catch (error43) {
15737
15849
  spinner.fail("Configuration validation failed");
15738
- console.error(chalk4.red(error43.message));
15850
+ console.error(chalk5.red(error43.message));
15739
15851
  process.exit(1);
15740
15852
  }
15741
- const outputDirectory = options.outputPath || config3.outputDirectory || "./agent-configurations";
15742
- const absoluteOutputPath = resolve3(process.cwd(), outputDirectory);
15743
- if (!existsSync4(absoluteOutputPath)) {
15744
- mkdirSync(absoluteOutputPath, { recursive: true });
15745
- }
15853
+ const outputPath = options.outputPath || "./graphs";
15854
+ const { filePath: outputFilePath, isExistingFile } = resolveOutputFilePath(
15855
+ outputPath,
15856
+ graphId,
15857
+ !!options.json
15858
+ );
15746
15859
  spinner.text = "Fetching graph from API...";
15747
15860
  const response = await fetch(
15748
15861
  `${config3.managementApiUrl}/tenants/${config3.tenantId}/crud/projects/${config3.projectId}/graph/${graphId}`,
@@ -15765,36 +15878,36 @@ async function pullCommand(graphId, options) {
15765
15878
  const graphData = responseData.data;
15766
15879
  if (options.json) {
15767
15880
  spinner.text = "Writing JSON file...";
15768
- const jsonFilePath = join4(absoluteOutputPath, `${graphId}.json`);
15769
- writeFileSync3(jsonFilePath, JSON.stringify(graphData, null, 2), "utf-8");
15881
+ writeFileSync3(outputFilePath, JSON.stringify(graphData, null, 2), "utf-8");
15770
15882
  spinner.succeed(`Graph "${graphData.name}" pulled successfully`);
15771
- console.log(chalk4.green(`\u2705 JSON file created: ${jsonFilePath}`));
15772
- console.log(chalk4.cyan("\n\u2728 Next steps:"));
15773
- console.log(chalk4.gray(` \u2022 View the file: ${jsonFilePath}`));
15774
- console.log(chalk4.gray(` \u2022 Use the data in your application`));
15883
+ console.log(
15884
+ chalk5.green(`\u2705 JSON file ${isExistingFile ? "updated" : "created"}: ${outputFilePath}`)
15885
+ );
15886
+ console.log(chalk5.cyan("\n\u2728 Next steps:"));
15887
+ console.log(chalk5.gray(` \u2022 View the file: ${outputFilePath}`));
15888
+ console.log(chalk5.gray(` \u2022 Use the data in your application`));
15775
15889
  } else {
15776
- spinner.text = "Generating TypeScript file with LLM...";
15777
- const outputFilePath = join4(absoluteOutputPath, `${graphId}.graph.ts`);
15778
15890
  if (!config3.modelSettings) {
15779
15891
  spinner.fail("Model Settings is required for TypeScript generation");
15780
- console.error(chalk4.red("Error: No modelSettings found in configuration."));
15781
- console.error(chalk4.yellow("Please add modelSettings to your inkeep.config.ts file."));
15782
- console.error(chalk4.gray("Example:"));
15783
- console.error(chalk4.gray(" modelSettings: {"));
15784
- console.error(chalk4.gray(' model: "anthropic/claude-3-5-sonnet-20241022",'));
15785
- console.error(chalk4.gray(" providerOptions: { anthropic: {} }"));
15786
- console.error(chalk4.gray(" }"));
15892
+ console.error(chalk5.red("Error: No modelSettings found in configuration."));
15893
+ console.error(chalk5.yellow("Please add modelSettings to your inkeep.config.ts file."));
15894
+ console.error(chalk5.gray("Example:"));
15895
+ console.error(chalk5.gray(" modelSettings: {"));
15896
+ console.error(chalk5.gray(' model: "anthropic/claude-3-5-sonnet-20241022",'));
15897
+ console.error(chalk5.gray(" providerOptions: { anthropic: {} }"));
15898
+ console.error(chalk5.gray(" }"));
15787
15899
  process.exit(1);
15788
15900
  }
15789
15901
  const maxRetries = options.maxRetries || 3;
15790
15902
  let attempt = 1;
15791
15903
  let validationPassed = false;
15792
15904
  let previousDifferences = [];
15793
- while (attempt <= maxRetries && !validationPassed) {
15905
+ const shouldValidate = isExistingFile;
15906
+ while (attempt <= maxRetries && (!shouldValidate || !validationPassed)) {
15794
15907
  if (attempt > 1) {
15795
15908
  spinner.text = `Regenerating TypeScript file (attempt ${attempt}/${maxRetries})...`;
15796
15909
  } else {
15797
- spinner.text = "Generating TypeScript file with LLM...";
15910
+ spinner.text = isExistingFile ? "Merging into existing TypeScript file with LLM..." : "Generating TypeScript file with LLM...";
15798
15911
  }
15799
15912
  await generateTypeScriptFileWithLLM(
15800
15913
  graphData,
@@ -15807,93 +15920,103 @@ async function pullCommand(graphId, options) {
15807
15920
  previousDifferences: attempt > 1 ? previousDifferences : void 0
15808
15921
  }
15809
15922
  );
15810
- spinner.text = "Validating generated TypeScript file...";
15811
- try {
15812
- const convertedResult = await convertTypeScriptToJson(outputFilePath);
15813
- const comparison = compareJsonObjects(graphData, convertedResult, {
15814
- ignoreArrayOrder: true,
15815
- ignoreCase: false,
15816
- ignoreWhitespace: false,
15817
- showDetails: true
15818
- });
15819
- if (comparison.isEqual) {
15820
- validationPassed = true;
15821
- spinner.succeed("TypeScript file validation passed");
15822
- console.log(chalk4.green("\u2705 Generated TypeScript file matches original graph data"));
15823
- } else {
15824
- previousDifferences = comparison.differences.map(
15825
- (diff) => `${diff.path}: ${diff.description}`
15826
- );
15923
+ if (shouldValidate) {
15924
+ spinner.text = "Validating generated TypeScript file...";
15925
+ try {
15926
+ const convertedResult = await convertTypeScriptToJson(outputFilePath);
15927
+ const comparison = compareJsonObjects(graphData, convertedResult, {
15928
+ ignoreArrayOrder: true,
15929
+ ignoreCase: false,
15930
+ ignoreWhitespace: false,
15931
+ showDetails: true
15932
+ });
15933
+ if (comparison.isEqual) {
15934
+ validationPassed = true;
15935
+ spinner.succeed("TypeScript file validation passed");
15936
+ console.log(chalk5.green("\u2705 Generated TypeScript file matches original graph data"));
15937
+ } else {
15938
+ previousDifferences = comparison.differences.map(
15939
+ (diff) => `${diff.path}: ${diff.description}`
15940
+ );
15941
+ if (attempt < maxRetries) {
15942
+ spinner.warn(`Validation failed (attempt ${attempt}/${maxRetries}), retrying...`);
15943
+ console.log(
15944
+ chalk5.yellow(
15945
+ "\u26A0\uFE0F Generated TypeScript file has differences from original graph data:"
15946
+ )
15947
+ );
15948
+ console.log(chalk5.gray(getDifferenceSummary(comparison)));
15949
+ console.log(chalk5.gray("\n\u{1F504} Retrying with improved prompt..."));
15950
+ } else {
15951
+ spinner.fail("TypeScript file validation failed after all retries");
15952
+ console.log(
15953
+ chalk5.red("\u274C Generated TypeScript file has differences from original:")
15954
+ );
15955
+ console.log(chalk5.gray(getDifferenceSummary(comparison)));
15956
+ console.log(
15957
+ chalk5.yellow(
15958
+ "\n\u{1F4A1} You may need to manually edit the generated file or check the LLM configuration."
15959
+ )
15960
+ );
15961
+ }
15962
+ }
15963
+ } catch (validationError) {
15964
+ previousDifferences = [`Validation error: ${validationError.message}`];
15827
15965
  if (attempt < maxRetries) {
15828
15966
  spinner.warn(`Validation failed (attempt ${attempt}/${maxRetries}), retrying...`);
15829
15967
  console.log(
15830
- chalk4.yellow(
15831
- "\u26A0\uFE0F Generated TypeScript file has differences from original graph data:"
15968
+ chalk5.yellow(
15969
+ "\u26A0\uFE0F Could not validate generated TypeScript file against original graph data:"
15970
+ )
15971
+ );
15972
+ console.log(chalk5.gray(validationError.message));
15973
+ console.log(
15974
+ chalk5.gray(
15975
+ "This might be due to the generated file having syntax errors or missing dependencies."
15832
15976
  )
15833
15977
  );
15834
- console.log(chalk4.gray(getDifferenceSummary(comparison)));
15835
- console.log(chalk4.gray("\n\u{1F504} Retrying with improved prompt..."));
15978
+ console.log(chalk5.gray("\n\u{1F504} Retrying with improved prompt..."));
15836
15979
  } else {
15837
15980
  spinner.fail("TypeScript file validation failed after all retries");
15838
- console.log(chalk4.red("\u274C Generated TypeScript file has differences from original:"));
15839
- console.log(chalk4.gray(getDifferenceSummary(comparison)));
15840
15981
  console.log(
15841
- chalk4.yellow(
15982
+ chalk5.red(
15983
+ "\u274C Could not validate generated TypeScript file against original graph data:"
15984
+ )
15985
+ );
15986
+ console.log(chalk5.gray(validationError.message));
15987
+ console.log(
15988
+ chalk5.gray(
15989
+ "This might be due to the generated file having syntax errors or missing dependencies."
15990
+ )
15991
+ );
15992
+ console.log(
15993
+ chalk5.yellow(
15842
15994
  "\n\u{1F4A1} You may need to manually edit the generated file or check the LLM configuration."
15843
15995
  )
15844
15996
  );
15845
15997
  }
15846
15998
  }
15847
- } catch (validationError) {
15848
- previousDifferences = [`Validation error: ${validationError.message}`];
15849
- if (attempt < maxRetries) {
15850
- spinner.warn(`Validation failed (attempt ${attempt}/${maxRetries}), retrying...`);
15851
- console.log(
15852
- chalk4.yellow(
15853
- "\u26A0\uFE0F Could not validate generated TypeScript file against original graph data:"
15854
- )
15855
- );
15856
- console.log(chalk4.gray(validationError.message));
15857
- console.log(
15858
- chalk4.gray(
15859
- "This might be due to the generated file having syntax errors or missing dependencies."
15860
- )
15861
- );
15862
- console.log(chalk4.gray("\n\u{1F504} Retrying with improved prompt..."));
15863
- } else {
15864
- spinner.fail("TypeScript file validation failed after all retries");
15865
- console.log(
15866
- chalk4.red(
15867
- "\u274C Could not validate generated TypeScript file against original graph data:"
15868
- )
15869
- );
15870
- console.log(chalk4.gray(validationError.message));
15871
- console.log(
15872
- chalk4.gray(
15873
- "This might be due to the generated file having syntax errors or missing dependencies."
15874
- )
15875
- );
15876
- console.log(
15877
- chalk4.yellow(
15878
- "\n\u{1F4A1} You may need to manually edit the generated file or check the LLM configuration."
15879
- )
15880
- );
15881
- }
15999
+ } else {
16000
+ validationPassed = true;
15882
16001
  }
15883
16002
  attempt++;
15884
16003
  }
15885
16004
  spinner.succeed(`Graph "${graphData.name}" pulled successfully`);
15886
- console.log(chalk4.green(`\u2705 TypeScript file created: ${outputFilePath}`));
15887
- console.log(chalk4.cyan("\n\u2728 Next steps:"));
15888
- console.log(chalk4.gray(` \u2022 Edit the file: ${outputFilePath}`));
15889
- console.log(chalk4.gray(` \u2022 Test locally: inkeep push ${outputFilePath}`));
15890
- console.log(chalk4.gray(` \u2022 Version control: git add ${outputFilePath}`));
16005
+ console.log(
16006
+ chalk5.green(
16007
+ `\u2705 TypeScript file ${isExistingFile ? "updated" : "created"}: ${outputFilePath}`
16008
+ )
16009
+ );
16010
+ console.log(chalk5.cyan("\n\u2728 Next steps:"));
16011
+ console.log(chalk5.gray(` \u2022 Edit the file: ${outputFilePath}`));
16012
+ console.log(chalk5.gray(` \u2022 Test locally: inkeep push ${outputFilePath}`));
16013
+ console.log(chalk5.gray(` \u2022 Version control: git add ${outputFilePath}`));
15891
16014
  }
15892
16015
  } catch (error43) {
15893
16016
  spinner.fail("Failed to pull graph");
15894
- console.error(chalk4.red("Error:"), error43.message);
16017
+ console.error(chalk5.red("Error:"), error43.message);
15895
16018
  if (error43.stack && process.env.DEBUG) {
15896
- console.error(chalk4.gray(error43.stack));
16019
+ console.error(chalk5.gray(error43.stack));
15897
16020
  }
15898
16021
  process.exit(1);
15899
16022
  }
@@ -15901,7 +16024,7 @@ async function pullCommand(graphId, options) {
15901
16024
 
15902
16025
  // src/commands/push.ts
15903
16026
  init_esm_shims();
15904
- import { existsSync as existsSync5 } from "fs";
16027
+ import { existsSync as existsSync6 } from "fs";
15905
16028
  import { resolve as resolve4 } from "path";
15906
16029
 
15907
16030
  // ../packages/agents-core/src/index.ts
@@ -37107,16 +37230,32 @@ init_esm_shims();
37107
37230
  init_api();
37108
37231
  init_config();
37109
37232
  init_tsx_loader();
37110
- import chalk5 from "chalk";
37233
+ import chalk6 from "chalk";
37111
37234
  import inquirer2 from "inquirer";
37112
- import ora3 from "ora";
37235
+ import ora4 from "ora";
37236
+
37237
+ // src/utils/url.ts
37238
+ init_esm_shims();
37239
+ function normalizeBaseUrl(url2) {
37240
+ const trimmedUrl = url2.trim();
37241
+ if (!trimmedUrl.match(/^https?:\/\//i)) {
37242
+ throw new Error(`Invalid URL format: ${url2}. Must start with http:// or https://`);
37243
+ }
37244
+ return trimmedUrl.replace(/\/+$/, "");
37245
+ }
37246
+ function buildGraphViewUrl(manageUiUrl, tenantId, projectId, graphId) {
37247
+ const baseUrl = normalizeBaseUrl(manageUiUrl || "http://localhost:3000");
37248
+ return `${baseUrl}/${tenantId}/projects/${projectId}/graphs/${graphId}`;
37249
+ }
37250
+
37251
+ // src/commands/push.ts
37113
37252
  async function pushCommand(graphPath, options) {
37114
- const spinner = ora3("Loading graph configuration...").start();
37253
+ const spinner = ora4("Loading graph configuration...").start();
37115
37254
  try {
37116
37255
  const absolutePath = resolve4(process.cwd(), graphPath);
37117
- if (!existsSync5(absolutePath)) {
37256
+ if (!existsSync6(absolutePath)) {
37118
37257
  spinner.fail("Graph file not found");
37119
- console.error(chalk5.red(`File not found: ${absolutePath}`));
37258
+ console.error(chalk6.red(`File not found: ${absolutePath}`));
37120
37259
  process.exit(1);
37121
37260
  }
37122
37261
  spinner.text = "Loading graph module...";
@@ -37128,13 +37267,13 @@ async function pushCommand(graphPath, options) {
37128
37267
  });
37129
37268
  if (graphExports.length === 0) {
37130
37269
  spinner.fail("No AgentGraph exported from configuration file");
37131
- console.error(chalk5.red("Configuration file must export at least one AgentGraph instance"));
37270
+ console.error(chalk6.red("Configuration file must export at least one AgentGraph instance"));
37132
37271
  process.exit(1);
37133
37272
  }
37134
37273
  if (graphExports.length > 1) {
37135
37274
  spinner.fail("Multiple AgentGraphs exported from configuration file");
37136
- console.error(chalk5.red("Configuration file must export exactly one AgentGraph instance"));
37137
- console.error(chalk5.yellow("Found exports:"), graphExports.join(", "));
37275
+ console.error(chalk6.red("Configuration file must export exactly one AgentGraph instance"));
37276
+ console.error(chalk6.yellow("Found exports:"), graphExports.join(", "));
37138
37277
  process.exit(1);
37139
37278
  }
37140
37279
  const graphKey = graphExports[0];
@@ -37151,14 +37290,14 @@ async function pushCommand(graphPath, options) {
37151
37290
  );
37152
37291
  } catch (error43) {
37153
37292
  spinner.fail("Configuration validation failed");
37154
- console.error(chalk5.red(error43.message));
37293
+ console.error(chalk6.red(error43.message));
37155
37294
  process.exit(1);
37156
37295
  }
37157
37296
  spinner.succeed("Configuration loaded");
37158
- console.log(chalk5.gray("Configuration sources:"));
37159
- console.log(chalk5.gray(` \u2022 Tenant ID: ${config3.sources.tenantId}`));
37160
- console.log(chalk5.gray(` \u2022 Project ID: ${config3.sources.projectId}`));
37161
- console.log(chalk5.gray(` \u2022 API URL: ${config3.sources.managementApiUrl}`));
37297
+ console.log(chalk6.gray("Configuration sources:"));
37298
+ console.log(chalk6.gray(` \u2022 Tenant ID: ${config3.sources.tenantId}`));
37299
+ console.log(chalk6.gray(` \u2022 Project ID: ${config3.sources.projectId}`));
37300
+ console.log(chalk6.gray(` \u2022 API URL: ${config3.sources.managementApiUrl}`));
37162
37301
  const tenantId = config3.tenantId;
37163
37302
  const projectId = config3.projectId;
37164
37303
  const managementApiUrl = config3.managementApiUrl;
@@ -37166,10 +37305,10 @@ async function pushCommand(graphPath, options) {
37166
37305
  let dbUrl = process.env.DB_FILE_NAME || "local.db";
37167
37306
  if (dbUrl !== ":memory:" && !dbUrl.startsWith("file:") && !dbUrl.startsWith("libsql:") && !dbUrl.startsWith("http")) {
37168
37307
  const absolutePath2 = resolve4(process.cwd(), dbUrl);
37169
- if (!existsSync5(absolutePath2)) {
37308
+ if (!existsSync6(absolutePath2)) {
37170
37309
  spinner.fail(`Database file not found: ${absolutePath2}`);
37171
37310
  console.error(
37172
- chalk5.red(
37311
+ chalk6.red(
37173
37312
  "Please ensure the database file exists or set DB_FILE_NAME environment variable"
37174
37313
  )
37175
37314
  );
@@ -37193,7 +37332,7 @@ async function pushCommand(graphPath, options) {
37193
37332
  }
37194
37333
  ]);
37195
37334
  if (!shouldCreate) {
37196
- console.log(chalk5.yellow("Push cancelled. Project must exist before pushing a graph."));
37335
+ console.log(chalk6.yellow("Push cancelled. Project must exist before pushing a graph."));
37197
37336
  process.exit(0);
37198
37337
  }
37199
37338
  const { projectName, projectDescription } = await inquirer2.prompt([
@@ -37227,7 +37366,7 @@ async function pushCommand(graphPath, options) {
37227
37366
  spinner.succeed(`Project "${projectName}" created successfully`);
37228
37367
  } catch (error43) {
37229
37368
  spinner.fail("Failed to create project");
37230
- console.error(chalk5.red("Error:"), error43.message);
37369
+ console.error(chalk6.red("Error:"), error43.message);
37231
37370
  process.exit(1);
37232
37371
  }
37233
37372
  } else {
@@ -37280,27 +37419,33 @@ async function pushCommand(graphPath, options) {
37280
37419
  }
37281
37420
  }
37282
37421
  if (warnings.length > 0) {
37283
- console.log(chalk5.yellow("\n\u26A0\uFE0F Warnings:"));
37422
+ console.log(chalk6.yellow("\n\u26A0\uFE0F Warnings:"));
37284
37423
  warnings.forEach((warning) => {
37285
- console.log(chalk5.yellow(` \u2022 ${warning}`));
37424
+ console.log(chalk6.yellow(` \u2022 ${warning}`));
37286
37425
  });
37287
37426
  }
37288
- console.log(chalk5.cyan("\n\u{1F4CA} Graph Summary:"));
37289
- console.log(chalk5.gray(` \u2022 Graph ID: ${graphId}`));
37290
- console.log(chalk5.gray(` \u2022 Name: ${graphName}`));
37291
- console.log(chalk5.gray(` \u2022 Agents: ${stats.agentCount}`));
37292
- console.log(chalk5.gray(` \u2022 Tools: ${stats.toolCount}`));
37293
- console.log(chalk5.gray(` \u2022 Relations: ${stats.relationCount}`));
37294
- console.log(chalk5.green("\n\u2728 Next steps:"));
37295
- console.log(chalk5.gray(` \u2022 Test your graph: inkeep chat ${graphId}`));
37296
- console.log(chalk5.gray(` \u2022 View all graphs: inkeep list-graphs`));
37297
- console.log(chalk5.gray(` \u2022 Get graph details: inkeep get-graph ${graphId}`));
37427
+ console.log(chalk6.cyan("\n\u{1F4CA} Graph Summary:"));
37428
+ console.log(chalk6.gray(` \u2022 Graph ID: ${graphId}`));
37429
+ console.log(chalk6.gray(` \u2022 Name: ${graphName}`));
37430
+ console.log(chalk6.gray(` \u2022 Agents: ${stats.agentCount}`));
37431
+ console.log(chalk6.gray(` \u2022 Tools: ${stats.toolCount}`));
37432
+ console.log(chalk6.gray(` \u2022 Relations: ${stats.relationCount}`));
37433
+ console.log(chalk6.green("\n\u2728 Next steps:"));
37434
+ try {
37435
+ const viewGraphUrl = buildGraphViewUrl(config3.manageUiUrl, tenantId, projectId, graphId);
37436
+ console.log(chalk6.gray(` \u2022 View graph in UI: ${chalk6.cyan(viewGraphUrl)}`));
37437
+ } catch (error43) {
37438
+ console.debug("Could not generate UI link:", error43);
37439
+ }
37440
+ console.log(chalk6.gray(` \u2022 Test your graph: inkeep chat ${graphId}`));
37441
+ console.log(chalk6.gray(` \u2022 View all graphs: inkeep list-graphs`));
37442
+ console.log(chalk6.gray(` \u2022 Get graph details: inkeep get-graph ${graphId}`));
37298
37443
  process.exit(0);
37299
37444
  } catch (error43) {
37300
37445
  spinner.fail("Failed to push graph");
37301
- console.error(chalk5.red("Error:"), error43.message);
37446
+ console.error(chalk6.red("Error:"), error43.message);
37302
37447
  if (error43.stack && process.env.DEBUG) {
37303
- console.error(chalk5.gray(error43.stack));
37448
+ console.error(chalk6.gray(error43.stack));
37304
37449
  }
37305
37450
  process.exit(1);
37306
37451
  }
@@ -37308,8 +37453,8 @@ async function pushCommand(graphPath, options) {
37308
37453
 
37309
37454
  // src/index.ts
37310
37455
  var __filename2 = fileURLToPath2(import.meta.url);
37311
- var __dirname2 = dirname4(__filename2);
37312
- var packageJsonPath = join5(__dirname2, "..", "package.json");
37456
+ var __dirname2 = dirname5(__filename2);
37457
+ var packageJsonPath = join6(__dirname2, "..", "package.json");
37313
37458
  var packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
37314
37459
  var program = new Command();
37315
37460
  program.name("inkeep").description("CLI tool for Inkeep Agent Framework").version(packageJson.version);
@@ -37353,6 +37498,12 @@ program.command("list-graphs").description("List all available graphs for the cu
37353
37498
  ).action(async (options) => {
37354
37499
  await listGraphsCommand(options);
37355
37500
  });
37501
+ program.command("dev").description("Start the Inkeep dashboard server").option("--port <port>", "Port to run the server on", "3000").option("--host <host>", "Host to bind the server to", "127.0.0.1").action(async (options) => {
37502
+ await devCommand({
37503
+ port: parseInt(options.port, 10),
37504
+ host: options.host
37505
+ });
37506
+ });
37356
37507
  program.parse();
37357
37508
  /*! Bundled license information:
37358
37509
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Inkeep CLI tool",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -38,6 +38,7 @@
38
38
  "recast": "^0.23.0",
39
39
  "ts-morph": "^26.0.0",
40
40
  "tsx": "^4.20.5",
41
+ "@inkeep/agents-manage-ui": "^0.1.4",
41
42
  "@inkeep/agents-core": "^0.1.4"
42
43
  },
43
44
  "devDependencies": {