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.
- package/LICENSE +21 -0
- package/README.md +399 -0
- package/config/default.example.yml +12 -0
- package/config/denylist.yml +15 -0
- package/config/scoring-profiles.yml +37 -0
- package/config/security.yml +10 -0
- package/dist/client/cli.js +68 -0
- package/dist/client/cli.js.map +1 -0
- package/dist/client/index.js +5 -0
- package/dist/client/index.js.map +1 -0
- package/dist/config/default.example.yml +12 -0
- package/dist/config/denylist.yml +15 -0
- package/dist/config/scoring-profiles.yml +37 -0
- package/dist/config/security.yml +10 -0
- package/dist/eval/metrics.js +47 -0
- package/dist/eval/metrics.js.map +1 -0
- package/dist/indexer/cli.js +362 -0
- package/dist/indexer/cli.js.map +1 -0
- package/dist/indexer/codeintel.js +182 -0
- package/dist/indexer/codeintel.js.map +1 -0
- package/dist/indexer/git.js +30 -0
- package/dist/indexer/git.js.map +1 -0
- package/dist/indexer/language.js +34 -0
- package/dist/indexer/language.js.map +1 -0
- package/dist/indexer/pipeline/filters/denylist.js +71 -0
- package/dist/indexer/pipeline/filters/denylist.js.map +1 -0
- package/dist/indexer/schema.js +101 -0
- package/dist/indexer/schema.js.map +1 -0
- package/dist/package.json +93 -0
- package/dist/server/bootstrap.js +19 -0
- package/dist/server/bootstrap.js.map +1 -0
- package/dist/server/context.js +2 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/fallbacks/degradeController.js +69 -0
- package/dist/server/fallbacks/degradeController.js.map +1 -0
- package/dist/server/handlers.js +800 -0
- package/dist/server/handlers.js.map +1 -0
- package/dist/server/main.js +151 -0
- package/dist/server/main.js.map +1 -0
- package/dist/server/observability/metrics.js +56 -0
- package/dist/server/observability/metrics.js.map +1 -0
- package/dist/server/observability/tracing.js +58 -0
- package/dist/server/observability/tracing.js.map +1 -0
- package/dist/server/rpc.js +477 -0
- package/dist/server/rpc.js.map +1 -0
- package/dist/server/runtime.js +47 -0
- package/dist/server/runtime.js.map +1 -0
- package/dist/server/scoring.js +111 -0
- package/dist/server/scoring.js.map +1 -0
- package/dist/server/stdio.js +76 -0
- package/dist/server/stdio.js.map +1 -0
- package/dist/shared/duckdb.js +121 -0
- package/dist/shared/duckdb.js.map +1 -0
- package/dist/shared/embedding.js +85 -0
- package/dist/shared/embedding.js.map +1 -0
- package/dist/shared/index.js +9 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/security/config.js +64 -0
- package/dist/shared/security/config.js.map +1 -0
- package/dist/shared/security/masker.js +56 -0
- package/dist/shared/security/masker.js.map +1 -0
- package/dist/shared/tokenizer.js +5 -0
- package/dist/shared/tokenizer.js.map +1 -0
- package/dist/shared/utils/simpleYaml.js +90 -0
- package/dist/shared/utils/simpleYaml.js.map +1 -0
- package/dist/sql/schema.sql +6 -0
- package/dist/src/client/cli.d.ts +3 -0
- package/dist/src/client/cli.d.ts.map +1 -0
- package/dist/src/client/cli.js +68 -0
- package/dist/src/client/cli.js.map +1 -0
- package/dist/src/client/index.d.ts +5 -0
- package/dist/src/client/index.d.ts.map +1 -0
- package/dist/src/client/index.js +5 -0
- package/dist/src/client/index.js.map +1 -0
- package/dist/src/client/proxy.d.ts +9 -0
- package/dist/src/client/proxy.d.ts.map +1 -0
- package/dist/src/client/proxy.js +198 -0
- package/dist/src/client/proxy.js.map +1 -0
- package/dist/src/client/start-daemon.d.ts +30 -0
- package/dist/src/client/start-daemon.d.ts.map +1 -0
- package/dist/src/client/start-daemon.js +175 -0
- package/dist/src/client/start-daemon.js.map +1 -0
- package/dist/src/daemon/daemon.d.ts +9 -0
- package/dist/src/daemon/daemon.d.ts.map +1 -0
- package/dist/src/daemon/daemon.js +149 -0
- package/dist/src/daemon/daemon.js.map +1 -0
- package/dist/src/daemon/lifecycle.d.ts +101 -0
- package/dist/src/daemon/lifecycle.d.ts.map +1 -0
- package/dist/src/daemon/lifecycle.js +266 -0
- package/dist/src/daemon/lifecycle.js.map +1 -0
- package/dist/src/daemon/socket.d.ts +26 -0
- package/dist/src/daemon/socket.d.ts.map +1 -0
- package/dist/src/daemon/socket.js +132 -0
- package/dist/src/daemon/socket.js.map +1 -0
- package/dist/src/eval/metrics.d.ts +23 -0
- package/dist/src/eval/metrics.d.ts.map +1 -0
- package/dist/src/eval/metrics.js +47 -0
- package/dist/src/eval/metrics.js.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +11 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/indexer/cli.d.ts +9 -0
- package/dist/src/indexer/cli.d.ts.map +1 -0
- package/dist/src/indexer/cli.js +402 -0
- package/dist/src/indexer/cli.js.map +1 -0
- package/dist/src/indexer/codeintel.d.ts +28 -0
- package/dist/src/indexer/codeintel.d.ts.map +1 -0
- package/dist/src/indexer/codeintel.js +451 -0
- package/dist/src/indexer/codeintel.js.map +1 -0
- package/dist/src/indexer/git.d.ts +4 -0
- package/dist/src/indexer/git.d.ts.map +1 -0
- package/dist/src/indexer/git.js +30 -0
- package/dist/src/indexer/git.js.map +1 -0
- package/dist/src/indexer/language.d.ts +2 -0
- package/dist/src/indexer/language.d.ts.map +1 -0
- package/dist/src/indexer/language.js +34 -0
- package/dist/src/indexer/language.js.map +1 -0
- package/dist/src/indexer/pipeline/filters/denylist.d.ts +10 -0
- package/dist/src/indexer/pipeline/filters/denylist.d.ts.map +1 -0
- package/dist/src/indexer/pipeline/filters/denylist.js +71 -0
- package/dist/src/indexer/pipeline/filters/denylist.js.map +1 -0
- package/dist/src/indexer/schema.d.ts +9 -0
- package/dist/src/indexer/schema.d.ts.map +1 -0
- package/dist/src/indexer/schema.js +125 -0
- package/dist/src/indexer/schema.js.map +1 -0
- package/dist/src/indexer/watch.d.ts +97 -0
- package/dist/src/indexer/watch.d.ts.map +1 -0
- package/dist/src/indexer/watch.js +264 -0
- package/dist/src/indexer/watch.js.map +1 -0
- package/dist/src/server/bootstrap.d.ts +11 -0
- package/dist/src/server/bootstrap.d.ts.map +1 -0
- package/dist/src/server/bootstrap.js +19 -0
- package/dist/src/server/bootstrap.js.map +1 -0
- package/dist/src/server/context.d.ts +9 -0
- package/dist/src/server/context.d.ts.map +1 -0
- package/dist/src/server/context.js +2 -0
- package/dist/src/server/context.js.map +1 -0
- package/dist/src/server/fallbacks/degradeController.d.ts +24 -0
- package/dist/src/server/fallbacks/degradeController.d.ts.map +1 -0
- package/dist/src/server/fallbacks/degradeController.js +135 -0
- package/dist/src/server/fallbacks/degradeController.js.map +1 -0
- package/dist/src/server/handlers.d.ts +105 -0
- package/dist/src/server/handlers.d.ts.map +1 -0
- package/dist/src/server/handlers.js +954 -0
- package/dist/src/server/handlers.js.map +1 -0
- package/dist/src/server/indexBootstrap.d.ts +13 -0
- package/dist/src/server/indexBootstrap.d.ts.map +1 -0
- package/dist/src/server/indexBootstrap.js +109 -0
- package/dist/src/server/indexBootstrap.js.map +1 -0
- package/dist/src/server/main.d.ts +10 -0
- package/dist/src/server/main.d.ts.map +1 -0
- package/dist/src/server/main.js +217 -0
- package/dist/src/server/main.js.map +1 -0
- package/dist/src/server/observability/metrics.d.ts +35 -0
- package/dist/src/server/observability/metrics.d.ts.map +1 -0
- package/dist/src/server/observability/metrics.js +70 -0
- package/dist/src/server/observability/metrics.js.map +1 -0
- package/dist/src/server/observability/tracing.d.ts +3 -0
- package/dist/src/server/observability/tracing.d.ts.map +1 -0
- package/dist/src/server/observability/tracing.js +58 -0
- package/dist/src/server/observability/tracing.js.map +1 -0
- package/dist/src/server/rpc.d.ts +39 -0
- package/dist/src/server/rpc.d.ts.map +1 -0
- package/dist/src/server/rpc.js +551 -0
- package/dist/src/server/rpc.js.map +1 -0
- package/dist/src/server/runtime.d.ts +21 -0
- package/dist/src/server/runtime.d.ts.map +1 -0
- package/dist/src/server/runtime.js +59 -0
- package/dist/src/server/runtime.js.map +1 -0
- package/dist/src/server/scoring.d.ts +20 -0
- package/dist/src/server/scoring.d.ts.map +1 -0
- package/dist/src/server/scoring.js +112 -0
- package/dist/src/server/scoring.js.map +1 -0
- package/dist/src/server/stdio.d.ts +4 -0
- package/dist/src/server/stdio.d.ts.map +1 -0
- package/dist/src/server/stdio.js +88 -0
- package/dist/src/server/stdio.js.map +1 -0
- package/dist/src/shared/duckdb.d.ts +16 -0
- package/dist/src/shared/duckdb.d.ts.map +1 -0
- package/dist/src/shared/duckdb.js +121 -0
- package/dist/src/shared/duckdb.js.map +1 -0
- package/dist/src/shared/embedding.d.ts +19 -0
- package/dist/src/shared/embedding.d.ts.map +1 -0
- package/dist/src/shared/embedding.js +85 -0
- package/dist/src/shared/embedding.js.map +1 -0
- package/dist/src/shared/index.d.ts +3 -0
- package/dist/src/shared/index.d.ts.map +1 -0
- package/dist/src/shared/index.js +9 -0
- package/dist/src/shared/index.js.map +1 -0
- package/dist/src/shared/security/config.d.ts +23 -0
- package/dist/src/shared/security/config.d.ts.map +1 -0
- package/dist/src/shared/security/config.js +66 -0
- package/dist/src/shared/security/config.js.map +1 -0
- package/dist/src/shared/security/masker.d.ts +10 -0
- package/dist/src/shared/security/masker.d.ts.map +1 -0
- package/dist/src/shared/security/masker.js +56 -0
- package/dist/src/shared/security/masker.js.map +1 -0
- package/dist/src/shared/tokenizer.d.ts +2 -0
- package/dist/src/shared/tokenizer.d.ts.map +1 -0
- package/dist/src/shared/tokenizer.js +5 -0
- package/dist/src/shared/tokenizer.js.map +1 -0
- package/dist/src/shared/utils/lockfile.d.ts +46 -0
- package/dist/src/shared/utils/lockfile.d.ts.map +1 -0
- package/dist/src/shared/utils/lockfile.js +136 -0
- package/dist/src/shared/utils/lockfile.js.map +1 -0
- package/dist/src/shared/utils/simpleYaml.d.ts +6 -0
- package/dist/src/shared/utils/simpleYaml.d.ts.map +1 -0
- package/dist/src/shared/utils/simpleYaml.js +90 -0
- package/dist/src/shared/utils/simpleYaml.js.map +1 -0
- package/package.json +91 -0
- package/sql/schema.sql +6 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { parseSimpleYaml } from "../utils/simpleYaml.js";
|
|
7
|
+
/**
|
|
8
|
+
* セキュリティ設定のスキーマ定義(Zodによる型安全な検証)
|
|
9
|
+
*/
|
|
10
|
+
const SecurityConfigSchema = z.object({
|
|
11
|
+
allowed_paths: z.array(z.string()).min(1, "At least one allowed path required"),
|
|
12
|
+
allow_network_egress: z.boolean(),
|
|
13
|
+
allow_subprocess: z.boolean(),
|
|
14
|
+
sensitive_tokens: z.array(z.string()),
|
|
15
|
+
});
|
|
16
|
+
export function loadSecurityConfig(configPath) {
|
|
17
|
+
const path = configPath ?? join(fileURLToPath(import.meta.url), "../../../../config/security.yml");
|
|
18
|
+
const content = readFileSync(path, "utf8");
|
|
19
|
+
const parsed = parseSimpleYaml(content);
|
|
20
|
+
// Zodによるスキーマ検証(手動アサーションを置き換え)
|
|
21
|
+
const result = SecurityConfigSchema.safeParse(parsed);
|
|
22
|
+
if (!result.success) {
|
|
23
|
+
const errors = result.error.issues.map((i) => i.message).join(", ");
|
|
24
|
+
throw new Error(`Security configuration is invalid. Fix the following errors: ${errors}`);
|
|
25
|
+
}
|
|
26
|
+
const hash = createHash("sha256").update(content).digest("hex");
|
|
27
|
+
return { config: result.data, hash };
|
|
28
|
+
}
|
|
29
|
+
export function readSecurityLock(lockPath) {
|
|
30
|
+
try {
|
|
31
|
+
return readFileSync(resolve(lockPath ?? "var/security.lock"), "utf8").trim();
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function evaluateSecurityStatus(configPath, lockPath) {
|
|
38
|
+
const { config, hash } = loadSecurityConfig(configPath);
|
|
39
|
+
const stored = readSecurityLock(lockPath);
|
|
40
|
+
const defaultConfigPath = join(fileURLToPath(import.meta.url), "../../../../config/security.yml");
|
|
41
|
+
return {
|
|
42
|
+
config,
|
|
43
|
+
configPath: configPath ?? defaultConfigPath,
|
|
44
|
+
lockPath: resolve(lockPath ?? "var/security.lock"),
|
|
45
|
+
hash,
|
|
46
|
+
lockHash: stored,
|
|
47
|
+
matches: stored === null ? false : stored === hash,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export function assertSecurityBaseline(configPath, lockPath) {
|
|
51
|
+
const status = evaluateSecurityStatus(configPath, lockPath);
|
|
52
|
+
if (!status.lockHash) {
|
|
53
|
+
throw new Error(`Security lock is missing at ${status.lockPath}. Establish baseline by running 'pnpm exec tsx src/client/cli.ts security verify --write-lock'.`);
|
|
54
|
+
}
|
|
55
|
+
if (!status.matches) {
|
|
56
|
+
throw new Error(`Security configuration at ${status.configPath} does not match lock hash. Review configuration changes before proceeding.`);
|
|
57
|
+
}
|
|
58
|
+
return status;
|
|
59
|
+
}
|
|
60
|
+
export function updateSecurityLock(hash, lockPath) {
|
|
61
|
+
const path = resolve(lockPath ?? "var/security.lock");
|
|
62
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
63
|
+
writeFileSync(path, `${hash}\n`, "utf8");
|
|
64
|
+
return path;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/shared/security/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAkBzD;;GAEG;AACH,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,oCAAoC,CAAC;IAC/E,oBAAoB,EAAE,CAAC,CAAC,OAAO,EAAE;IACjC,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE;IAC7B,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CACtC,CAAC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,UAAmB;IACpD,MAAM,IAAI,GACR,UAAU,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,iCAAiC,CAAC,CAAC;IACxF,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAExC,8BAA8B;IAC9B,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,gEAAgE,MAAM,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAiB;IAChD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,OAAO,CAAC,QAAQ,IAAI,mBAAmB,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAmB,EAAE,QAAiB;IAC3E,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,iCAAiC,CAAC,CAAC;IAClG,OAAO;QACL,MAAM;QACN,UAAU,EAAE,UAAU,IAAI,iBAAiB;QAC3C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,mBAAmB,CAAC;QAClD,IAAI;QACJ,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI;KACnD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAmB,EAAE,QAAiB;IAC3E,MAAM,MAAM,GAAG,sBAAsB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,+BAA+B,MAAM,CAAC,QAAQ,iGAAiG,CAChJ,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,6BAA6B,MAAM,CAAC,UAAU,4EAA4E,CAC3H,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,QAAiB;IAChE,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,IAAI,mBAAmB,CAAC,CAAC;IACtD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface MaskingOptions {
|
|
2
|
+
tokens: string[];
|
|
3
|
+
replacement?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface MaskResult<T> {
|
|
6
|
+
masked: T;
|
|
7
|
+
applied: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function maskValue(value: unknown, options: MaskingOptions): MaskResult<unknown>;
|
|
10
|
+
//# sourceMappingURL=masker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masker.d.ts","sourceRoot":"","sources":["../../../../src/shared/security/masker.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,MAAM,EAAE,CAAC,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;CACjB;AAkCD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,CAuBtF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* トークンパターンの妥当性を検証してReDoS攻撃を防ぐ
|
|
3
|
+
* @param token 検証対象のトークン文字列
|
|
4
|
+
* @throws パターンが長すぎる、またはネストした量指定子を含む場合
|
|
5
|
+
*/
|
|
6
|
+
function validateTokenPattern(token) {
|
|
7
|
+
if (token.length > 100) {
|
|
8
|
+
throw new Error("Token pattern exceeds maximum length. Use shorter patterns.");
|
|
9
|
+
}
|
|
10
|
+
// ネストした量指定子による壊滅的バックトラッキングを防ぐ
|
|
11
|
+
if (/(\*|\+|\{)\s*(\*|\+|\{)/.test(token)) {
|
|
12
|
+
throw new Error("Invalid pattern contains nested quantifiers. Simplify the pattern.");
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function maskString(input, tokens, replacement) {
|
|
16
|
+
let applied = 0;
|
|
17
|
+
let output = input;
|
|
18
|
+
for (const token of tokens) {
|
|
19
|
+
if (!token)
|
|
20
|
+
continue;
|
|
21
|
+
validateTokenPattern(token); // ReDoS対策の検証を追加
|
|
22
|
+
const escaped = token.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
23
|
+
const pattern = new RegExp(escaped, "g");
|
|
24
|
+
const matches = output.match(pattern);
|
|
25
|
+
if (matches && matches.length > 0) {
|
|
26
|
+
applied += matches.length;
|
|
27
|
+
output = output.replace(pattern, replacement);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { masked: output, applied };
|
|
31
|
+
}
|
|
32
|
+
export function maskValue(value, options) {
|
|
33
|
+
if (typeof value === "string") {
|
|
34
|
+
return maskString(value, options.tokens, options.replacement ?? "***");
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(value)) {
|
|
37
|
+
let applied = 0;
|
|
38
|
+
const maskedArray = value.map((item) => {
|
|
39
|
+
const result = maskValue(item, options);
|
|
40
|
+
applied += result.applied;
|
|
41
|
+
return result.masked;
|
|
42
|
+
});
|
|
43
|
+
return { masked: maskedArray, applied };
|
|
44
|
+
}
|
|
45
|
+
if (value && typeof value === "object") {
|
|
46
|
+
let applied = 0;
|
|
47
|
+
const entries = Object.entries(value).map(([key, item]) => {
|
|
48
|
+
const result = maskValue(item, options);
|
|
49
|
+
applied += result.applied;
|
|
50
|
+
return [key, result.masked];
|
|
51
|
+
});
|
|
52
|
+
return { masked: Object.fromEntries(entries), applied };
|
|
53
|
+
}
|
|
54
|
+
return { masked: value, applied: 0 };
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=masker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masker.js","sourceRoot":"","sources":["../../../../src/shared/security/masker.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,KAAa;IACzC,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IACD,8BAA8B;IAC9B,IAAI,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,MAAgB,EAAE,WAAmB;IACtE,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB;QAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;YAC1B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,OAAuB;IAC/D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACxC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC;YAC1B,OAAO,MAAM,CAAC,MAAM,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;IAC1C,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE;YACnF,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACxC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC;YAC1B,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../../src/shared/tokenizer.ts"],"names":[],"mappings":"AAAA,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAG7C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../../src/shared/tokenizer.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lockfile management for preventing concurrent indexing operations.
|
|
3
|
+
*
|
|
4
|
+
* Uses atomic file creation (wx flag) to ensure only one process acquires the lock.
|
|
5
|
+
* Lock files contain the PID of the owning process for debugging.
|
|
6
|
+
*
|
|
7
|
+
* Features stale lock detection: If a lock file exists but the owning process
|
|
8
|
+
* is no longer running, the lock is automatically removed and reacquired.
|
|
9
|
+
*/
|
|
10
|
+
export declare class LockfileError extends Error {
|
|
11
|
+
readonly lockfilePath: string;
|
|
12
|
+
readonly ownerPid?: number | undefined;
|
|
13
|
+
constructor(message: string, lockfilePath: string, ownerPid?: number | undefined);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Attempts to acquire a lock file atomically.
|
|
17
|
+
*
|
|
18
|
+
* If lock exists but owning process is dead, removes stale lock and retries.
|
|
19
|
+
*
|
|
20
|
+
* @param lockfilePath - Path to the lock file (e.g., "/path/to/db.duckdb.lock")
|
|
21
|
+
* @throws {LockfileError} If the lock is already held by another running process
|
|
22
|
+
*/
|
|
23
|
+
export declare function acquireLock(lockfilePath: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* Releases a previously acquired lock file.
|
|
26
|
+
*
|
|
27
|
+
* Silently succeeds if the lock file doesn't exist (idempotent).
|
|
28
|
+
*
|
|
29
|
+
* @param lockfilePath - Path to the lock file to release
|
|
30
|
+
*/
|
|
31
|
+
export declare function releaseLock(lockfilePath: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Checks if a lock file currently exists.
|
|
34
|
+
*
|
|
35
|
+
* @param lockfilePath - Path to the lock file to check
|
|
36
|
+
* @returns true if lock file exists, false otherwise
|
|
37
|
+
*/
|
|
38
|
+
export declare function isLocked(lockfilePath: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Gets the PID of the process that owns the lock file.
|
|
41
|
+
*
|
|
42
|
+
* @param lockfilePath - Path to the lock file to check
|
|
43
|
+
* @returns PID of the owning process, or null if file doesn't exist or can't be read
|
|
44
|
+
*/
|
|
45
|
+
export declare function getLockOwner(lockfilePath: string): number | null;
|
|
46
|
+
//# sourceMappingURL=lockfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../../../../src/shared/utils/lockfile.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,qBAAa,aAAc,SAAQ,KAAK;aAGpB,YAAY,EAAE,MAAM;aACpB,QAAQ,CAAC,EAAE,MAAM;gBAFjC,OAAO,EAAE,MAAM,EACC,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,YAAA;CAKpC;AAmBD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CA0DtD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAStD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWhE"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
/**
|
|
3
|
+
* Lockfile management for preventing concurrent indexing operations.
|
|
4
|
+
*
|
|
5
|
+
* Uses atomic file creation (wx flag) to ensure only one process acquires the lock.
|
|
6
|
+
* Lock files contain the PID of the owning process for debugging.
|
|
7
|
+
*
|
|
8
|
+
* Features stale lock detection: If a lock file exists but the owning process
|
|
9
|
+
* is no longer running, the lock is automatically removed and reacquired.
|
|
10
|
+
*/
|
|
11
|
+
export class LockfileError extends Error {
|
|
12
|
+
lockfilePath;
|
|
13
|
+
ownerPid;
|
|
14
|
+
constructor(message, lockfilePath, ownerPid) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.lockfilePath = lockfilePath;
|
|
17
|
+
this.ownerPid = ownerPid;
|
|
18
|
+
this.name = "LockfileError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Checks if a process with the given PID is currently running.
|
|
23
|
+
*
|
|
24
|
+
* @param pid - Process ID to check
|
|
25
|
+
* @returns true if process exists, false otherwise
|
|
26
|
+
*/
|
|
27
|
+
function isProcessRunning(pid) {
|
|
28
|
+
try {
|
|
29
|
+
// Signal 0 doesn't kill the process, just checks if it exists
|
|
30
|
+
process.kill(pid, 0);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// ESRCH means process doesn't exist
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Attempts to acquire a lock file atomically.
|
|
40
|
+
*
|
|
41
|
+
* If lock exists but owning process is dead, removes stale lock and retries.
|
|
42
|
+
*
|
|
43
|
+
* @param lockfilePath - Path to the lock file (e.g., "/path/to/db.duckdb.lock")
|
|
44
|
+
* @throws {LockfileError} If the lock is already held by another running process
|
|
45
|
+
*/
|
|
46
|
+
export function acquireLock(lockfilePath) {
|
|
47
|
+
try {
|
|
48
|
+
writeFileSync(lockfilePath, String(process.pid), { flag: "wx" });
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const err = error;
|
|
52
|
+
if (err.code === "EEXIST") {
|
|
53
|
+
// Check if lock is stale (owning process is dead)
|
|
54
|
+
try {
|
|
55
|
+
const existingPidStr = readFileSync(lockfilePath, "utf8");
|
|
56
|
+
const existingPid = parseInt(existingPidStr, 10);
|
|
57
|
+
if (!isNaN(existingPid) && !isProcessRunning(existingPid)) {
|
|
58
|
+
// Stale lock detected - double-check before removing to prevent PID reuse race
|
|
59
|
+
process.stderr.write(`⚠️ Removing stale lock file (PID ${existingPid} not running)\n`);
|
|
60
|
+
// Re-verify PID hasn't been reused (TOCTOU mitigation)
|
|
61
|
+
if (existsSync(lockfilePath)) {
|
|
62
|
+
const recheckPidStr = readFileSync(lockfilePath, "utf8");
|
|
63
|
+
const recheckPid = parseInt(recheckPidStr, 10);
|
|
64
|
+
// Only remove if PID still matches and process still dead
|
|
65
|
+
if (!isNaN(recheckPid) && recheckPid === existingPid && !isProcessRunning(recheckPid)) {
|
|
66
|
+
unlinkSync(lockfilePath);
|
|
67
|
+
// Retry acquisition (should succeed now)
|
|
68
|
+
writeFileSync(lockfilePath, String(process.pid), { flag: "wx" });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Lock file changed or PID was reused - throw error
|
|
73
|
+
throw new LockfileError(`Lock file changed during stale check. Another process may be active.`, lockfilePath, existingPid);
|
|
74
|
+
}
|
|
75
|
+
// Lock is held by a running process
|
|
76
|
+
throw new LockfileError(`Lock file already exists. Another process is indexing.`, lockfilePath, existingPid);
|
|
77
|
+
}
|
|
78
|
+
catch (lockError) {
|
|
79
|
+
// If it's already a LockfileError, rethrow it
|
|
80
|
+
if (lockError instanceof LockfileError) {
|
|
81
|
+
throw lockError;
|
|
82
|
+
}
|
|
83
|
+
// If we can't read the PID, treat as active lock for safety
|
|
84
|
+
throw new LockfileError(`Lock file already exists. Another process may be indexing.`, lockfilePath);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Releases a previously acquired lock file.
|
|
92
|
+
*
|
|
93
|
+
* Silently succeeds if the lock file doesn't exist (idempotent).
|
|
94
|
+
*
|
|
95
|
+
* @param lockfilePath - Path to the lock file to release
|
|
96
|
+
*/
|
|
97
|
+
export function releaseLock(lockfilePath) {
|
|
98
|
+
try {
|
|
99
|
+
if (existsSync(lockfilePath)) {
|
|
100
|
+
unlinkSync(lockfilePath);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Ignore errors during cleanup - lock may have been manually removed
|
|
105
|
+
// or process killed before lock was created
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Checks if a lock file currently exists.
|
|
110
|
+
*
|
|
111
|
+
* @param lockfilePath - Path to the lock file to check
|
|
112
|
+
* @returns true if lock file exists, false otherwise
|
|
113
|
+
*/
|
|
114
|
+
export function isLocked(lockfilePath) {
|
|
115
|
+
return existsSync(lockfilePath);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Gets the PID of the process that owns the lock file.
|
|
119
|
+
*
|
|
120
|
+
* @param lockfilePath - Path to the lock file to check
|
|
121
|
+
* @returns PID of the owning process, or null if file doesn't exist or can't be read
|
|
122
|
+
*/
|
|
123
|
+
export function getLockOwner(lockfilePath) {
|
|
124
|
+
try {
|
|
125
|
+
if (existsSync(lockfilePath)) {
|
|
126
|
+
const pidStr = readFileSync(lockfilePath, "utf8");
|
|
127
|
+
const pid = parseInt(pidStr, 10);
|
|
128
|
+
return isNaN(pid) ? null : pid;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=lockfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../../../src/shared/utils/lockfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface SimpleYamlObject {
|
|
2
|
+
[key: string]: SimpleYamlValue;
|
|
3
|
+
}
|
|
4
|
+
export type SimpleYamlValue = string | number | boolean | null | SimpleYamlValue[] | SimpleYamlObject;
|
|
5
|
+
export declare function parseSimpleYaml(content: string): Record<string, SimpleYamlValue>;
|
|
6
|
+
//# sourceMappingURL=simpleYaml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simpleYaml.d.ts","sourceRoot":"","sources":["../../../../src/shared/utils/simpleYaml.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;CAChC;AAED,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,eAAe,EAAE,GACjB,gBAAgB,CAAC;AAmCrB,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CA6DhF"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
function parseScalar(value) {
|
|
2
|
+
let trimmed = value.trim();
|
|
3
|
+
const commentIndex = trimmed.indexOf(" #");
|
|
4
|
+
if (commentIndex >= 0) {
|
|
5
|
+
trimmed = trimmed.slice(0, commentIndex).trim();
|
|
6
|
+
}
|
|
7
|
+
if (trimmed === "true")
|
|
8
|
+
return true;
|
|
9
|
+
if (trimmed === "false")
|
|
10
|
+
return false;
|
|
11
|
+
if (trimmed === "null")
|
|
12
|
+
return null;
|
|
13
|
+
if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
|
|
14
|
+
return Number(trimmed);
|
|
15
|
+
}
|
|
16
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
17
|
+
return trimmed.slice(1, -1);
|
|
18
|
+
}
|
|
19
|
+
if (trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
20
|
+
return trimmed.slice(1, -1);
|
|
21
|
+
}
|
|
22
|
+
return trimmed;
|
|
23
|
+
}
|
|
24
|
+
function ensureObject(value) {
|
|
25
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
26
|
+
throw new Error("Expected mapping");
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
export function parseSimpleYaml(content) {
|
|
31
|
+
const root = {};
|
|
32
|
+
const lines = content.split(/\r?\n/);
|
|
33
|
+
const stack = [{ indent: -1, value: root }];
|
|
34
|
+
for (let index = 0; index < lines.length; index++) {
|
|
35
|
+
const rawLine = lines[index];
|
|
36
|
+
if (!rawLine || /^\s*$/.test(rawLine) || /^\s*#/.test(rawLine)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const indentMatch = rawLine.match(/^\s*/);
|
|
40
|
+
const indent = indentMatch?.[0]?.length ?? 0;
|
|
41
|
+
const line = rawLine.trim();
|
|
42
|
+
while (stack.length > 0) {
|
|
43
|
+
const last = stack[stack.length - 1];
|
|
44
|
+
if (!last || indent <= last.indent) {
|
|
45
|
+
stack.pop();
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const parent = stack[stack.length - 1];
|
|
52
|
+
if (!parent) {
|
|
53
|
+
throw new Error("Invalid YAML structure: no parent context");
|
|
54
|
+
}
|
|
55
|
+
const container = parent.value;
|
|
56
|
+
if (line.startsWith("- ")) {
|
|
57
|
+
if (!Array.isArray(container)) {
|
|
58
|
+
throw new Error("List item without array context");
|
|
59
|
+
}
|
|
60
|
+
container.push(parseScalar(line.slice(2)));
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const separatorIndex = line.indexOf(":");
|
|
64
|
+
if (separatorIndex === -1) {
|
|
65
|
+
throw new Error(`Invalid YAML line: ${line}`);
|
|
66
|
+
}
|
|
67
|
+
const key = line.slice(0, separatorIndex).trim();
|
|
68
|
+
const remainder = line.slice(separatorIndex + 1);
|
|
69
|
+
const target = ensureObject(container);
|
|
70
|
+
if (remainder.trim().length === 0) {
|
|
71
|
+
const nextLine = lines[index + 1];
|
|
72
|
+
const isList = nextLine ? nextLine.trim().startsWith("- ") : false;
|
|
73
|
+
if (isList) {
|
|
74
|
+
const arr = [];
|
|
75
|
+
target[key] = arr;
|
|
76
|
+
stack.push({ indent, value: arr });
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const obj = {};
|
|
80
|
+
target[key] = obj;
|
|
81
|
+
stack.push({ indent, value: obj });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
target[key] = parseScalar(remainder);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return root;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=simpleYaml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simpleYaml.js","sourceRoot":"","sources":["../../../../src/shared/utils/simpleYaml.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kiri-mcp-server",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "KIRI context extraction platform",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/src/index.js",
|
|
7
|
+
"module": "./dist/src/index.js",
|
|
8
|
+
"types": "./dist/src/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/src/index.d.ts",
|
|
12
|
+
"import": "./dist/src/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"kiri": "./dist/src/client/proxy.js",
|
|
18
|
+
"kiri-server": "./dist/src/server/main.js",
|
|
19
|
+
"kiri-daemon": "./dist/src/daemon/daemon.js"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist/",
|
|
23
|
+
"config/",
|
|
24
|
+
"sql/"
|
|
25
|
+
],
|
|
26
|
+
"keywords": [
|
|
27
|
+
"mcp",
|
|
28
|
+
"duckdb",
|
|
29
|
+
"context",
|
|
30
|
+
"llm",
|
|
31
|
+
"code-search",
|
|
32
|
+
"indexer"
|
|
33
|
+
],
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"author": "CAPHTECH",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/CAPHTECH/kiri.git"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/CAPHTECH/kiri/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/CAPHTECH/kiri#readme",
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20.0.0"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"chokidar": "^4.0.3",
|
|
52
|
+
"duckdb": "^1.1.0",
|
|
53
|
+
"gpt-tokenizer": "^3.2.0",
|
|
54
|
+
"tree-sitter": "^0.22.0",
|
|
55
|
+
"tree-sitter-swift": "0.7.1",
|
|
56
|
+
"typescript": "^5.6.3",
|
|
57
|
+
"yaml": "^2.8.1",
|
|
58
|
+
"zod": "^4.1.12"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^22.7.4",
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
63
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
64
|
+
"@vitest/coverage-v8": "^2.0.0",
|
|
65
|
+
"eslint": "^9.9.0",
|
|
66
|
+
"eslint-config-prettier": "^9.1.0",
|
|
67
|
+
"eslint-plugin-import": "^2.29.1",
|
|
68
|
+
"prettier": "^3.3.3",
|
|
69
|
+
"lint-staged": "^15.2.10",
|
|
70
|
+
"simple-git-hooks": "^2.10.0",
|
|
71
|
+
"tsx": "^4.16.5",
|
|
72
|
+
"vitest": "^2.0.5"
|
|
73
|
+
},
|
|
74
|
+
"simple-git-hooks": {
|
|
75
|
+
"pre-commit": "pnpm exec lint-staged"
|
|
76
|
+
},
|
|
77
|
+
"lint-staged": {
|
|
78
|
+
"*.{ts,tsx,json,md,yml}": [
|
|
79
|
+
"pnpm exec prettier --write"
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
"scripts": {
|
|
83
|
+
"bootstrap": "pnpm install",
|
|
84
|
+
"build": "tsc --project tsconfig.build.json && pnpm run build:copy-assets",
|
|
85
|
+
"build:copy-assets": "tsx scripts/build/copy-assets.ts",
|
|
86
|
+
"dev": "tsx src/server/main.ts --port 8765",
|
|
87
|
+
"lint": "eslint \"{src,tests,scripts}/**/*.{ts,tsx}\" && prettier --check \"**/*.{ts,tsx,json,md,yml}\"",
|
|
88
|
+
"test": "vitest run --coverage",
|
|
89
|
+
"check": "pnpm run lint && pnpm run test"
|
|
90
|
+
}
|
|
91
|
+
}
|