@knowledgine/cli 0.2.0 → 0.2.1

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.
Files changed (104) hide show
  1. package/dist/commands/capture.d.ts +13 -0
  2. package/dist/commands/capture.d.ts.map +1 -1
  3. package/dist/commands/capture.js +116 -11
  4. package/dist/commands/capture.js.map +1 -1
  5. package/dist/commands/demo.d.ts.map +1 -1
  6. package/dist/commands/demo.js +23 -19
  7. package/dist/commands/demo.js.map +1 -1
  8. package/dist/commands/feedback.d.ts +9 -0
  9. package/dist/commands/feedback.d.ts.map +1 -1
  10. package/dist/commands/feedback.js +62 -21
  11. package/dist/commands/feedback.js.map +1 -1
  12. package/dist/commands/ingest.d.ts +1 -0
  13. package/dist/commands/ingest.d.ts.map +1 -1
  14. package/dist/commands/ingest.js +82 -18
  15. package/dist/commands/ingest.js.map +1 -1
  16. package/dist/commands/init.d.ts.map +1 -1
  17. package/dist/commands/init.js +88 -60
  18. package/dist/commands/init.js.map +1 -1
  19. package/dist/commands/plugins.d.ts.map +1 -1
  20. package/dist/commands/plugins.js +14 -13
  21. package/dist/commands/plugins.js.map +1 -1
  22. package/dist/commands/search.d.ts.map +1 -1
  23. package/dist/commands/search.js +35 -12
  24. package/dist/commands/search.js.map +1 -1
  25. package/dist/commands/setup.d.ts +48 -5
  26. package/dist/commands/setup.d.ts.map +1 -1
  27. package/dist/commands/setup.js +263 -99
  28. package/dist/commands/setup.js.map +1 -1
  29. package/dist/commands/start.d.ts.map +1 -1
  30. package/dist/commands/start.js +27 -20
  31. package/dist/commands/start.js.map +1 -1
  32. package/dist/commands/status.d.ts.map +1 -1
  33. package/dist/commands/status.js +81 -53
  34. package/dist/commands/status.js.map +1 -1
  35. package/dist/commands/tool.d.ts.map +1 -1
  36. package/dist/commands/tool.js +5 -5
  37. package/dist/commands/tool.js.map +1 -1
  38. package/dist/commands/upgrade.d.ts.map +1 -1
  39. package/dist/commands/upgrade.js +64 -18
  40. package/dist/commands/upgrade.js.map +1 -1
  41. package/dist/index.js +51 -17
  42. package/dist/index.js.map +1 -1
  43. package/dist/lib/entity-extractor.d.ts +15 -0
  44. package/dist/lib/entity-extractor.d.ts.map +1 -0
  45. package/dist/lib/entity-extractor.js +86 -0
  46. package/dist/lib/entity-extractor.js.map +1 -0
  47. package/dist/lib/formatter.d.ts.map +1 -1
  48. package/dist/lib/formatter.js +35 -32
  49. package/dist/lib/formatter.js.map +1 -1
  50. package/dist/lib/indexer.d.ts +2 -0
  51. package/dist/lib/indexer.d.ts.map +1 -1
  52. package/dist/lib/indexer.js +2 -0
  53. package/dist/lib/indexer.js.map +1 -1
  54. package/dist/lib/ingest-watcher.d.ts.map +1 -1
  55. package/dist/lib/ingest-watcher.js +1 -0
  56. package/dist/lib/ingest-watcher.js.map +1 -1
  57. package/dist/lib/progress.d.ts +6 -0
  58. package/dist/lib/progress.d.ts.map +1 -1
  59. package/dist/lib/progress.js +42 -5
  60. package/dist/lib/progress.js.map +1 -1
  61. package/dist/lib/ui/box.d.ts +7 -0
  62. package/dist/lib/ui/box.d.ts.map +1 -0
  63. package/dist/lib/ui/box.js +19 -0
  64. package/dist/lib/ui/box.js.map +1 -0
  65. package/dist/lib/ui/error-formatter.d.ts +8 -0
  66. package/dist/lib/ui/error-formatter.d.ts.map +1 -0
  67. package/dist/lib/ui/error-formatter.js +21 -0
  68. package/dist/lib/ui/error-formatter.js.map +1 -0
  69. package/dist/lib/ui/index.d.ts +7 -0
  70. package/dist/lib/ui/index.d.ts.map +1 -0
  71. package/dist/lib/ui/index.js +7 -0
  72. package/dist/lib/ui/index.js.map +1 -0
  73. package/dist/lib/ui/output.d.ts +2 -0
  74. package/dist/lib/ui/output.d.ts.map +1 -0
  75. package/dist/lib/ui/output.js +4 -0
  76. package/dist/lib/ui/output.js.map +1 -0
  77. package/dist/lib/ui/spinner.d.ts +4 -0
  78. package/dist/lib/ui/spinner.d.ts.map +1 -0
  79. package/dist/lib/ui/spinner.js +5 -0
  80. package/dist/lib/ui/spinner.js.map +1 -0
  81. package/dist/lib/ui/table.d.ts +9 -0
  82. package/dist/lib/ui/table.d.ts.map +1 -0
  83. package/dist/lib/ui/table.js +28 -0
  84. package/dist/lib/ui/table.js.map +1 -0
  85. package/dist/lib/ui/theme.d.ts +21 -0
  86. package/dist/lib/ui/theme.d.ts.map +1 -0
  87. package/dist/lib/ui/theme.js +29 -0
  88. package/dist/lib/ui/theme.js.map +1 -0
  89. package/dist/lib/unknown-command-handler.d.ts +14 -0
  90. package/dist/lib/unknown-command-handler.d.ts.map +1 -0
  91. package/dist/lib/unknown-command-handler.js +25 -0
  92. package/dist/lib/unknown-command-handler.js.map +1 -0
  93. package/dist/lib/url-validator.d.ts.map +1 -1
  94. package/dist/lib/url-validator.js +5 -1
  95. package/dist/lib/url-validator.js.map +1 -1
  96. package/fixtures/demo/notes/api-design-decisions.md +7 -2
  97. package/fixtures/demo/notes/auth-debugging.md +8 -0
  98. package/fixtures/demo/notes/ci-cd-pipeline.md +7 -0
  99. package/fixtures/demo/notes/code-review-notes.md +7 -0
  100. package/fixtures/demo/notes/database-optimization.md +8 -0
  101. package/fixtures/demo/notes/docker-troubleshooting.md +7 -1
  102. package/fixtures/demo/notes/react-performance.md +7 -6
  103. package/fixtures/demo/notes/typescript-migration.md +13 -4
  104. package/package.json +11 -4
