kiri-mcp-server 0.2.0

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 (212) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +399 -0
  3. package/config/default.example.yml +12 -0
  4. package/config/denylist.yml +15 -0
  5. package/config/scoring-profiles.yml +37 -0
  6. package/config/security.yml +10 -0
  7. package/dist/client/cli.js +68 -0
  8. package/dist/client/cli.js.map +1 -0
  9. package/dist/client/index.js +5 -0
  10. package/dist/client/index.js.map +1 -0
  11. package/dist/config/default.example.yml +12 -0
  12. package/dist/config/denylist.yml +15 -0
  13. package/dist/config/scoring-profiles.yml +37 -0
  14. package/dist/config/security.yml +10 -0
  15. package/dist/eval/metrics.js +47 -0
  16. package/dist/eval/metrics.js.map +1 -0
  17. package/dist/indexer/cli.js +362 -0
  18. package/dist/indexer/cli.js.map +1 -0
  19. package/dist/indexer/codeintel.js +182 -0
  20. package/dist/indexer/codeintel.js.map +1 -0
  21. package/dist/indexer/git.js +30 -0
  22. package/dist/indexer/git.js.map +1 -0
  23. package/dist/indexer/language.js +34 -0
  24. package/dist/indexer/language.js.map +1 -0
  25. package/dist/indexer/pipeline/filters/denylist.js +71 -0
  26. package/dist/indexer/pipeline/filters/denylist.js.map +1 -0
  27. package/dist/indexer/schema.js +101 -0
  28. package/dist/indexer/schema.js.map +1 -0
  29. package/dist/package.json +93 -0
  30. package/dist/server/bootstrap.js +19 -0
  31. package/dist/server/bootstrap.js.map +1 -0
  32. package/dist/server/context.js +2 -0
  33. package/dist/server/context.js.map +1 -0
  34. package/dist/server/fallbacks/degradeController.js +69 -0
  35. package/dist/server/fallbacks/degradeController.js.map +1 -0
  36. package/dist/server/handlers.js +800 -0
  37. package/dist/server/handlers.js.map +1 -0
  38. package/dist/server/main.js +151 -0
  39. package/dist/server/main.js.map +1 -0
  40. package/dist/server/observability/metrics.js +56 -0
  41. package/dist/server/observability/metrics.js.map +1 -0
  42. package/dist/server/observability/tracing.js +58 -0
  43. package/dist/server/observability/tracing.js.map +1 -0
  44. package/dist/server/rpc.js +477 -0
  45. package/dist/server/rpc.js.map +1 -0
  46. package/dist/server/runtime.js +47 -0
  47. package/dist/server/runtime.js.map +1 -0
  48. package/dist/server/scoring.js +111 -0
  49. package/dist/server/scoring.js.map +1 -0
  50. package/dist/server/stdio.js +76 -0
  51. package/dist/server/stdio.js.map +1 -0
  52. package/dist/shared/duckdb.js +121 -0
  53. package/dist/shared/duckdb.js.map +1 -0
  54. package/dist/shared/embedding.js +85 -0
  55. package/dist/shared/embedding.js.map +1 -0
  56. package/dist/shared/index.js +9 -0
  57. package/dist/shared/index.js.map +1 -0
  58. package/dist/shared/security/config.js +64 -0
  59. package/dist/shared/security/config.js.map +1 -0
  60. package/dist/shared/security/masker.js +56 -0
  61. package/dist/shared/security/masker.js.map +1 -0
  62. package/dist/shared/tokenizer.js +5 -0
  63. package/dist/shared/tokenizer.js.map +1 -0
  64. package/dist/shared/utils/simpleYaml.js +90 -0
  65. package/dist/shared/utils/simpleYaml.js.map +1 -0
  66. package/dist/sql/schema.sql +6 -0
  67. package/dist/src/client/cli.d.ts +3 -0
  68. package/dist/src/client/cli.d.ts.map +1 -0
  69. package/dist/src/client/cli.js +68 -0
  70. package/dist/src/client/cli.js.map +1 -0
  71. package/dist/src/client/index.d.ts +5 -0
  72. package/dist/src/client/index.d.ts.map +1 -0
  73. package/dist/src/client/index.js +5 -0
  74. package/dist/src/client/index.js.map +1 -0
  75. package/dist/src/client/proxy.d.ts +9 -0
  76. package/dist/src/client/proxy.d.ts.map +1 -0
  77. package/dist/src/client/proxy.js +198 -0
  78. package/dist/src/client/proxy.js.map +1 -0
  79. package/dist/src/client/start-daemon.d.ts +30 -0
  80. package/dist/src/client/start-daemon.d.ts.map +1 -0
  81. package/dist/src/client/start-daemon.js +175 -0
  82. package/dist/src/client/start-daemon.js.map +1 -0
  83. package/dist/src/daemon/daemon.d.ts +9 -0
  84. package/dist/src/daemon/daemon.d.ts.map +1 -0
  85. package/dist/src/daemon/daemon.js +149 -0
  86. package/dist/src/daemon/daemon.js.map +1 -0
  87. package/dist/src/daemon/lifecycle.d.ts +101 -0
  88. package/dist/src/daemon/lifecycle.d.ts.map +1 -0
  89. package/dist/src/daemon/lifecycle.js +266 -0
  90. package/dist/src/daemon/lifecycle.js.map +1 -0
  91. package/dist/src/daemon/socket.d.ts +26 -0
  92. package/dist/src/daemon/socket.d.ts.map +1 -0
  93. package/dist/src/daemon/socket.js +132 -0
  94. package/dist/src/daemon/socket.js.map +1 -0
  95. package/dist/src/eval/metrics.d.ts +23 -0
  96. package/dist/src/eval/metrics.d.ts.map +1 -0
  97. package/dist/src/eval/metrics.js +47 -0
  98. package/dist/src/eval/metrics.js.map +1 -0
  99. package/dist/src/index.d.ts +11 -0
  100. package/dist/src/index.d.ts.map +1 -0
  101. package/dist/src/index.js +11 -0
  102. package/dist/src/index.js.map +1 -0
  103. package/dist/src/indexer/cli.d.ts +9 -0
  104. package/dist/src/indexer/cli.d.ts.map +1 -0
  105. package/dist/src/indexer/cli.js +402 -0
  106. package/dist/src/indexer/cli.js.map +1 -0
  107. package/dist/src/indexer/codeintel.d.ts +28 -0
  108. package/dist/src/indexer/codeintel.d.ts.map +1 -0
  109. package/dist/src/indexer/codeintel.js +451 -0
  110. package/dist/src/indexer/codeintel.js.map +1 -0
  111. package/dist/src/indexer/git.d.ts +4 -0
  112. package/dist/src/indexer/git.d.ts.map +1 -0
  113. package/dist/src/indexer/git.js +30 -0
  114. package/dist/src/indexer/git.js.map +1 -0
  115. package/dist/src/indexer/language.d.ts +2 -0
  116. package/dist/src/indexer/language.d.ts.map +1 -0
  117. package/dist/src/indexer/language.js +34 -0
  118. package/dist/src/indexer/language.js.map +1 -0
  119. package/dist/src/indexer/pipeline/filters/denylist.d.ts +10 -0
  120. package/dist/src/indexer/pipeline/filters/denylist.d.ts.map +1 -0
  121. package/dist/src/indexer/pipeline/filters/denylist.js +71 -0
  122. package/dist/src/indexer/pipeline/filters/denylist.js.map +1 -0
  123. package/dist/src/indexer/schema.d.ts +9 -0
  124. package/dist/src/indexer/schema.d.ts.map +1 -0
  125. package/dist/src/indexer/schema.js +125 -0
  126. package/dist/src/indexer/schema.js.map +1 -0
  127. package/dist/src/indexer/watch.d.ts +97 -0
  128. package/dist/src/indexer/watch.d.ts.map +1 -0
  129. package/dist/src/indexer/watch.js +264 -0
  130. package/dist/src/indexer/watch.js.map +1 -0
  131. package/dist/src/server/bootstrap.d.ts +11 -0
  132. package/dist/src/server/bootstrap.d.ts.map +1 -0
  133. package/dist/src/server/bootstrap.js +19 -0
  134. package/dist/src/server/bootstrap.js.map +1 -0
  135. package/dist/src/server/context.d.ts +9 -0
  136. package/dist/src/server/context.d.ts.map +1 -0
  137. package/dist/src/server/context.js +2 -0
  138. package/dist/src/server/context.js.map +1 -0
  139. package/dist/src/server/fallbacks/degradeController.d.ts +24 -0
  140. package/dist/src/server/fallbacks/degradeController.d.ts.map +1 -0
  141. package/dist/src/server/fallbacks/degradeController.js +135 -0
  142. package/dist/src/server/fallbacks/degradeController.js.map +1 -0
  143. package/dist/src/server/handlers.d.ts +105 -0
  144. package/dist/src/server/handlers.d.ts.map +1 -0
  145. package/dist/src/server/handlers.js +954 -0
  146. package/dist/src/server/handlers.js.map +1 -0
  147. package/dist/src/server/indexBootstrap.d.ts +13 -0
  148. package/dist/src/server/indexBootstrap.d.ts.map +1 -0
  149. package/dist/src/server/indexBootstrap.js +109 -0
  150. package/dist/src/server/indexBootstrap.js.map +1 -0
  151. package/dist/src/server/main.d.ts +10 -0
  152. package/dist/src/server/main.d.ts.map +1 -0
  153. package/dist/src/server/main.js +217 -0
  154. package/dist/src/server/main.js.map +1 -0
  155. package/dist/src/server/observability/metrics.d.ts +35 -0
  156. package/dist/src/server/observability/metrics.d.ts.map +1 -0
  157. package/dist/src/server/observability/metrics.js +70 -0
  158. package/dist/src/server/observability/metrics.js.map +1 -0
  159. package/dist/src/server/observability/tracing.d.ts +3 -0
  160. package/dist/src/server/observability/tracing.d.ts.map +1 -0
  161. package/dist/src/server/observability/tracing.js +58 -0
  162. package/dist/src/server/observability/tracing.js.map +1 -0
  163. package/dist/src/server/rpc.d.ts +39 -0
  164. package/dist/src/server/rpc.d.ts.map +1 -0
  165. package/dist/src/server/rpc.js +551 -0
  166. package/dist/src/server/rpc.js.map +1 -0
  167. package/dist/src/server/runtime.d.ts +21 -0
  168. package/dist/src/server/runtime.d.ts.map +1 -0
  169. package/dist/src/server/runtime.js +59 -0
  170. package/dist/src/server/runtime.js.map +1 -0
  171. package/dist/src/server/scoring.d.ts +20 -0
  172. package/dist/src/server/scoring.d.ts.map +1 -0
  173. package/dist/src/server/scoring.js +112 -0
  174. package/dist/src/server/scoring.js.map +1 -0
  175. package/dist/src/server/stdio.d.ts +4 -0
  176. package/dist/src/server/stdio.d.ts.map +1 -0
  177. package/dist/src/server/stdio.js +88 -0
  178. package/dist/src/server/stdio.js.map +1 -0
  179. package/dist/src/shared/duckdb.d.ts +16 -0
  180. package/dist/src/shared/duckdb.d.ts.map +1 -0
  181. package/dist/src/shared/duckdb.js +121 -0
  182. package/dist/src/shared/duckdb.js.map +1 -0
  183. package/dist/src/shared/embedding.d.ts +19 -0
  184. package/dist/src/shared/embedding.d.ts.map +1 -0
  185. package/dist/src/shared/embedding.js +85 -0
  186. package/dist/src/shared/embedding.js.map +1 -0
  187. package/dist/src/shared/index.d.ts +3 -0
  188. package/dist/src/shared/index.d.ts.map +1 -0
  189. package/dist/src/shared/index.js +9 -0
  190. package/dist/src/shared/index.js.map +1 -0
  191. package/dist/src/shared/security/config.d.ts +23 -0
  192. package/dist/src/shared/security/config.d.ts.map +1 -0
  193. package/dist/src/shared/security/config.js +66 -0
  194. package/dist/src/shared/security/config.js.map +1 -0
  195. package/dist/src/shared/security/masker.d.ts +10 -0
  196. package/dist/src/shared/security/masker.d.ts.map +1 -0
  197. package/dist/src/shared/security/masker.js +56 -0
  198. package/dist/src/shared/security/masker.js.map +1 -0
  199. package/dist/src/shared/tokenizer.d.ts +2 -0
  200. package/dist/src/shared/tokenizer.d.ts.map +1 -0
  201. package/dist/src/shared/tokenizer.js +5 -0
  202. package/dist/src/shared/tokenizer.js.map +1 -0
  203. package/dist/src/shared/utils/lockfile.d.ts +46 -0
  204. package/dist/src/shared/utils/lockfile.d.ts.map +1 -0
  205. package/dist/src/shared/utils/lockfile.js +136 -0
  206. package/dist/src/shared/utils/lockfile.js.map +1 -0
  207. package/dist/src/shared/utils/simpleYaml.d.ts +6 -0
  208. package/dist/src/shared/utils/simpleYaml.d.ts.map +1 -0
  209. package/dist/src/shared/utils/simpleYaml.js +90 -0
  210. package/dist/src/shared/utils/simpleYaml.js.map +1 -0
  211. package/package.json +91 -0
  212. package/sql/schema.sql +6 -0
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import process from "node:process";
3
+ import { bootstrapServer } from "../server/bootstrap.js";
4
+ import { evaluateSecurityStatus, updateSecurityLock } from "../shared/security/config.js";
5
+ function printUsage() {
6
+ console.info(`Usage: pnpm exec tsx src/client/cli.ts <command> [options]\n`);
7
+ console.info(`Commands:`);
8
+ console.info(` security verify [--write-lock] Verify security baseline matches lock file`);
9
+ }
10
+ function formatStatus() {
11
+ const status = evaluateSecurityStatus();
12
+ const lockInfo = status.lockHash ? `hash=${status.lockHash}` : "missing";
13
+ const matchState = status.matches ? "MATCH" : "MISMATCH";
14
+ return [
15
+ `config: ${status.configPath}`,
16
+ `lock: ${status.lockPath} (${lockInfo})`,
17
+ `state: ${matchState}`,
18
+ ].join("\n");
19
+ }
20
+ function handleSecurityVerify(argv) {
21
+ const writeLock = argv.includes("--write-lock");
22
+ const status = evaluateSecurityStatus();
23
+ if (!status.lockHash && writeLock) {
24
+ updateSecurityLock(status.hash);
25
+ console.info("Security lock created.");
26
+ const refreshed = evaluateSecurityStatus();
27
+ console.info([
28
+ `config: ${refreshed.configPath}`,
29
+ `lock: ${refreshed.lockPath} (hash=${refreshed.lockHash})`,
30
+ "state: MATCH",
31
+ ].join("\n"));
32
+ return 0;
33
+ }
34
+ try {
35
+ bootstrapServer({ allowWriteLock: writeLock });
36
+ console.info("Security baseline verified.");
37
+ console.info(formatStatus());
38
+ return 0;
39
+ }
40
+ catch (error) {
41
+ console.error(error instanceof Error ? error.message : String(error));
42
+ console.info(formatStatus());
43
+ return 1;
44
+ }
45
+ }
46
+ export function main(argv = process.argv.slice(2)) {
47
+ const [command, ...rest] = argv;
48
+ switch (command) {
49
+ case "security": {
50
+ const [subcommand, ...subArgs] = rest;
51
+ if (subcommand === "verify") {
52
+ return handleSecurityVerify(subArgs);
53
+ }
54
+ break;
55
+ }
56
+ case undefined:
57
+ printUsage();
58
+ return 1;
59
+ default:
60
+ break;
61
+ }
62
+ printUsage();
63
+ return 1;
64
+ }
65
+ if (process.argv[1] && new URL(import.meta.url).pathname === process.argv[1]) {
66
+ process.exitCode = main();
67
+ }
68
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/client/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function buildContextBundleRequest(snippets: Array<{
2
+ path: string;
3
+ lines: number[];
4
+ }>): string;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,GACjD,MAAM,CAGR"}
@@ -0,0 +1,5 @@
1
+ export function buildContextBundleRequest(snippets) {
2
+ // TODO: align with MCP client schema
3
+ return JSON.stringify({ snippets }, null, 2);
4
+ }
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,yBAAyB,CACvC,QAAkD;IAElD,qCAAqC;IACrC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * KIRI Client Proxy
4
+ *
5
+ * Transparently bridges stdio (MCP client) ↔ Unix socket (daemon).
6
+ * Auto-starts daemon if not running, handles retries and fallback.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../src/client/proxy.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * KIRI Client Proxy
4
+ *
5
+ * Transparently bridges stdio (MCP client) ↔ Unix socket (daemon).
6
+ * Auto-starts daemon if not running, handles retries and fallback.
7
+ */
8
+ import * as net from "net";
9
+ import * as path from "path";
10
+ import * as readline from "readline";
11
+ import { parseArgs } from "util";
12
+ import packageJson from "../../package.json" with { type: "json" };
13
+ import { startDaemon, isDaemonRunning } from "./start-daemon.js";
14
+ /**
15
+ * CLI引数をパース
16
+ */
17
+ function parseProxyArgs() {
18
+ const { values } = parseArgs({
19
+ options: {
20
+ repo: { type: "string" },
21
+ db: { type: "string" },
22
+ "socket-path": { type: "string" },
23
+ watch: { type: "boolean", default: false },
24
+ "allow-degrade": { type: "boolean", default: false },
25
+ "security-config": { type: "string" },
26
+ "security-lock": { type: "string" },
27
+ },
28
+ });
29
+ const repoRoot = path.resolve(values.repo || process.cwd());
30
+ const databasePath = path.resolve(values.db || path.join(repoRoot, "var", "index.duckdb"));
31
+ const socketPath = values["socket-path"]
32
+ ? path.resolve(values["socket-path"])
33
+ : `${databasePath}.sock`;
34
+ return {
35
+ repoRoot,
36
+ databasePath,
37
+ socketPath,
38
+ watchMode: values.watch || false,
39
+ maxRetries: 3,
40
+ retryDelayMs: 1000,
41
+ allowDegrade: values["allow-degrade"] || false,
42
+ securityConfigPath: values["security-config"],
43
+ securityLockPath: values["security-lock"],
44
+ };
45
+ }
46
+ /**
47
+ * デーモンのバージョンをチェック
48
+ *
49
+ * Major/minor versionが一致しない場合はエラーを投げる
50
+ */
51
+ async function checkDaemonVersion(socket) {
52
+ return new Promise((resolve, reject) => {
53
+ const timeout = setTimeout(() => {
54
+ reject(new Error("Version check timeout"));
55
+ }, 3000);
56
+ // pingリクエストを送信してバージョン情報を取得
57
+ const pingRequest = {
58
+ jsonrpc: "2.0",
59
+ id: "version-check",
60
+ method: "ping",
61
+ };
62
+ let responseReceived = false;
63
+ const dataHandler = (data) => {
64
+ if (responseReceived)
65
+ return;
66
+ try {
67
+ const response = JSON.parse(data.toString().trim());
68
+ if (response.id === "version-check" && response.result) {
69
+ responseReceived = true;
70
+ clearTimeout(timeout);
71
+ socket.removeListener("data", dataHandler);
72
+ const daemonVersion = response.result.serverInfo?.version || "unknown";
73
+ const clientVersion = typeof packageJson?.version === "string" ? packageJson.version : "0.0.0";
74
+ // Major.minor バージョンを比較
75
+ const daemonMajorMinor = daemonVersion.split(".").slice(0, 2).join(".");
76
+ const clientMajorMinor = clientVersion.split(".").slice(0, 2).join(".");
77
+ if (daemonMajorMinor !== clientMajorMinor) {
78
+ reject(new Error(`Version mismatch: client ${clientVersion} is incompatible with daemon ${daemonVersion}. Restart the daemon to use the current version.`));
79
+ }
80
+ else {
81
+ console.error(`[Proxy] Version check passed: client=${clientVersion}, daemon=${daemonVersion}`);
82
+ resolve();
83
+ }
84
+ }
85
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
86
+ }
87
+ catch (parseErr) {
88
+ clearTimeout(timeout);
89
+ socket.removeListener("data", dataHandler);
90
+ reject(new Error("Failed to parse version check response"));
91
+ }
92
+ };
93
+ socket.on("data", dataHandler);
94
+ socket.write(JSON.stringify(pingRequest) + "\n");
95
+ });
96
+ }
97
+ /**
98
+ * デーモンに接続を試みる(リトライロジック付き)
99
+ */
100
+ async function connectToDaemon(socketPath, maxRetries, retryDelayMs) {
101
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
102
+ try {
103
+ const socket = net.connect(socketPath);
104
+ // 接続成功を待つ
105
+ await new Promise((resolve, reject) => {
106
+ socket.on("connect", () => resolve());
107
+ socket.on("error", (err) => reject(err));
108
+ });
109
+ return socket;
110
+ }
111
+ catch (err) {
112
+ console.error(`[Proxy] Connection attempt ${attempt}/${maxRetries} failed: ${err.message}`);
113
+ if (attempt < maxRetries) {
114
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
115
+ }
116
+ else {
117
+ throw new Error(`Failed to connect to daemon after ${maxRetries} attempts. Connection error: ${err.message}`);
118
+ }
119
+ }
120
+ }
121
+ throw new Error("Unexpected error in connectToDaemon");
122
+ }
123
+ /**
124
+ * Stdio ↔ Socket ブリッジを確立
125
+ */
126
+ function bridgeStdioToSocket(socket) {
127
+ // stdin → socket
128
+ const stdinReader = readline.createInterface({
129
+ input: process.stdin,
130
+ crlfDelay: Infinity,
131
+ });
132
+ stdinReader.on("line", (line) => {
133
+ socket.write(line + "\n");
134
+ });
135
+ stdinReader.on("close", () => {
136
+ socket.end();
137
+ });
138
+ // socket → stdout
139
+ const socketReader = readline.createInterface({
140
+ input: socket,
141
+ crlfDelay: Infinity,
142
+ });
143
+ socketReader.on("line", (line) => {
144
+ console.log(line);
145
+ });
146
+ socket.on("end", () => {
147
+ stdinReader.close();
148
+ process.exit(0);
149
+ });
150
+ socket.on("error", (err) => {
151
+ console.error(`[Proxy] Socket error: ${err.message}`);
152
+ process.exit(1);
153
+ });
154
+ }
155
+ /**
156
+ * メイン関数:プロキシを起動
157
+ */
158
+ async function main() {
159
+ const options = parseProxyArgs();
160
+ try {
161
+ // デーモンが実行中かチェック
162
+ const running = await isDaemonRunning(options.databasePath);
163
+ if (!running) {
164
+ console.error("[Proxy] Daemon not running. Starting daemon...");
165
+ // デーモンを起動
166
+ await startDaemon({
167
+ repoRoot: options.repoRoot,
168
+ databasePath: options.databasePath,
169
+ socketPath: options.socketPath,
170
+ watchMode: options.watchMode,
171
+ allowDegrade: options.allowDegrade,
172
+ securityConfigPath: options.securityConfigPath,
173
+ securityLockPath: options.securityLockPath,
174
+ });
175
+ console.error("[Proxy] Daemon started successfully");
176
+ }
177
+ // デーモンに接続
178
+ const socket = await connectToDaemon(options.socketPath, options.maxRetries, options.retryDelayMs);
179
+ // バージョン互換性をチェック
180
+ await checkDaemonVersion(socket);
181
+ console.error("[Proxy] Connected to daemon. Bridging stdio ↔ socket...");
182
+ // Stdio ↔ Socket ブリッジを確立
183
+ bridgeStdioToSocket(socket);
184
+ }
185
+ catch (err) {
186
+ const error = err;
187
+ console.error(`[Proxy] Failed to start proxy: ${error.message}`);
188
+ console.error(`[Proxy] Check daemon log at: ${options.databasePath}.daemon.log`);
189
+ console.error("[Proxy] Falling back to legacy stdio mode is not yet implemented");
190
+ process.exit(1);
191
+ }
192
+ }
193
+ // エントリーポイント
194
+ main().catch((err) => {
195
+ console.error(`[Proxy] Unhandled error: ${err}`);
196
+ process.exit(1);
197
+ });
198
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../../src/client/proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Daemon Starter Utility
3
+ *
4
+ * Responsible for spawning daemon process in detached mode and waiting for readiness.
5
+ */
6
+ /**
7
+ * デーモン起動オプション
8
+ */
9
+ export interface StartDaemonOptions {
10
+ repoRoot: string;
11
+ databasePath: string;
12
+ socketPath: string;
13
+ watchMode: boolean;
14
+ allowDegrade: boolean;
15
+ securityConfigPath?: string | undefined;
16
+ securityLockPath?: string | undefined;
17
+ }
18
+ /**
19
+ * デーモンが実行中かチェック
20
+ *
21
+ * PIDファイルの存在とプロセスの存在、ソケット接続可能性を確認
22
+ */
23
+ export declare function isDaemonRunning(databasePath: string): Promise<boolean>;
24
+ /**
25
+ * デーモンプロセスを起動
26
+ *
27
+ * デタッチモードで起動し、ソケットが準備完了するまで待つ
28
+ */
29
+ export declare function startDaemon(options: StartDaemonOptions): Promise<void>;
30
+ //# sourceMappingURL=start-daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-daemon.d.ts","sourceRoot":"","sources":["../../../src/client/start-daemon.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAsF5E;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkG5E"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Daemon Starter Utility
3
+ *
4
+ * Responsible for spawning daemon process in detached mode and waiting for readiness.
5
+ */
6
+ import { spawn } from "child_process";
7
+ import * as fs from "fs/promises";
8
+ import * as net from "net";
9
+ import * as path from "path";
10
+ import { fileURLToPath } from "url";
11
+ /**
12
+ * デーモンが実行中かチェック
13
+ *
14
+ * PIDファイルの存在とプロセスの存在、ソケット接続可能性を確認
15
+ */
16
+ export async function isDaemonRunning(databasePath) {
17
+ const pidFilePath = `${databasePath}.daemon.pid`;
18
+ const socketPath = `${databasePath}.sock`;
19
+ try {
20
+ // PIDファイルが存在するかチェック
21
+ const pidStr = await fs.readFile(pidFilePath, "utf-8");
22
+ const pid = parseInt(pidStr.trim(), 10);
23
+ // プロセスが実際に存在するかチェック
24
+ try {
25
+ process.kill(pid, 0); // シグナル0は存在チェック
26
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
27
+ }
28
+ catch (_err) {
29
+ // プロセスが存在しない場合、PIDファイルは古い
30
+ // Note: クリーンアップは意図的に行わない(デーモン起動中の競合を防ぐため)
31
+ console.error("[StartDaemon] Stale PID file detected");
32
+ return false;
33
+ }
34
+ // ソケットに接続してpingヘルスチェックを実行
35
+ try {
36
+ const socket = net.connect(socketPath);
37
+ const healthCheck = await new Promise((resolve, reject) => {
38
+ const timeout = setTimeout(() => {
39
+ socket.destroy();
40
+ reject(new Error("Health check timeout"));
41
+ }, 2000);
42
+ let responseReceived = false;
43
+ socket.on("connect", () => {
44
+ // pingリクエストを送信
45
+ const pingRequest = {
46
+ jsonrpc: "2.0",
47
+ id: 1,
48
+ method: "ping",
49
+ };
50
+ socket.write(JSON.stringify(pingRequest) + "\n");
51
+ });
52
+ socket.on("data", (data) => {
53
+ if (responseReceived)
54
+ return;
55
+ try {
56
+ const response = JSON.parse(data.toString().trim());
57
+ // 正常なpingレスポンスを確認
58
+ if (response.result && response.result.status === "ok") {
59
+ responseReceived = true;
60
+ clearTimeout(timeout);
61
+ socket.end();
62
+ resolve(true);
63
+ }
64
+ else {
65
+ clearTimeout(timeout);
66
+ socket.destroy();
67
+ reject(new Error("Invalid ping response"));
68
+ }
69
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
70
+ }
71
+ catch (_parseErr) {
72
+ clearTimeout(timeout);
73
+ socket.destroy();
74
+ reject(new Error("Failed to parse health check response"));
75
+ }
76
+ });
77
+ socket.on("error", (err) => {
78
+ clearTimeout(timeout);
79
+ reject(err);
80
+ });
81
+ });
82
+ return healthCheck;
83
+ }
84
+ catch (err) {
85
+ // ソケット接続失敗またはヘルスチェック失敗(起動中の可能性もあるため、クリーンアップは行わない)
86
+ console.error(`[StartDaemon] Daemon health check failed: ${err instanceof Error ? err.message : String(err)}`);
87
+ return false;
88
+ }
89
+ }
90
+ catch (err) {
91
+ if (err.code === "ENOENT") {
92
+ return false;
93
+ }
94
+ throw err;
95
+ }
96
+ }
97
+ /**
98
+ * デーモンプロセスを起動
99
+ *
100
+ * デタッチモードで起動し、ソケットが準備完了するまで待つ
101
+ */
102
+ export async function startDaemon(options) {
103
+ const { repoRoot, databasePath, socketPath, watchMode, allowDegrade, securityConfigPath, securityLockPath, } = options;
104
+ // デーモン実行ファイルのパスを解決
105
+ // 開発時: src/daemon/daemon.ts, ビルド後: dist/src/daemon/daemon.js
106
+ const __filename = fileURLToPath(import.meta.url);
107
+ const __dirname = path.dirname(__filename);
108
+ const daemonScriptPath = path.resolve(__dirname, "../daemon/daemon.js");
109
+ // デーモン起動引数
110
+ const args = ["--repo", repoRoot, "--db", databasePath, "--socket-path", socketPath];
111
+ if (watchMode) {
112
+ args.push("--watch");
113
+ }
114
+ if (allowDegrade) {
115
+ args.push("--allow-degrade");
116
+ }
117
+ if (securityConfigPath) {
118
+ args.push("--security-config", securityConfigPath);
119
+ }
120
+ if (securityLockPath) {
121
+ args.push("--security-lock", securityLockPath);
122
+ }
123
+ // データベースの親ディレクトリを自動作成(.kiri/ などが存在しない場合)
124
+ const dbDir = path.dirname(databasePath);
125
+ await fs.mkdir(dbDir, { recursive: true });
126
+ // デーモンログファイル
127
+ const logFilePath = `${databasePath}.daemon.log`;
128
+ const logFile = await fs.open(logFilePath, "a");
129
+ // デタッチモードでデーモンを起動
130
+ const daemon = spawn(process.execPath, [daemonScriptPath, ...args], {
131
+ detached: true,
132
+ stdio: ["ignore", logFile.fd, logFile.fd],
133
+ });
134
+ daemon.unref(); // 親プロセスがデーモンの終了を待たない
135
+ console.error(`[StartDaemon] Spawned daemon process (PID: ${daemon.pid})`);
136
+ console.error(`[StartDaemon] Daemon log: ${logFilePath}`);
137
+ // ソケットが準備完了するまで待つ(最大10秒)
138
+ const maxWaitSeconds = 10;
139
+ const pollIntervalMs = 500;
140
+ const maxAttempts = (maxWaitSeconds * 1000) / pollIntervalMs;
141
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
142
+ try {
143
+ // ソケット接続を試みる
144
+ const socket = net.connect(socketPath);
145
+ await new Promise((resolve, reject) => {
146
+ const timeout = setTimeout(() => {
147
+ socket.destroy();
148
+ reject(new Error("Socket connection timeout"));
149
+ }, pollIntervalMs);
150
+ socket.on("connect", () => {
151
+ clearTimeout(timeout);
152
+ socket.end();
153
+ resolve();
154
+ });
155
+ socket.on("error", (err) => {
156
+ clearTimeout(timeout);
157
+ reject(err);
158
+ });
159
+ });
160
+ // 接続成功
161
+ console.error("[StartDaemon] Daemon is ready");
162
+ await logFile.close();
163
+ return;
164
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
165
+ }
166
+ catch (_err) {
167
+ // まだ準備できていない、再試行
168
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
169
+ }
170
+ }
171
+ // タイムアウト
172
+ await logFile.close();
173
+ throw new Error(`Daemon did not become ready within ${maxWaitSeconds} seconds. Check log: ${logFilePath}`);
174
+ }
175
+ //# sourceMappingURL=start-daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-daemon.js","sourceRoot":"","sources":["../../../src/client/start-daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * KIRI Daemon Main Process
4
+ *
5
+ * Single daemon per database, handles multiple client connections via Unix socket.
6
+ * Manages DuckDB connection, watch mode, and graceful lifecycle.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../../src/daemon/daemon.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}