@knowledgine/ingest 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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cursor-store.d.ts +11 -0
  3. package/dist/cursor-store.d.ts.map +1 -0
  4. package/dist/cursor-store.js +42 -0
  5. package/dist/cursor-store.js.map +1 -0
  6. package/dist/event-writer.d.ts +18 -0
  7. package/dist/event-writer.d.ts.map +1 -0
  8. package/dist/event-writer.js +50 -0
  9. package/dist/event-writer.js.map +1 -0
  10. package/dist/index.d.ts +12 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +11 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/ingest-engine.d.ts +20 -0
  15. package/dist/ingest-engine.d.ts.map +1 -0
  16. package/dist/ingest-engine.js +63 -0
  17. package/dist/ingest-engine.js.map +1 -0
  18. package/dist/normalizer.d.ts +7 -0
  19. package/dist/normalizer.d.ts.map +1 -0
  20. package/dist/normalizer.js +71 -0
  21. package/dist/normalizer.js.map +1 -0
  22. package/dist/plugin-registry.d.ts +14 -0
  23. package/dist/plugin-registry.d.ts.map +1 -0
  24. package/dist/plugin-registry.js +37 -0
  25. package/dist/plugin-registry.js.map +1 -0
  26. package/dist/plugins/claude-sessions/index.d.ts +14 -0
  27. package/dist/plugins/claude-sessions/index.d.ts.map +1 -0
  28. package/dist/plugins/claude-sessions/index.js +123 -0
  29. package/dist/plugins/claude-sessions/index.js.map +1 -0
  30. package/dist/plugins/claude-sessions/session-parser.d.ts +18 -0
  31. package/dist/plugins/claude-sessions/session-parser.d.ts.map +1 -0
  32. package/dist/plugins/claude-sessions/session-parser.js +84 -0
  33. package/dist/plugins/claude-sessions/session-parser.js.map +1 -0
  34. package/dist/plugins/git-history/git-parser.d.ts +27 -0
  35. package/dist/plugins/git-history/git-parser.d.ts.map +1 -0
  36. package/dist/plugins/git-history/git-parser.js +121 -0
  37. package/dist/plugins/git-history/git-parser.js.map +1 -0
  38. package/dist/plugins/git-history/index.d.ts +12 -0
  39. package/dist/plugins/git-history/index.d.ts.map +1 -0
  40. package/dist/plugins/git-history/index.js +82 -0
  41. package/dist/plugins/git-history/index.js.map +1 -0
  42. package/dist/plugins/github/gh-parser.d.ts +51 -0
  43. package/dist/plugins/github/gh-parser.d.ts.map +1 -0
  44. package/dist/plugins/github/gh-parser.js +127 -0
  45. package/dist/plugins/github/gh-parser.js.map +1 -0
  46. package/dist/plugins/github/index.d.ts +13 -0
  47. package/dist/plugins/github/index.d.ts.map +1 -0
  48. package/dist/plugins/github/index.js +127 -0
  49. package/dist/plugins/github/index.js.map +1 -0
  50. package/dist/plugins/markdown/index.d.ts +16 -0
  51. package/dist/plugins/markdown/index.d.ts.map +1 -0
  52. package/dist/plugins/markdown/index.js +97 -0
  53. package/dist/plugins/markdown/index.js.map +1 -0
  54. package/dist/plugins/obsidian/frontmatter-parser.d.ts +8 -0
  55. package/dist/plugins/obsidian/frontmatter-parser.d.ts.map +1 -0
  56. package/dist/plugins/obsidian/frontmatter-parser.js +51 -0
  57. package/dist/plugins/obsidian/frontmatter-parser.js.map +1 -0
  58. package/dist/plugins/obsidian/index.d.ts +15 -0
  59. package/dist/plugins/obsidian/index.d.ts.map +1 -0
  60. package/dist/plugins/obsidian/index.js +161 -0
  61. package/dist/plugins/obsidian/index.js.map +1 -0
  62. package/dist/plugins/obsidian/wikilink-parser.d.ts +10 -0
  63. package/dist/plugins/obsidian/wikilink-parser.d.ts.map +1 -0
  64. package/dist/plugins/obsidian/wikilink-parser.js +55 -0
  65. package/dist/plugins/obsidian/wikilink-parser.js.map +1 -0
  66. package/dist/types.d.ts +81 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +2 -0
  69. package/dist/types.js.map +1 -0
  70. package/package.json +35 -0