@@ -1,14 +1,11 @@
1
1
  import { resolve } from "path";
2
2
  import { existsSync } from "fs";
3
- import { loadConfig, createDatabase, Migrator, KnowledgeRepository, KnowledgeSearcher, GraphRepository, KnowledgeService, ALL_MIGRATIONS, } from "@knowledgine/core";
3
+ import { loadConfig, resolveDefaultPath, createDatabase, loadSqliteVecExtension, Migrator, KnowledgeRepository, GraphRepository, KnowledgeService, ALL_MIGRATIONS, OnnxEmbeddingProvider, ModelManager, DEFAULT_MODEL_NAME, } from "@knowledgine/core";
4
4
  import { getDemoNotesPath } from "./demo.js";
5
5
  import { formatSearchResults as formatToolSearchResults, formatRelatedNotes, } from "../lib/formatter.js";
6
+ import { colors, symbols } from "../lib/ui/index.js";
6
7
  export async function searchCommand(query, options) {
7
- const rootPath = options.demo
8
- ? getDemoNotesPath()
9
- : options.path
10
- ? resolve(options.path)
11
- : resolve(process.cwd());
8
+ const rootPath = options.demo ? getDemoNotesPath() : resolveDefaultPath(options.path);
12
9
  const knowledgineDir = resolve(rootPath, ".knowledgine");
13
10
  if (!existsSync(knowledgineDir)) {
14
11
  console.error(options.demo
@@ -20,6 +17,9 @@ export async function searchCommand(query, options) {
20
17
  const config = loadConfig(rootPath);
21
18
  const db = createDatabase(config.dbPath);
22
19
  try {
20
+ if (config.embedding?.enabled) {
21
+ await loadSqliteVecExtension(db);
22
+ }
23
23
  new Migrator(db, ALL_MIGRATIONS).migrate();
24
24
  const repository = new KnowledgeRepository(db);
25
25
  const graphRepository = new GraphRepository(db);
@@ -54,15 +54,38 @@ export async function searchCommand(query, options) {
54
54
  }
55
55
  return;
56
56
  }
57
+ // Initialize embedding provider if semantic is enabled and requested
58
+ let embeddingProvider;
59
+ if (mode !== "keyword" && config.embedding?.enabled) {
60
+ const modelManager = new ModelManager();
61
+ if (modelManager.isModelAvailable()) {
62
+ embeddingProvider = new OnnxEmbeddingProvider(DEFAULT_MODEL_NAME, modelManager);
63
+ }
64
+ }
57
65
  // 通常の検索モード
58
- const service = new KnowledgeService({ repository, rootPath, graphRepository });
66
+ const service = new KnowledgeService({
67
+ repository,
68
+ rootPath,
69
+ graphRepository,
70
+ embeddingProvider,
71
+ });
59
72
  const result = await service.search({ query, limit, mode });
73
+ const warnings = result.results.flatMap((r) => r.matchReason.filter((m) => m.startsWith("Warning:")));
74
+ if (warnings.length > 0) {
75
+ console.error(`\n${symbols.warning} ${colors.warning(warnings[0])}\n`);
76
+ }
77
+ // セマンティック検索が要求されたが利用不可の場合の警告
78
+ if (mode !== "keyword" && (!config.embedding?.enabled || !embeddingProvider)) {
79
+ console.error(`${symbols.warning} ${colors.warning("Semantic search is not configured. Falling back to FTS5.")}`);
80
+ console.error(`${symbols.arrow} ${colors.hint("Run 'knowledgine upgrade --semantic' to enable semantic search.")}`);
81
+ console.error("");
82
+ }
60
83
  if (format === "json") {
61
84
  console.log(JSON.stringify({ ok: true, command: "search", result }));
62
85
  }
63
86
  else if (format === "table") {
64
87
  if (result.results.length === 0) {
65
- console.error(`No results for "${query}".`);
88
+ console.error(`${symbols.info} ${colors.hint(`No results for "${query}".`)}`);
66
89
  }
67
90
  else {
68
91
  console.error(formatToolSearchResults(result.results, "table"));
@@ -84,10 +107,10 @@ export async function searchCommand(query, options) {
84
107
  /** 後方互換のためのレガシー出力形式 */
85
108
  function formatLegacySearchResults(query, results) {
86
109
  if (results.length === 0) {
87
- console.error(`No results for "${query}".`);
110
+ console.error(`${symbols.info} ${colors.hint(`No results for "${query}".`)}`);
88
111
  return;
89
112
  }
90
- console.error(`Results for "${query}" (${results.length} matches):`);
113
+ console.error(colors.bold(`Results for "${query}" (${results.length} matches):`));
91
114
  console.error("");
92
115
  for (let i = 0; i < results.length; i++) {
93
116
  const r = results[i];
@@ -100,10 +123,10 @@ function formatLegacySearchResults(query, results) {
100
123
  /** @deprecated Use searchCommand with format option instead */
101
124
  export function formatSearchResults(query, results) {
102
125
  if (results.length === 0) {
103
- console.error(`No results for "${query}".`);
126
+ console.error(`${symbols.info} ${colors.hint(`No results for "${query}".`)}`);
104
127
  return;
105
128
  }
106
- console.error(`Results for "${query}" (${results.length} matches):`);
129
+ console.error(colors.bold(`Results for "${query}" (${results.length} matches):`));
107
130
  console.error("");
108
131
  for (let i = 0; i < results.length; i++) {
109
132
  const r = results[i];
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
@@ -4,11 +4,54 @@ export interface SetupOptions {
4
4
  dryRun?: boolean;
5
5
  write?: boolean;
6
6
  }
7
- interface SetupIO {
8
- input: NodeJS.ReadableStream;
9
- output: NodeJS.WritableStream;
7
+ export declare const TARGETS: readonly [{
8
+ readonly value: "claude-desktop";
9
+ readonly label: "Claude Desktop";
10
+ readonly description: "Anthropic's desktop app";
11
+ }, {
12
+ readonly value: "cursor";
13
+ readonly label: "Cursor";
14
+ readonly description: "AI-first code editor";
15
+ }, {
16
+ readonly value: "claude-code";
17
+ readonly label: "Claude Code";
18
+ readonly description: "CLI agent for developers";
19
+ }, {
20
+ readonly value: "windsurf";
21
+ readonly label: "Windsurf";
22
+ readonly description: "Codeium's AI IDE";
23
+ }, {
24
+ readonly value: "vscode";
25
+ readonly label: "VS Code";
26
+ readonly description: "GitHub Copilot MCP";
27
+ }, {
28
+ readonly value: "zed";
29
+ readonly label: "Zed";
30
+ readonly description: "High-performance editor";
31
+ }, {
32
+ readonly value: "codex";
33
+ readonly label: "Codex CLI";
34
+ readonly description: "OpenAI's coding agent";
35
+ }, {
36
+ readonly value: "github-copilot";
37
+ readonly label: "GitHub Copilot CLI";
38
+ readonly description: "AI pair programmer CLI";
39
+ }, {
40
+ readonly value: "gemini";
41
+ readonly label: "Gemini CLI";
42
+ readonly description: "Google's AI coding agent";
43
+ }, {
44
+ readonly value: "antigravity";
45
+ readonly label: "Antigravity";
46
+ readonly description: "Google's AI development platform";
47
+ }];
48
+ export declare function getConfigPath(target: string): string;
49
+ export declare function getTargetLabel(target: string): string;
50
+ export declare const PROJECT_CONFIG_SUPPORT: Record<string, (projectRoot: string) => string>;
51
+ export interface SetupIO {
52
+ input?: NodeJS.ReadableStream;
53
+ output?: NodeJS.WritableStream;
10
54
  isTTY: boolean;
11
55
  }
12
- export declare function setupCommand(options: SetupOptions, io?: SetupIO): Promise<void>;
13
- export {};
56
+ export declare function setupCommand(options: SetupOptions, ioOrCommand?: SetupIO | unknown): Promise<void>;
14
57
  //# sourceMappingURL=setup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAmFD,UAAU,OAAO;IACf,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,KAAK,EAAE,OAAO,CAAC;CAChB;AAsCD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,EACrB,EAAE,CAAC,EAAE,OAAO,GACX,OAAO,CAAC,IAAI,CAAC,CAyEf"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAWD,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWV,CAAC;AAOX,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA+CpD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AAgHD,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAMlF,CAAC;AAiHF,MAAM,WAAW,OAAO;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFxG"}
@@ -1,41 +1,72 @@
1
1
  import { resolve, join } from "path";
2
2
  import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from "fs";
3
3
  import { homedir } from "os";
4
- import { createInterface } from "readline";
5
- function getClaudeDesktopConfigPath() {
6
- switch (process.platform) {
7
- case "darwin":
8
- return join(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
9
- case "linux":
10
- return join(homedir(), ".config", "claude", "claude_desktop_config.json");
11
- case "win32":
12
- return join(process.env["APPDATA"] ?? join(homedir(), "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
13
- default:
14
- return join(homedir(), ".config", "claude", "claude_desktop_config.json");
15
- }
16
- }
17
- function getCursorConfigPath() {
18
- return join(homedir(), ".cursor", "mcp.json");
19
- }
20
- function getConfigPath(target) {
4
+ import { resolveDefaultPath } from "@knowledgine/core";
5
+ import { createBox, colors, symbols } from "../lib/ui/index.js";
6
+ import * as p from "@clack/prompts";
7
+ import * as TOML from "smol-toml";
8
+ export const TARGETS = [
9
+ { value: "claude-desktop", label: "Claude Desktop", description: "Anthropic's desktop app" },
10
+ { value: "cursor", label: "Cursor", description: "AI-first code editor" },
11
+ { value: "claude-code", label: "Claude Code", description: "CLI agent for developers" },
12
+ { value: "windsurf", label: "Windsurf", description: "Codeium's AI IDE" },
13
+ { value: "vscode", label: "VS Code", description: "GitHub Copilot MCP" },
14
+ { value: "zed", label: "Zed", description: "High-performance editor" },
15
+ { value: "codex", label: "Codex CLI", description: "OpenAI's coding agent" },
16
+ { value: "github-copilot", label: "GitHub Copilot CLI", description: "AI pair programmer CLI" },
17
+ { value: "gemini", label: "Gemini CLI", description: "Google's AI coding agent" },
18
+ { value: "antigravity", label: "Antigravity", description: "Google's AI development platform" },
19
+ ];
20
+ // Zed uses "context_servers" key instead of "mcpServers"
21
+ const ZED_MCP_KEY = "context_servers";
22
+ export function getConfigPath(target) {
23
+ const home = homedir();
24
+ const appdata = process.env["APPDATA"] ?? join(home, "AppData", "Roaming");
21
25
  switch (target) {
22
26
  case "claude-desktop":
23
- return getClaudeDesktopConfigPath();
27
+ switch (process.platform) {
28
+ case "darwin":
29
+ return join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
30
+ case "win32":
31
+ return join(appdata, "Claude", "claude_desktop_config.json");
32
+ default:
33
+ return join(home, ".config", "claude", "claude_desktop_config.json");
34
+ }
24
35
  case "cursor":
25
- return getCursorConfigPath();
36
+ return join(home, ".cursor", "mcp.json");
37
+ case "claude-code":
38
+ return join(home, ".claude.json");
39
+ case "windsurf":
40
+ if (process.platform === "win32") {
41
+ return join(appdata, "Codeium", "Windsurf", "mcp_config.json");
42
+ }
43
+ return join(home, ".codeium", "windsurf", "mcp_config.json");
44
+ case "vscode":
45
+ switch (process.platform) {
46
+ case "darwin":
47
+ return join(home, "Library", "Application Support", "Code", "User", "settings.json");
48
+ case "win32":
49
+ return join(appdata, "Code", "User", "settings.json");
50
+ default:
51
+ return join(home, ".config", "Code", "User", "settings.json");
52
+ }
53
+ case "zed":
54
+ return join(home, ".config", "zed", "settings.json");
55
+ case "codex":
56
+ return join(home, ".codex", "config.toml");
57
+ case "github-copilot":
58
+ return join(home, ".copilot", "mcp-config.json");
59
+ case "gemini":
60
+ return join(home, ".gemini", "settings.json");
61
+ case "antigravity":
62
+ return join(home, ".gemini", "antigravity", "mcp_config.json");
26
63
  default:
27
- throw new Error(`Unknown target: ${target}. Supported: claude-desktop, cursor`);
64
+ throw new Error(`Unknown target: ${target}. Supported: ${TARGETS.map((t) => t.value).join(", ")}`);
28
65
  }
29
66
  }
30
- function getTargetLabel(target) {
31
- switch (target) {
32
- case "claude-desktop":
33
- return "Claude Desktop";
34
- case "cursor":
35
- return "Cursor";
36
- default:
37
- return target;
38
- }
67
+ export function getTargetLabel(target) {
68
+ const found = TARGETS.find((t) => t.value === target);
69
+ return found ? found.label : target;
39
70
  }
40
71
  function buildMcpConfig(rootPath) {
41
72
  return {
@@ -43,17 +74,42 @@ function buildMcpConfig(rootPath) {
43
74
  args: ["-y", "@knowledgine/cli", "start", "--path", rootPath],
44
75
  };
45
76
  }
46
- function readExistingConfig(configPath) {
77
+ function isTomlConfig(configPath) {
78
+ return configPath.endsWith(".toml");
79
+ }
80
+ /** Get the MCP servers key name for a given target */
81
+ function getMcpKey(target) {
82
+ if (target === "zed")
83
+ return ZED_MCP_KEY;
84
+ return "mcpServers";
85
+ }
86
+ function readExistingConfig(configPath, target) {
47
87
  if (!existsSync(configPath)) {
48
88
  return {};
49
89
  }
50
- const raw = readFileSync(configPath, "utf-8");
90
+ const raw = readFileSync(configPath, "utf-8").trim();
91
+ if (!raw) {
92
+ return {};
93
+ }
51
94
  try {
52
- return JSON.parse(raw);
95
+ if (isTomlConfig(configPath)) {
96
+ const parsed = TOML.parse(raw);
97
+ return {
98
+ mcpServers: (parsed["mcp_servers"] ?? {}),
99
+ };
100
+ }
101
+ const parsed = JSON.parse(raw);
102
+ const mcpKey = getMcpKey(target ?? "");
103
+ // For tools that embed MCP in a larger settings file (Zed, VS Code)
104
+ if (parsed[mcpKey]) {
105
+ return { mcpServers: parsed[mcpKey] };
106
+ }
107
+ return parsed;
53
108
  }
54
109
  catch {
110
+ const format = isTomlConfig(configPath) ? "TOML" : "JSON";
55
111
  throw new Error(`Failed to parse existing config: ${configPath}\n` +
56
- `The file contains invalid JSON. Fix it manually or remove it before running setup.`);
112
+ `The file contains invalid ${format}. Fix it manually or remove it before running setup.`);
57
113
  }
58
114
  }
59
115
  function mergeConfig(existing, rootPath) {
@@ -66,102 +122,210 @@ function mergeConfig(existing, rootPath) {
66
122
  },
67
123
  };
68
124
  }
69
- function getDefaultIO() {
70
- return {
71
- input: process.stdin,
72
- output: process.stderr,
73
- isTTY: process.stderr.isTTY ?? false,
74
- };
125
+ function writeConfig(configPath, config, target) {
126
+ const configDir = resolve(configPath, "..");
127
+ if (!existsSync(configDir)) {
128
+ mkdirSync(configDir, { recursive: true });
129
+ }
130
+ if (existsSync(configPath)) {
131
+ copyFileSync(configPath, configPath + ".bak");
132
+ }
133
+ if (isTomlConfig(configPath)) {
134
+ // TOML: read existing, merge mcp_servers, write back
135
+ let existing = {};
136
+ if (existsSync(configPath)) {
137
+ try {
138
+ existing = TOML.parse(readFileSync(configPath, "utf-8"));
139
+ }
140
+ catch { /* start fresh */ }
141
+ }
142
+ existing["mcp_servers"] = {
143
+ ...(existing["mcp_servers"] ?? {}),
144
+ knowledgine: config.mcpServers?.["knowledgine"] ?? buildMcpConfig(""),
145
+ };
146
+ writeFileSync(configPath, TOML.stringify(existing) + "\n", "utf-8");
147
+ }
148
+ else {
149
+ const mcpKey = getMcpKey(target ?? "");
150
+ const isEmbeddedSettings = mcpKey !== "mcpServers" || target === "vscode" || target === "gemini";
151
+ if (isEmbeddedSettings) {
152
+ // Zed/VS Code: merge into existing settings.json
153
+ let existing = {};
154
+ if (existsSync(configPath)) {
155
+ try {
156
+ existing = JSON.parse(readFileSync(configPath, "utf-8"));
157
+ }
158
+ catch { /* start fresh */ }
159
+ }
160
+ existing[mcpKey] = {
161
+ ...(existing[mcpKey] ?? {}),
162
+ knowledgine: config.mcpServers?.["knowledgine"] ?? buildMcpConfig(""),
163
+ };
164
+ writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
165
+ }
166
+ else {
167
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
168
+ }
169
+ }
170
+ }
171
+ function isTTY() {
172
+ // Check both stdin and stdout for interactive prompt support
173
+ return Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY);
75
174
  }
76
- async function promptTarget(io) {
77
- const targets = [
78
- { value: "claude-desktop", label: "Claude Desktop" },
79
- { value: "cursor", label: "Cursor" },
80
- ];
81
- return new Promise((resolvePrompt, reject) => {
82
- const rl = createInterface({
83
- input: io.input,
84
- output: io.output,
175
+ // Tools that support project-level config (in project root directory)
176
+ export const PROJECT_CONFIG_SUPPORT = {
177
+ cursor: (root) => join(root, ".cursor", "mcp.json"),
178
+ "claude-code": (root) => join(root, ".mcp.json"),
179
+ vscode: (root) => join(root, ".vscode", "mcp.json"),
180
+ windsurf: (root) => join(root, ".windsurf", "mcp_config.json"),
181
+ gemini: (root) => join(root, ".gemini", "settings.json"),
182
+ };
183
+ function getConfigPathForScope(target, scope, projectRoot) {
184
+ if (scope === "project") {
185
+ const projectFn = PROJECT_CONFIG_SUPPORT[target];
186
+ if (projectFn)
187
+ return projectFn(projectRoot);
188
+ }
189
+ return getConfigPath(target);
190
+ }
191
+ async function interactiveSetup(rootPath) {
192
+ p.intro(colors.bold("knowledgine Setup"));
193
+ // Step 1: Select tools
194
+ const selectedTargets = await p.multiselect({
195
+ message: "Which AI tools do you use? (space to select, enter to confirm)",
196
+ options: TARGETS.map((t) => ({
197
+ value: t.value,
198
+ label: t.label,
199
+ hint: t.description,
200
+ })),
201
+ required: true,
202
+ });
203
+ if (p.isCancel(selectedTargets)) {
204
+ p.cancel("Setup cancelled.");
205
+ return;
206
+ }
207
+ const targets = selectedTargets;
208
+ // Step 2: Select scope (only if any selected tool supports project-level config)
209
+ const hasProjectSupport = targets.some((t) => t in PROJECT_CONFIG_SUPPORT);
210
+ let scope = "global";
211
+ if (hasProjectSupport) {
212
+ const scopeResult = await p.select({
213
+ message: "Where should the config be installed?",
214
+ options: [
215
+ {
216
+ value: "global",
217
+ label: "Global",
218
+ hint: `User-level config (~/) — works everywhere`,
219
+ },
220
+ {
221
+ value: "project",
222
+ label: "Project",
223
+ hint: `Project-level config (./) — scoped to this workspace`,
224
+ },
225
+ ],
85
226
  });
86
- io.output.write("Select target AI tool:\n");
87
- for (let i = 0; i < targets.length; i++) {
88
- io.output.write(` ${i + 1}) ${targets[i].label}\n`);
227
+ if (p.isCancel(scopeResult)) {
228
+ p.cancel("Setup cancelled.");
229
+ return;
89
230
  }
90
- rl.question("Enter number (1-2): ", (answer) => {
91
- rl.close();
92
- const idx = parseInt(answer, 10) - 1;
93
- if (idx >= 0 && idx < targets.length) {
94
- resolvePrompt(targets[idx].value);
95
- }
96
- else {
97
- reject(new Error("Invalid selection. Run with --target to specify directly."));
98
- }
231
+ scope = scopeResult;
232
+ }
233
+ // Step 3: Configure each tool
234
+ const s = p.spinner();
235
+ const results = [];
236
+ for (const target of targets) {
237
+ const targetLabel = getTargetLabel(target);
238
+ const useProject = scope === "project" && target in PROJECT_CONFIG_SUPPORT;
239
+ const actualScope = useProject ? "project" : "global";
240
+ s.start(`Configuring ${targetLabel} (${actualScope})...`);
241
+ try {
242
+ const configPath = getConfigPathForScope(target, scope, rootPath);
243
+ const existingConfig = readExistingConfig(configPath, target);
244
+ const mergedConfig = mergeConfig(existingConfig, rootPath);
245
+ writeConfig(configPath, mergedConfig, target);
246
+ s.stop(`${symbols.success} ${colors.success(targetLabel)} configured (${actualScope})`);
247
+ const note = !useProject && scope === "project" ? "project config not supported, used global" : undefined;
248
+ results.push({ target, status: "ok", configPath, note });
249
+ }
250
+ catch (error) {
251
+ const msg = error instanceof Error ? error.message : String(error);
252
+ s.stop(`${symbols.error} ${colors.error(targetLabel)} failed`);
253
+ results.push({ target, status: "fail", configPath: "", error: msg });
254
+ }
255
+ }
256
+ // Summary
257
+ const ok = results.filter((r) => r.status === "ok");
258
+ const fail = results.filter((r) => r.status === "fail");
259
+ if (ok.length > 0) {
260
+ const lines = ok.map((r) => {
261
+ const extra = r.note ? ` ${colors.dim(`(${r.note})`)}` : "";
262
+ return `${symbols.success} ${getTargetLabel(r.target)} ${colors.dim(r.configPath)}${extra}`;
99
263
  });
100
- });
264
+ p.note(lines.join("\n"), "Configured");
265
+ }
266
+ if (fail.length > 0) {
267
+ const lines = fail.map((r) => `${symbols.error} ${getTargetLabel(r.target)} ${colors.dim(r.error ?? "")}`);
268
+ p.note(lines.join("\n"), "Failed");
269
+ }
270
+ p.outro(`${colors.success("Setup complete!")} Restart your AI tools to activate knowledgine.`);
101
271
  }
102
- export async function setupCommand(options, io) {
103
- const rootPath = resolve(options.path ?? process.cwd());
104
- const setupIO = io ?? getDefaultIO();
105
- // Check initialization
272
+ export async function setupCommand(options, ioOrCommand) {
273
+ // Commander.js passes (options, Command) — detect and ignore the Command object
274
+ const io = ioOrCommand && typeof ioOrCommand.isTTY === "boolean"
275
+ ? ioOrCommand
276
+ : undefined;
277
+ const rootPath = resolveDefaultPath(options.path);
106
278
  const knowledgineDir = resolve(rootPath, ".knowledgine");
107
279
  if (!existsSync(knowledgineDir)) {
108
- console.error(`Error: Not initialized. Run 'knowledgine init --path ${rootPath}' first.`);
280
+ console.error(`${symbols.error} Not initialized. Run 'knowledgine init --path ${rootPath}' first.`);
109
281
  process.exitCode = 1;
110
282
  return;
111
283
  }
112
- // Determine target
113
- let target = options.target;
114
- if (!target) {
115
- if (!setupIO.isTTY) {
284
+ // Interactive mode when no --target specified
285
+ if (!options.target) {
286
+ const tty = io ? io.isTTY : isTTY();
287
+ if (!tty) {
116
288
  console.error("Error: --target is required in non-interactive mode.");
117
- console.error(" Supported targets: claude-desktop, cursor");
289
+ console.error(` Supported targets: ${TARGETS.map((t) => t.value).join(", ")}`);
118
290
  process.exitCode = 1;
119
291
  return;
120
292
  }
121
- target = await promptTarget(setupIO);
293
+ await interactiveSetup(rootPath);
294
+ return;
122
295
  }
296
+ const target = options.target;
123
297
  const configPath = getConfigPath(target);
124
298
  const targetLabel = getTargetLabel(target);
125
299
  const shouldWrite = options.write === true;
126
- // Read existing config (may throw on invalid JSON)
127
300
  let existingConfig;
128
301
  try {
129
- existingConfig = readExistingConfig(configPath);
302
+ existingConfig = readExistingConfig(configPath, target);
130
303
  }
131
304
  catch (error) {
132
305
  console.error(error instanceof Error ? error.message : String(error));
133
306
  process.exitCode = 1;
134
307
  return;
135
308
  }
136
- const mergedConfig = mergeConfig(existingConfig, rootPath);
137
- const configJson = JSON.stringify(mergedConfig, null, 2);
138
- console.error(`\nMCP configuration for ${targetLabel}:`);
139
- console.error(` Config: ${configPath}`);
140
- console.error("");
141
- console.error(configJson);
142
- console.error("");
309
+ const knowledgineConfig = buildMcpConfig(rootPath);
310
+ const otherServerCount = Object.keys(existingConfig.mcpServers ?? {}).filter((k) => k !== "knowledgine").length;
311
+ const jsonContent = JSON.stringify({ mcpServers: { knowledgine: knowledgineConfig } }, null, 2);
312
+ const preserveNote = otherServerCount > 0
313
+ ? `\n${colors.hint(`(${otherServerCount} other MCP server(s) will be preserved)`)}`
314
+ : "";
315
+ const boxContent = `${colors.hint(`Config: ${configPath}`)}${preserveNote}\n\n${jsonContent}`;
316
+ console.error("\n" + createBox(boxContent, { title: `MCP Configuration for ${targetLabel}`, type: "info" }));
143
317
  if (!shouldWrite) {
144
- console.error(`To apply: Run with --write flag, then restart ${targetLabel}.`);
145
- console.error(` knowledgine setup --target ${target} --path ${rootPath} --write`);
318
+ console.error(`${symbols.arrow} ${colors.hint(`To apply: Run with --write flag, then restart ${targetLabel}.`)}`);
319
+ console.error(`${symbols.arrow} ${colors.hint(`knowledgine setup --target ${target} --path ${rootPath} --write`)}`);
146
320
  console.error("");
147
- console.error("Run 'knowledgine status' to verify your setup.");
321
+ console.error(`${symbols.arrow} ${colors.hint("Run 'knowledgine status' to verify your setup.")}`);
148
322
  return;
149
323
  }
150
- // Write config
151
- const configDir = resolve(configPath, "..");
152
- if (!existsSync(configDir)) {
153
- mkdirSync(configDir, { recursive: true });
154
- }
155
- // Backup existing file
156
- if (existsSync(configPath)) {
157
- const backupPath = configPath + ".bak";
158
- copyFileSync(configPath, backupPath);
159
- console.error(`Backup created: ${backupPath}`);
160
- }
161
- writeFileSync(configPath, configJson + "\n", "utf-8");
162
- console.error(`Config written: ${configPath}`);
324
+ const mergedConfig = mergeConfig(existingConfig, rootPath);
325
+ writeConfig(configPath, mergedConfig, target);
326
+ console.error(`${symbols.success} ${colors.success(`Config written: ${configPath}`)}`);
163
327
  console.error("");
164
- console.error(`Restart ${targetLabel} to activate knowledgine.`);
165
- console.error("Run 'knowledgine status' to verify your setup.");
328
+ console.error(`${symbols.arrow} ${colors.hint(`Restart ${targetLabel} to activate knowledgine.`)}`);
329
+ console.error(`${symbols.arrow} ${colors.hint("Run 'knowledgine status' to verify your setup.")}`);
166
330
  }
167
331
  //# sourceMappingURL=setup.js.map