@@ -0,0 +1,127 @@
1
+ import { execGh, checkGhAuth, checkGhVersion, parseGitHubSourceUri, parsePRList, parseIssueList, prToNormalizedEvent, issueToNormalizedEvent, } from "./gh-parser.js";
2
+ export class GitHubPlugin {
3
+ manifest = {
4
+ id: "github",
5
+ name: "GitHub PRs & Issues",
6
+ version: "0.1.0",
7
+ schemes: ["github://"],
8
+ priority: 1,
9
+ };
10
+ triggers = [
11
+ { type: "scheduled", cron: "0 * * * *" },
12
+ { type: "manual" },
13
+ ];
14
+ async initialize(_config) {
15
+ const versionCheck = await checkGhVersion();
16
+ if (!versionCheck.ok) {
17
+ return { ok: false, error: versionCheck.error ?? "gh CLI version check failed" };
18
+ }
19
+ const authed = await checkGhAuth();
20
+ if (!authed) {
21
+ return { ok: false, error: "gh CLI not authenticated. Run 'gh auth login'" };
22
+ }
23
+ return { ok: true };
24
+ }
25
+ async *ingestAll(sourceUri) {
26
+ const { owner, repo } = parseGitHubSourceUri(sourceUri);
27
+ // PRs
28
+ const prJson = await this.execWithRetry([
29
+ "pr",
30
+ "list",
31
+ "-R",
32
+ `${owner}/${repo}`,
33
+ "--json",
34
+ "number,title,body,author,labels,createdAt,updatedAt,url,state,reviewDecision",
35
+ "--limit",
36
+ "1000",
37
+ "--state",
38
+ "all",
39
+ ]);
40
+ for (const pr of parsePRList(prJson)) {
41
+ yield prToNormalizedEvent(pr, owner, repo);
42
+ }
43
+ // Issues
44
+ const issueJson = await this.execWithRetry([
45
+ "issue",
46
+ "list",
47
+ "-R",
48
+ `${owner}/${repo}`,
49
+ "--json",
50
+ "number,title,body,author,labels,createdAt,updatedAt,url,state",
51
+ "--limit",
52
+ "1000",
53
+ "--state",
54
+ "all",
55
+ ]);
56
+ for (const issue of parseIssueList(issueJson)) {
57
+ yield issueToNormalizedEvent(issue, owner, repo);
58
+ }
59
+ }
60
+ async *ingestIncremental(sourceUri, checkpoint) {
61
+ const { owner, repo } = parseGitHubSourceUri(sourceUri);
62
+ // checkpoint を1分前にオフセット(GitHub検索APIの分単位精度対応)
63
+ const checkpointDate = new Date(checkpoint);
64
+ checkpointDate.setMinutes(checkpointDate.getMinutes() - 1);
65
+ const adjustedCheckpoint = checkpointDate.toISOString().replace(/\.\d{3}Z$/, "Z");
66
+ // PRs (incremental)
67
+ const prJson = await this.execWithRetry([
68
+ "pr",
69
+ "list",
70
+ "-R",
71
+ `${owner}/${repo}`,
72
+ "--json",
73
+ "number,title,body,author,labels,createdAt,updatedAt,url,state,reviewDecision",
74
+ "--limit",
75
+ "1000",
76
+ "--state",
77
+ "all",
78
+ "--search",
79
+ `updated:>=${adjustedCheckpoint}`,
80
+ ]);
81
+ for (const pr of parsePRList(prJson)) {
82
+ yield prToNormalizedEvent(pr, owner, repo);
83
+ }
84
+ // Issues (incremental)
85
+ const issueJson = await this.execWithRetry([
86
+ "issue",
87
+ "list",
88
+ "-R",
89
+ `${owner}/${repo}`,
90
+ "--json",
91
+ "number,title,body,author,labels,createdAt,updatedAt,url,state",
92
+ "--limit",
93
+ "1000",
94
+ "--state",
95
+ "all",
96
+ "--search",
97
+ `updated:>=${adjustedCheckpoint}`,
98
+ ]);
99
+ for (const issue of parseIssueList(issueJson)) {
100
+ yield issueToNormalizedEvent(issue, owner, repo);
101
+ }
102
+ }
103
+ async getCurrentCheckpoint(_sourceUri) {
104
+ return new Date().toISOString();
105
+ }
106
+ async dispose() {
107
+ // no-op
108
+ }
109
+ /** Exponential backoff リトライ (3回、1s→2s→4s) */
110
+ async execWithRetry(args, maxRetries = 3) {
111
+ let lastError;
112
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
113
+ try {
114
+ return await execGh(args);
115
+ }
116
+ catch (error) {
117
+ lastError = error;
118
+ if (attempt < maxRetries - 1) {
119
+ const delay = Math.min(1000 * Math.pow(2, attempt), 30_000);
120
+ await new Promise((resolve) => setTimeout(resolve, delay));
121
+ }
122
+ }
123
+ }
124
+ throw lastError;
125
+ }
126
+ }
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/github/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { IngestPlugin, PluginManifest, TriggerConfig, PluginConfig, PluginInitResult, NormalizedEvent, SourceURI } from "../../types.js";
2
+ export declare class MarkdownPlugin implements IngestPlugin {
3
+ readonly manifest: PluginManifest;
4
+ readonly triggers: TriggerConfig[];
5
+ private fileProcessor;
6
+ initialize(_config?: PluginConfig): Promise<PluginInitResult>;
7
+ ingestAll(sourcePath: SourceURI): AsyncGenerator<NormalizedEvent>;
8
+ ingestIncremental(sourcePath: SourceURI, checkpoint: string): AsyncGenerator<NormalizedEvent>;
9
+ getCurrentCheckpoint(_sourcePath: SourceURI): Promise<string>;
10
+ dispose(): Promise<void>;
11
+ private processFile;
12
+ private extractTags;
13
+ private findMarkdownFiles;
14
+ private walkDir;
15
+ }
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/markdown/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,SAAS,EACV,MAAM,gBAAgB,CAAC;AAExB,qBAAa,cAAe,YAAW,YAAY;IACjD,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAM/B;IAEF,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,CAEhC;IAEF,OAAO,CAAC,aAAa,CAAuB;IAEtC,UAAU,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI5D,SAAS,CAAC,UAAU,EAAE,SAAS,GAAG,cAAc,CAAC,eAAe,CAAC;IAQjE,iBAAiB,CACtB,UAAU,EAAE,SAAS,EACrB,UAAU,EAAE,MAAM,GACjB,cAAc,CAAC,eAAe,CAAC;IAY5B,oBAAoB,CAAC,WAAW,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAIhB,WAAW;IAgCzB,OAAO,CAAC,WAAW;YAQL,iBAAiB;YAMjB,OAAO;CAatB"}
@@ -0,0 +1,97 @@
1
+ import { readdir, stat } from "fs/promises";
2
+ import { join, relative } from "path";
3
+ import { FileProcessor } from "@knowledgine/core";
4
+ export class MarkdownPlugin {
5
+ manifest = {
6
+ id: "markdown",
7
+ name: "Markdown Files",
8
+ version: "0.1.0",
9
+ schemes: ["file://"],
10
+ priority: 0,
11
+ };
12
+ triggers = [
13
+ { type: "file_watcher", paths: ["**/*.md"] },
14
+ ];
15
+ fileProcessor = new FileProcessor();
16
+ async initialize(_config) {
17
+ return { ok: true };
18
+ }
19
+ async *ingestAll(sourcePath) {
20
+ const mdFiles = await this.findMarkdownFiles(sourcePath);
21
+ for (const filePath of mdFiles) {
22
+ const event = await this.processFile(filePath, sourcePath);
23
+ if (event)
24
+ yield event;
25
+ }
26
+ }
27
+ async *ingestIncremental(sourcePath, checkpoint) {
28
+ const sinceDate = new Date(checkpoint);
29
+ const mdFiles = await this.findMarkdownFiles(sourcePath);
30
+ for (const filePath of mdFiles) {
31
+ const fileStat = await stat(filePath);
32
+ if (fileStat.mtimeMs > sinceDate.getTime()) {
33
+ const event = await this.processFile(filePath, sourcePath);
34
+ if (event)
35
+ yield event;
36
+ }
37
+ }
38
+ }
39
+ async getCurrentCheckpoint(_sourcePath) {
40
+ return new Date().toISOString();
41
+ }
42
+ async dispose() {
43
+ // no-op
44
+ }
45
+ async processFile(filePath, basePath) {
46
+ try {
47
+ const processed = await this.fileProcessor.processFile(filePath);
48
+ const title = this.fileProcessor.extractTitle(processed.content, filePath);
49
+ const relativePath = relative(basePath, filePath);
50
+ const fileStat = await stat(filePath);
51
+ return {
52
+ sourceUri: `file://${filePath}`,
53
+ eventType: "document",
54
+ title,
55
+ content: processed.content,
56
+ timestamp: fileStat.mtime,
57
+ metadata: {
58
+ sourcePlugin: "markdown",
59
+ sourceId: relativePath,
60
+ tags: this.extractTags(processed.frontmatter),
61
+ },
62
+ relatedPaths: [relativePath],
63
+ rawData: processed.frontmatter,
64
+ };
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ }
70
+ extractTags(frontmatter) {
71
+ const tags = frontmatter.tags;
72
+ if (Array.isArray(tags)) {
73
+ return tags.filter((t) => typeof t === "string");
74
+ }
75
+ return [];
76
+ }
77
+ async findMarkdownFiles(dir) {
78
+ const results = [];
79
+ await this.walkDir(dir, results);
80
+ return results;
81
+ }
82
+ async walkDir(dir, results) {
83
+ const entries = await readdir(dir, { withFileTypes: true });
84
+ for (const entry of entries) {
85
+ const fullPath = join(dir, entry.name);
86
+ if (entry.isDirectory()) {
87
+ if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
88
+ await this.walkDir(fullPath, results);
89
+ }
90
+ }
91
+ else if (entry.name.endsWith(".md")) {
92
+ results.push(fullPath);
93
+ }
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/markdown/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface ObsidianFrontmatter {
2
+ tags: string[];
3
+ aliases: string[];
4
+ custom: Record<string, unknown>;
5
+ }
6
+ export declare function parseObsidianFrontmatter(raw: Record<string, unknown>): ObsidianFrontmatter;
7
+ export declare function extractInlineTags(content: string): string[];
8
+ //# sourceMappingURL=frontmatter-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter-parser.d.ts","sourceRoot":"","sources":["../../../src/plugins/obsidian/frontmatter-parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,mBAAmB,CAqCrB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAe3D"}
@@ -0,0 +1,51 @@
1
+ export function parseObsidianFrontmatter(raw) {
2
+ // tags正規化
3
+ const rawTags = raw.tags;
4
+ let tags = [];
5
+ if (typeof rawTags === "string") {
6
+ tags = rawTags
7
+ .split(",")
8
+ .map((t) => t.trim().replace(/^#/, ""))
9
+ .filter(Boolean);
10
+ }
11
+ else if (Array.isArray(rawTags)) {
12
+ tags = rawTags
13
+ .filter((t) => typeof t === "string")
14
+ .map((t) => t.trim().replace(/^#/, ""))
15
+ .filter(Boolean);
16
+ }
17
+ // aliases正規化
18
+ const rawAliases = raw.aliases;
19
+ let aliases = [];
20
+ if (typeof rawAliases === "string") {
21
+ aliases = [rawAliases.trim()].filter(Boolean);
22
+ }
23
+ else if (Array.isArray(rawAliases)) {
24
+ aliases = rawAliases
25
+ .filter((a) => typeof a === "string")
26
+ .map((a) => a.trim())
27
+ .filter(Boolean);
28
+ }
29
+ // custom fields (tags, aliases, title以外)
30
+ const custom = {};
31
+ for (const [key, value] of Object.entries(raw)) {
32
+ if (key !== "tags" && key !== "aliases" && key !== "title") {
33
+ custom[key] = value;
34
+ }
35
+ }
36
+ return { tags, aliases, custom };
37
+ }
38
+ export function extractInlineTags(content) {
39
+ // コードブロック除外
40
+ const withoutCodeBlocks = content
41
+ .replace(/```[\s\S]*?```/g, "")
42
+ .replace(/`[^`]+`/g, "");
43
+ const tagRegex = /(?:^|\s)#([a-zA-Z0-9_\-/]+)/g;
44
+ const tags = new Set();
45
+ let match;
46
+ while ((match = tagRegex.exec(withoutCodeBlocks)) !== null) {
47
+ tags.add(match[1]);
48
+ }
49
+ return Array.from(tags);
50
+ }
51
+ //# sourceMappingURL=frontmatter-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter-parser.js","sourceRoot":"","sources":["../../../src/plugins/obsidian/frontmatter-parser.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,wBAAwB,CACtC,GAA4B;IAE5B,UAAU;IACV,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;IACzB,IAAI,IAAI,GAAa,EAAE,CAAC;IACxB,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,IAAI,GAAG,OAAO;aACX,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;aACtC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,IAAI,GAAG,OAAO;aACX,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;aACjD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;aACtC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,aAAa;IACb,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC;IAC/B,IAAI,OAAO,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACrC,OAAO,GAAG,UAAU;aACjB,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;aACjD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,yCAAyC;IACzC,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YAC3D,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,YAAY;IACZ,MAAM,iBAAiB,GAAG,OAAO;SAC9B,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;SAC9B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAE3B,MAAM,QAAQ,GAAG,8BAA8B,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,KAAK,CAAC;IAEV,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3D,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { IngestPlugin, PluginManifest, TriggerConfig, PluginConfig, PluginInitResult, NormalizedEvent, SourceURI } from "../../types.js";
2
+ export declare class ObsidianPlugin implements IngestPlugin {
3
+ readonly manifest: PluginManifest;
4
+ readonly triggers: TriggerConfig[];
5
+ private fileProcessor;
6
+ initialize(config?: PluginConfig): Promise<PluginInitResult>;
7
+ ingestAll(sourcePath: SourceURI): AsyncGenerator<NormalizedEvent>;
8
+ ingestIncremental(sourcePath: SourceURI, checkpoint: string): AsyncGenerator<NormalizedEvent>;
9
+ getCurrentCheckpoint(_sourcePath: SourceURI): Promise<string>;
10
+ dispose(): Promise<void>;
11
+ private processFile;
12
+ private findMarkdownFiles;
13
+ private walkDir;
14
+ }
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/obsidian/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,SAAS,EACV,MAAM,gBAAgB,CAAC;AAQxB,qBAAa,cAAe,YAAW,YAAY;IACjD,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAM/B;IAEF,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,CAGhC;IAEF,OAAO,CAAC,aAAa,CAAuB;IAEtC,UAAU,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAW3D,SAAS,CAAC,UAAU,EAAE,SAAS,GAAG,cAAc,CAAC,eAAe,CAAC;IAcjE,iBAAiB,CACtB,UAAU,EAAE,SAAS,EACrB,UAAU,EAAE,MAAM,GACjB,cAAc,CAAC,eAAe,CAAC;IAkB5B,oBAAoB,CAAC,WAAW,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAIhB,WAAW;YAkEX,iBAAiB;YAMjB,OAAO;CAwCtB"}
@@ -0,0 +1,161 @@
1
+ import { readdir, stat, realpath } from "fs/promises";
2
+ import { join, relative, basename, resolve, dirname } from "path";
3
+ import { existsSync } from "fs";
4
+ import { FileProcessor } from "@knowledgine/core";
5
+ import { sanitizeContent } from "../../normalizer.js";
6
+ import { parseWikiLinks, resolveWikiLinkPath } from "./wikilink-parser.js";
7
+ import { parseObsidianFrontmatter, extractInlineTags, } from "./frontmatter-parser.js";
8
+ export class ObsidianPlugin {
9
+ manifest = {
10
+ id: "obsidian",
11
+ name: "Obsidian Vault",
12
+ version: "0.1.0",
13
+ schemes: ["obsidian://"],
14
+ priority: 1,
15
+ };
16
+ triggers = [
17
+ { type: "file_watcher", paths: ["**/*.md"] },
18
+ { type: "manual" },
19
+ ];
20
+ fileProcessor = new FileProcessor();
21
+ async initialize(config) {
22
+ const sourcePath = config?.sourcePath;
23
+ if (sourcePath && !existsSync(join(sourcePath, ".obsidian"))) {
24
+ return {
25
+ ok: false,
26
+ error: "No Obsidian vault found (.obsidian directory missing)",
27
+ };
28
+ }
29
+ return { ok: true };
30
+ }
31
+ async *ingestAll(sourcePath) {
32
+ if (!existsSync(join(sourcePath, ".obsidian"))) {
33
+ return;
34
+ }
35
+ const mdFiles = await this.findMarkdownFiles(sourcePath);
36
+ const vaultName = basename(sourcePath);
37
+ for (const filePath of mdFiles) {
38
+ const event = await this.processFile(filePath, sourcePath, vaultName);
39
+ if (event)
40
+ yield event;
41
+ }
42
+ }
43
+ async *ingestIncremental(sourcePath, checkpoint) {
44
+ if (!existsSync(join(sourcePath, ".obsidian"))) {
45
+ return;
46
+ }
47
+ const sinceDate = new Date(checkpoint);
48
+ const mdFiles = await this.findMarkdownFiles(sourcePath);
49
+ const vaultName = basename(sourcePath);
50
+ for (const filePath of mdFiles) {
51
+ const fileStat = await stat(filePath);
52
+ if (fileStat.mtimeMs > sinceDate.getTime()) {
53
+ const event = await this.processFile(filePath, sourcePath, vaultName);
54
+ if (event)
55
+ yield event;
56
+ }
57
+ }
58
+ }
59
+ async getCurrentCheckpoint(_sourcePath) {
60
+ return new Date().toISOString();
61
+ }
62
+ async dispose() {
63
+ // no-op
64
+ }
65
+ async processFile(filePath, vaultPath, vaultName) {
66
+ try {
67
+ const processed = await this.fileProcessor.processFile(filePath);
68
+ const title = processed.frontmatter.title ||
69
+ this.fileProcessor.extractTitle(processed.content, filePath);
70
+ const relativePath = relative(vaultPath, filePath);
71
+ const fileStat = await stat(filePath);
72
+ // Obsidian固有処理
73
+ const obsidianFm = parseObsidianFrontmatter(processed.frontmatter);
74
+ const wikilinks = parseWikiLinks(processed.content);
75
+ const inlineTags = extractInlineTags(processed.content);
76
+ // タグ統合(重複除去)
77
+ const allTags = [...new Set([...obsidianFm.tags, ...inlineTags])];
78
+ // Wikilink解決
79
+ const relatedPaths = [];
80
+ for (const link of wikilinks) {
81
+ if (!link.isEmbed ||
82
+ !link.target.match(/\.(png|jpg|jpeg|gif|svg|webp|pdf)$/i)) {
83
+ const resolved = resolveWikiLinkPath(link.target, vaultPath, filePath);
84
+ if (resolved) {
85
+ relatedPaths.push(relative(vaultPath, resolved));
86
+ }
87
+ }
88
+ }
89
+ return {
90
+ sourceUri: `obsidian://${vaultName}/${relativePath}`,
91
+ eventType: "document",
92
+ title,
93
+ content: sanitizeContent(processed.content),
94
+ timestamp: fileStat.mtime,
95
+ metadata: {
96
+ sourcePlugin: "obsidian",
97
+ sourceId: relativePath,
98
+ tags: allTags,
99
+ extra: {
100
+ aliases: obsidianFm.aliases,
101
+ wikilinks: wikilinks.map((l) => ({
102
+ target: l.target,
103
+ alias: l.alias,
104
+ })),
105
+ ...obsidianFm.custom,
106
+ },
107
+ },
108
+ relatedPaths,
109
+ rawData: processed.frontmatter,
110
+ };
111
+ }
112
+ catch {
113
+ return null;
114
+ }
115
+ }
116
+ async findMarkdownFiles(dir) {
117
+ const results = [];
118
+ await this.walkDir(dir, dir, results);
119
+ return results;
120
+ }
121
+ async walkDir(dir, vaultRoot, results) {
122
+ const entries = await readdir(dir, { withFileTypes: true });
123
+ const SKIP_DIRS = new Set([
124
+ ".obsidian",
125
+ "node_modules",
126
+ ".git",
127
+ ".trash",
128
+ ]);
129
+ for (const entry of entries) {
130
+ const fullPath = join(dir, entry.name);
131
+ if (entry.isSymbolicLink()) {
132
+ try {
133
+ const realPath = await realpath(fullPath);
134
+ if (!realPath.startsWith(vaultRoot))
135
+ continue;
136
+ const linkStat = await stat(fullPath);
137
+ if (linkStat.isDirectory()) {
138
+ if (!SKIP_DIRS.has(entry.name)) {
139
+ await this.walkDir(fullPath, vaultRoot, results);
140
+ }
141
+ }
142
+ else if (entry.name.endsWith(".md")) {
143
+ results.push(fullPath);
144
+ }
145
+ }
146
+ catch {
147
+ continue;
148
+ }
149
+ }
150
+ else if (entry.isDirectory()) {
151
+ if (!SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
152
+ await this.walkDir(fullPath, vaultRoot, results);
153
+ }
154
+ }
155
+ else if (entry.name.endsWith(".md")) {
156
+ results.push(fullPath);
157
+ }
158
+ }
159
+ }
160
+ }
161
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/obsidian/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAUlD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EACL,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,OAAO,cAAc;IAChB,QAAQ,GAAmB;QAClC,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,CAAC,aAAa,CAAC;QACxB,QAAQ,EAAE,CAAC;KACZ,CAAC;IAEO,QAAQ,GAAoB;QACnC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE;QAC5C,EAAE,IAAI,EAAE,QAAQ,EAAE;KACnB,CAAC;IAEM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;IAE5C,KAAK,CAAC,UAAU,CAAC,MAAqB;QACpC,MAAM,UAAU,GAAG,MAAM,EAAE,UAAgC,CAAC;QAC5D,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;YAC7D,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,uDAAuD;aAC/D,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,CAAC,SAAS,CAAC,UAAqB;QACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;YAC/C,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAEvC,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YACtE,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,CAAC,iBAAiB,CACtB,UAAqB,EACrB,UAAkB;QAElB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;YAC/C,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAEvC,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtC,IAAI,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC3C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;gBACtE,IAAI,KAAK;oBAAE,MAAM,KAAK,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,WAAsB;QAC/C,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,OAAO;QACX,QAAQ;IACV,CAAC;IAEO,KAAK,CAAC,WAAW,CACvB,QAAgB,EAChB,SAAiB,EACjB,SAAiB;QAEjB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YACjE,MAAM,KAAK,GACR,SAAS,CAAC,WAAW,CAAC,KAAgB;gBACvC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC/D,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;YAEtC,eAAe;YACf,MAAM,UAAU,GAAG,wBAAwB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACnE,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACpD,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAExD,aAAa;YACb,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAElE,aAAa;YACb,MAAM,YAAY,GAAa,EAAE,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,IACE,CAAC,IAAI,CAAC,OAAO;oBACb,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,EACzD,CAAC;oBACD,MAAM,QAAQ,GAAG,mBAAmB,CAClC,IAAI,CAAC,MAAM,EACX,SAAS,EACT,QAAQ,CACT,CAAC;oBACF,IAAI,QAAQ,EAAE,CAAC;wBACb,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;oBACnD,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO;gBACL,SAAS,EAAE,cAAc,SAAS,IAAI,YAAY,EAAE;gBACpD,SAAS,EAAE,UAAU;gBACrB,KAAK;gBACL,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,OAAO,CAAC;gBAC3C,SAAS,EAAE,QAAQ,CAAC,KAAK;gBACzB,QAAQ,EAAE;oBACR,YAAY,EAAE,UAAU;oBACxB,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,OAAO,EAAE,UAAU,CAAC,OAAO;wBAC3B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAC/B,MAAM,EAAE,CAAC,CAAC,MAAM;4BAChB,KAAK,EAAE,CAAC,CAAC,KAAK;yBACf,CAAC,CAAC;wBACH,GAAG,UAAU,CAAC,MAAM;qBACrB;iBACF;gBACD,YAAY;gBACZ,OAAO,EAAE,SAAS,CAAC,WAAW;aAC/B,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,GAAW;QACzC,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACtC,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,GAAW,EACX,SAAiB,EACjB,OAAiB;QAEjB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;YACxB,WAAW;YACX,cAAc;YACd,MAAM;YACN,QAAQ;SACT,CAAC,CAAC;QAEH,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAEvC,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBAC1C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;wBAAE,SAAS;oBAC9C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACtC,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;wBAC3B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;4BAC/B,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;wBACnD,CAAC;oBACH,CAAC;yBAAM,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;wBACtC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9D,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ export interface WikiLink {
2
+ raw: string;
3
+ target: string;
4
+ alias?: string;
5
+ heading?: string;
6
+ isEmbed: boolean;
7
+ }
8
+ export declare function parseWikiLinks(content: string): WikiLink[];
9
+ export declare function resolveWikiLinkPath(target: string, vaultPath: string, currentFilePath: string): string | null;
10
+ //# sourceMappingURL=wikilink-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wikilink-parser.d.ts","sourceRoot":"","sources":["../../../src/plugins/obsidian/wikilink-parser.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAgD1D;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,GACtB,MAAM,GAAG,IAAI,CAaf"}
@@ -0,0 +1,55 @@
1
+ import { resolve, dirname } from "node:path";
2
+ import { existsSync } from "node:fs";
3
+ export function parseWikiLinks(content) {
4
+ // コードブロック内のwikilinkを除外
5
+ const codeBlockRegex = /```[\s\S]*?```|`[^`]+`/g;
6
+ const codeBlocks = [];
7
+ let match;
8
+ while ((match = codeBlockRegex.exec(content)) !== null) {
9
+ codeBlocks.push({ start: match.index, end: match.index + match[0].length });
10
+ }
11
+ const wikiLinkRegex = /(!?)\[\[([^\]]+)\]\]/g;
12
+ const links = [];
13
+ while ((match = wikiLinkRegex.exec(content)) !== null) {
14
+ const pos = match.index;
15
+ if (codeBlocks.some((b) => pos >= b.start && pos < b.end))
16
+ continue;
17
+ const isEmbed = match[1] === "!";
18
+ const inner = match[2];
19
+ const pipeIdx = inner.indexOf("|");
20
+ const pathPart = pipeIdx >= 0 ? inner.slice(0, pipeIdx).trim() : inner.trim();
21
+ const alias = pipeIdx >= 0 ? inner.slice(pipeIdx + 1).trim() : undefined;
22
+ if (!pathPart)
23
+ continue;
24
+ const hashIdx = pathPart.indexOf("#");
25
+ const target = hashIdx >= 0 ? pathPart.slice(0, hashIdx).trim() : pathPart;
26
+ const heading = hashIdx >= 0 ? pathPart.slice(hashIdx + 1).trim() : undefined;
27
+ if (!target)
28
+ continue;
29
+ // パストラバーサル拒否
30
+ if (target.includes(".."))
31
+ continue;
32
+ links.push({
33
+ raw: match[0],
34
+ target,
35
+ alias: alias || undefined,
36
+ heading: heading || undefined,
37
+ isEmbed,
38
+ });
39
+ }
40
+ return links;
41
+ }
42
+ export function resolveWikiLinkPath(target, vaultPath, currentFilePath) {
43
+ if (target.includes(".."))
44
+ return null;
45
+ const resolved = resolve(dirname(currentFilePath), target);
46
+ // vault配下か検証
47
+ if (!resolved.startsWith(vaultPath))
48
+ return null;
49
+ if (existsSync(resolved))
50
+ return resolved;
51
+ if (!resolved.endsWith(".md") && existsSync(resolved + ".md"))
52
+ return resolved + ".md";
53
+ return null;
54
+ }
55
+ //# sourceMappingURL=wikilink-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wikilink-parser.js","sourceRoot":"","sources":["../../../src/plugins/obsidian/wikilink-parser.ts"],"names":[],"mappings":"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"}