obsidian-accomplishments-mcp 0.1.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 (119) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +349 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +120 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/models/types.d.ts +136 -0
  8. package/dist/models/types.d.ts.map +1 -0
  9. package/dist/models/types.js +27 -0
  10. package/dist/models/types.js.map +1 -0
  11. package/dist/parsers/canvas-parser.d.ts +58 -0
  12. package/dist/parsers/canvas-parser.d.ts.map +1 -0
  13. package/dist/parsers/canvas-parser.js +136 -0
  14. package/dist/parsers/canvas-parser.js.map +1 -0
  15. package/dist/parsers/markdown-parser.d.ts +22 -0
  16. package/dist/parsers/markdown-parser.d.ts.map +1 -0
  17. package/dist/parsers/markdown-parser.js +254 -0
  18. package/dist/parsers/markdown-parser.js.map +1 -0
  19. package/dist/services/accomplishment-service.d.ts +33 -0
  20. package/dist/services/accomplishment-service.d.ts.map +1 -0
  21. package/dist/services/accomplishment-service.js +284 -0
  22. package/dist/services/accomplishment-service.js.map +1 -0
  23. package/dist/services/canvas-service.d.ts +52 -0
  24. package/dist/services/canvas-service.d.ts.map +1 -0
  25. package/dist/services/canvas-service.js +166 -0
  26. package/dist/services/canvas-service.js.map +1 -0
  27. package/dist/services/context-doc-service.d.ts +70 -0
  28. package/dist/services/context-doc-service.d.ts.map +1 -0
  29. package/dist/services/context-doc-service.js +229 -0
  30. package/dist/services/context-doc-service.js.map +1 -0
  31. package/dist/services/dependency-service.d.ts +22 -0
  32. package/dist/services/dependency-service.d.ts.map +1 -0
  33. package/dist/services/dependency-service.js +99 -0
  34. package/dist/services/dependency-service.js.map +1 -0
  35. package/dist/services/task-service.d.ts +32 -0
  36. package/dist/services/task-service.d.ts.map +1 -0
  37. package/dist/services/task-service.js +152 -0
  38. package/dist/services/task-service.js.map +1 -0
  39. package/dist/test-runner.d.ts +6 -0
  40. package/dist/test-runner.d.ts.map +1 -0
  41. package/dist/test-runner.js +130 -0
  42. package/dist/test-runner.js.map +1 -0
  43. package/dist/tools/get-accomplishment.d.ts +26 -0
  44. package/dist/tools/get-accomplishment.d.ts.map +1 -0
  45. package/dist/tools/get-accomplishment.js +53 -0
  46. package/dist/tools/get-accomplishment.js.map +1 -0
  47. package/dist/tools/get-blocked-items.d.ts +15 -0
  48. package/dist/tools/get-blocked-items.d.ts.map +1 -0
  49. package/dist/tools/get-blocked-items.js +72 -0
  50. package/dist/tools/get-blocked-items.js.map +1 -0
  51. package/dist/tools/get-current-work.d.ts +15 -0
  52. package/dist/tools/get-current-work.d.ts.map +1 -0
  53. package/dist/tools/get-current-work.js +67 -0
  54. package/dist/tools/get-current-work.js.map +1 -0
  55. package/dist/tools/get-project-status.d.ts +26 -0
  56. package/dist/tools/get-project-status.d.ts.map +1 -0
  57. package/dist/tools/get-project-status.js +92 -0
  58. package/dist/tools/get-project-status.js.map +1 -0
  59. package/dist/tools/get-ready-to-start.d.ts +15 -0
  60. package/dist/tools/get-ready-to-start.d.ts.map +1 -0
  61. package/dist/tools/get-ready-to-start.js +46 -0
  62. package/dist/tools/get-ready-to-start.js.map +1 -0
  63. package/dist/tools/index.d.ts +155 -0
  64. package/dist/tools/index.d.ts.map +1 -0
  65. package/dist/tools/index.js +48 -0
  66. package/dist/tools/index.js.map +1 -0
  67. package/dist/tools/list-accomplishments.d.ts +34 -0
  68. package/dist/tools/list-accomplishments.d.ts.map +1 -0
  69. package/dist/tools/list-accomplishments.js +34 -0
  70. package/dist/tools/list-accomplishments.js.map +1 -0
  71. package/dist/tools/list-files.d.ts +26 -0
  72. package/dist/tools/list-files.d.ts.map +1 -0
  73. package/dist/tools/list-files.js +46 -0
  74. package/dist/tools/list-files.js.map +1 -0
  75. package/dist/tools/list-workspaces.d.ts +22 -0
  76. package/dist/tools/list-workspaces.d.ts.map +1 -0
  77. package/dist/tools/list-workspaces.js +22 -0
  78. package/dist/tools/list-workspaces.js.map +1 -0
  79. package/dist/tools/manage-accomplishment.d.ts +147 -0
  80. package/dist/tools/manage-accomplishment.d.ts.map +1 -0
  81. package/dist/tools/manage-accomplishment.js +138 -0
  82. package/dist/tools/manage-accomplishment.js.map +1 -0
  83. package/dist/tools/manage-dependency.d.ts +41 -0
  84. package/dist/tools/manage-dependency.d.ts.map +1 -0
  85. package/dist/tools/manage-dependency.js +61 -0
  86. package/dist/tools/manage-dependency.js.map +1 -0
  87. package/dist/tools/manage-task.d.ts +119 -0
  88. package/dist/tools/manage-task.d.ts.map +1 -0
  89. package/dist/tools/manage-task.js +121 -0
  90. package/dist/tools/manage-task.js.map +1 -0
  91. package/dist/tools/read-docs.d.ts +48 -0
  92. package/dist/tools/read-docs.d.ts.map +1 -0
  93. package/dist/tools/read-docs.js +90 -0
  94. package/dist/tools/read-docs.js.map +1 -0
  95. package/dist/tools/set-work-focus.d.ts +48 -0
  96. package/dist/tools/set-work-focus.d.ts.map +1 -0
  97. package/dist/tools/set-work-focus.js +75 -0
  98. package/dist/tools/set-work-focus.js.map +1 -0
  99. package/dist/tools/sync-dependencies.d.ts +33 -0
  100. package/dist/tools/sync-dependencies.d.ts.map +1 -0
  101. package/dist/tools/sync-dependencies.js +144 -0
  102. package/dist/tools/sync-dependencies.js.map +1 -0
  103. package/dist/tools/update-doc.d.ts +62 -0
  104. package/dist/tools/update-doc.d.ts.map +1 -0
  105. package/dist/tools/update-doc.js +196 -0
  106. package/dist/tools/update-doc.js.map +1 -0
  107. package/dist/utils/config.d.ts +27 -0
  108. package/dist/utils/config.d.ts.map +1 -0
  109. package/dist/utils/config.js +106 -0
  110. package/dist/utils/config.js.map +1 -0
  111. package/dist/utils/file-utils.d.ts +29 -0
  112. package/dist/utils/file-utils.d.ts.map +1 -0
  113. package/dist/utils/file-utils.js +83 -0
  114. package/dist/utils/file-utils.js.map +1 -0
  115. package/dist/utils/positioning.d.ts +16 -0
  116. package/dist/utils/positioning.d.ts.map +1 -0
  117. package/dist/utils/positioning.js +126 -0
  118. package/dist/utils/positioning.js.map +1 -0
  119. package/package.json +56 -0
@@ -0,0 +1,106 @@
1
+ import { readFileSync, existsSync, writeFileSync } from 'fs';
2
+ const WORKSPACES_TEMPLATE = {
3
+ "example_workspace": {
4
+ "path": "/path/to/your/documents",
5
+ "description": "Description of what this workspace contains"
6
+ }
7
+ };
8
+ export function getConfig() {
9
+ const vaultPath = process.env.VAULT_PATH;
10
+ const accomplishmentsFolder = process.env.ACCOMPLISHMENTS_FOLDER;
11
+ const defaultCanvas = process.env.DEFAULT_CANVAS;
12
+ if (!vaultPath) {
13
+ throw new Error('VAULT_PATH environment variable is required');
14
+ }
15
+ if (!accomplishmentsFolder) {
16
+ throw new Error('ACCOMPLISHMENTS_FOLDER environment variable is required');
17
+ }
18
+ if (!defaultCanvas) {
19
+ throw new Error('DEFAULT_CANVAS environment variable is required');
20
+ }
21
+ // Load workspaces from workspaces.json in vault folder
22
+ let workspaces = {};
23
+ const workspacesConfigPath = `${vaultPath}/workspaces.json`;
24
+ if (!existsSync(workspacesConfigPath)) {
25
+ // Create template file on first run
26
+ writeFileSync(workspacesConfigPath, JSON.stringify(WORKSPACES_TEMPLATE, null, 2), 'utf-8');
27
+ console.error(`Created workspaces.json template at: ${workspacesConfigPath}`);
28
+ console.error('Please edit this file to configure your workspaces.');
29
+ }
30
+ try {
31
+ const content = readFileSync(workspacesConfigPath, 'utf-8');
32
+ const parsed = JSON.parse(content);
33
+ // Validate workspace config structure
34
+ for (const [name, config] of Object.entries(parsed)) {
35
+ if (typeof config !== 'object' || config === null) {
36
+ throw new Error(`Workspace "${name}" must be an object with path and description`);
37
+ }
38
+ const wsConfig = config;
39
+ if (typeof wsConfig.path !== 'string') {
40
+ throw new Error(`Workspace "${name}" must have a "path" string`);
41
+ }
42
+ if (typeof wsConfig.description !== 'string') {
43
+ throw new Error(`Workspace "${name}" must have a "description" string`);
44
+ }
45
+ workspaces[name] = {
46
+ path: wsConfig.path,
47
+ description: wsConfig.description,
48
+ };
49
+ }
50
+ }
51
+ catch (e) {
52
+ if (e instanceof SyntaxError) {
53
+ throw new Error(`workspaces.json is not valid JSON: ${e.message}`);
54
+ }
55
+ throw e;
56
+ }
57
+ return {
58
+ vaultPath,
59
+ accomplishmentsFolder,
60
+ defaultCanvas,
61
+ workspaces,
62
+ };
63
+ }
64
+ export function getAccomplishmentsPath(config) {
65
+ return `${config.vaultPath}/${config.accomplishmentsFolder}`;
66
+ }
67
+ export function getCanvasPath(config, canvasSource) {
68
+ return `${config.vaultPath}/${canvasSource || config.defaultCanvas}`;
69
+ }
70
+ export function getAccomplishmentFilePath(config, title) {
71
+ return `${getAccomplishmentsPath(config)}/${title}.md`;
72
+ }
73
+ export function getRelativeAccomplishmentPath(config, title) {
74
+ return `${config.accomplishmentsFolder}/${title}.md`;
75
+ }
76
+ /**
77
+ * Get workspace config by name
78
+ */
79
+ export function getWorkspace(config, workspaceName) {
80
+ return config.workspaces[workspaceName];
81
+ }
82
+ /**
83
+ * Get the absolute path for a workspace
84
+ */
85
+ export function getWorkspacePath(config, workspaceName) {
86
+ return config.workspaces[workspaceName]?.path;
87
+ }
88
+ /**
89
+ * Get workspace description
90
+ */
91
+ export function getWorkspaceDescription(config, workspaceName) {
92
+ return config.workspaces[workspaceName]?.description;
93
+ }
94
+ /**
95
+ * Get all workspace names
96
+ */
97
+ export function getWorkspaceNames(config) {
98
+ return Object.keys(config.workspaces);
99
+ }
100
+ /**
101
+ * Get all workspaces with their configs
102
+ */
103
+ export function getAllWorkspaces(config) {
104
+ return config.workspaces;
105
+ }
106
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAE7D,MAAM,mBAAmB,GAAG;IAC1B,mBAAmB,EAAE;QACnB,MAAM,EAAE,yBAAyB;QACjC,aAAa,EAAE,6CAA6C;KAC7D;CACF,CAAC;AAEF,MAAM,UAAU,SAAS;IACvB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACzC,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IACjE,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAEjD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,uDAAuD;IACvD,IAAI,UAAU,GAAoC,EAAE,CAAC;IACrD,MAAM,oBAAoB,GAAG,GAAG,SAAS,kBAAkB,CAAC;IAE5D,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACtC,oCAAoC;QACpC,aAAa,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC3F,OAAO,CAAC,KAAK,CAAC,wCAAwC,oBAAoB,EAAE,CAAC,CAAC;QAC9E,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEnC,sCAAsC;QACtC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACpD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,+CAA+C,CAAC,CAAC;YACrF,CAAC;YACD,MAAM,QAAQ,GAAG,MAAiC,CAAC;YACnD,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtC,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,6BAA6B,CAAC,CAAC;YACnE,CAAC;YACD,IAAI,OAAO,QAAQ,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;gBAC7C,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,oCAAoC,CAAC,CAAC;YAC1E,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,GAAG;gBACjB,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,WAAW,EAAE,QAAQ,CAAC,WAAW;aAClC,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,WAAW,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;IAED,OAAO;QACL,SAAS;QACT,qBAAqB;QACrB,aAAa;QACb,UAAU;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,OAAO,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,YAAqB;IACjE,OAAO,GAAG,MAAM,CAAC,SAAS,IAAI,YAAY,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,KAAa;IACrE,OAAO,GAAG,sBAAsB,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,MAAc,EAAE,KAAa;IACzE,OAAO,GAAG,MAAM,CAAC,qBAAqB,IAAI,KAAK,KAAK,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,aAAqB;IAChE,OAAO,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,aAAqB;IACpE,OAAO,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,aAAqB;IAC3E,OAAO,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO,MAAM,CAAC,UAAU,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Read file content as string
3
+ */
4
+ export declare function readFile(path: string): Promise<string>;
5
+ /**
6
+ * Write file atomically (write to temp, then rename)
7
+ */
8
+ export declare function writeFileAtomic(path: string, content: string): Promise<void>;
9
+ /**
10
+ * Delete a file
11
+ */
12
+ export declare function deleteFile(path: string): Promise<void>;
13
+ /**
14
+ * Check if file exists
15
+ */
16
+ export declare function fileExists(path: string): Promise<boolean>;
17
+ /**
18
+ * List files in directory (non-recursive, returns filenames only)
19
+ */
20
+ export declare function listFiles(dirPath: string): Promise<string[]>;
21
+ /**
22
+ * List files recursively in directory (returns relative paths like "subfolder/doc.md")
23
+ */
24
+ export declare function listFilesRecursive(dirPath: string, basePath?: string): Promise<string[]>;
25
+ /**
26
+ * Generate a unique ID for canvas nodes/edges
27
+ */
28
+ export declare function generateId(): string;
29
+ //# sourceMappingURL=file-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/utils/file-utils.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5D;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWlF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASlE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmBlG;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAGnC"}
@@ -0,0 +1,83 @@
1
+ import { promises as fs } from 'fs';
2
+ import { dirname } from 'path';
3
+ /**
4
+ * Read file content as string
5
+ */
6
+ export async function readFile(path) {
7
+ return fs.readFile(path, 'utf-8');
8
+ }
9
+ /**
10
+ * Write file atomically (write to temp, then rename)
11
+ */
12
+ export async function writeFileAtomic(path, content) {
13
+ const tempPath = `${path}.tmp`;
14
+ // Ensure directory exists
15
+ await fs.mkdir(dirname(path), { recursive: true });
16
+ // Write to temp file
17
+ await fs.writeFile(tempPath, content, 'utf-8');
18
+ // Rename to target (atomic on most filesystems)
19
+ await fs.rename(tempPath, path);
20
+ }
21
+ /**
22
+ * Delete a file
23
+ */
24
+ export async function deleteFile(path) {
25
+ await fs.unlink(path);
26
+ }
27
+ /**
28
+ * Check if file exists
29
+ */
30
+ export async function fileExists(path) {
31
+ try {
32
+ await fs.access(path);
33
+ return true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
39
+ /**
40
+ * List files in directory (non-recursive, returns filenames only)
41
+ */
42
+ export async function listFiles(dirPath) {
43
+ try {
44
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
45
+ return entries
46
+ .filter(entry => entry.isFile())
47
+ .map(entry => entry.name);
48
+ }
49
+ catch {
50
+ return [];
51
+ }
52
+ }
53
+ /**
54
+ * List files recursively in directory (returns relative paths like "subfolder/doc.md")
55
+ */
56
+ export async function listFilesRecursive(dirPath, basePath = '') {
57
+ try {
58
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
59
+ const files = [];
60
+ for (const entry of entries) {
61
+ const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;
62
+ if (entry.isFile()) {
63
+ files.push(relativePath);
64
+ }
65
+ else if (entry.isDirectory()) {
66
+ const subFiles = await listFilesRecursive(`${dirPath}/${entry.name}`, relativePath);
67
+ files.push(...subFiles);
68
+ }
69
+ }
70
+ return files;
71
+ }
72
+ catch {
73
+ return [];
74
+ }
75
+ }
76
+ /**
77
+ * Generate a unique ID for canvas nodes/edges
78
+ */
79
+ export function generateId() {
80
+ return Math.random().toString(36).substring(2, 15) +
81
+ Math.random().toString(36).substring(2, 15);
82
+ }
83
+ //# sourceMappingURL=file-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-utils.js","sourceRoot":"","sources":["../../src/utils/file-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { CanvasFile, Position } from '../models/types.js';
2
+ export declare const NODE_WIDTH = 400;
3
+ export declare const NODE_HEIGHT = 300;
4
+ export declare const HORIZONTAL_GAP = 100;
5
+ export declare const VERTICAL_GAP = 50;
6
+ export declare const START_X = 0;
7
+ export declare const START_Y = 0;
8
+ /**
9
+ * Calculate position for a new accomplishment based on its dependencies
10
+ */
11
+ export declare function calculatePosition(canvas: CanvasFile, dependsOnNodeIds: string[]): Position;
12
+ /**
13
+ * Recalculate position for an existing node based on its current dependencies
14
+ */
15
+ export declare function recalculatePosition(canvas: CanvasFile, nodeId: string, dependsOnNodeIds: string[]): Position;
16
+ //# sourceMappingURL=positioning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"positioning.d.ts","sourceRoot":"","sources":["../../src/utils/positioning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAc,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGtE,eAAO,MAAM,UAAU,MAAM,CAAC;AAC9B,eAAO,MAAM,WAAW,MAAM,CAAC;AAC/B,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,eAAO,MAAM,OAAO,IAAI,CAAC;AAEzB;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAClB,gBAAgB,EAAE,MAAM,EAAE,GACzB,QAAQ,CAQV;AAyHD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,EAAE,GACzB,QAAQ,CAQV"}
@@ -0,0 +1,126 @@
1
+ // Constants for positioning
2
+ export const NODE_WIDTH = 400;
3
+ export const NODE_HEIGHT = 300;
4
+ export const HORIZONTAL_GAP = 100;
5
+ export const VERTICAL_GAP = 50;
6
+ export const START_X = 0;
7
+ export const START_Y = 0;
8
+ /**
9
+ * Calculate position for a new accomplishment based on its dependencies
10
+ */
11
+ export function calculatePosition(canvas, dependsOnNodeIds) {
12
+ if (dependsOnNodeIds.length === 0) {
13
+ // No dependencies: place in leftmost column
14
+ return calculateLeftColumnPosition(canvas);
15
+ }
16
+ // Has dependencies: place to the right of blockers
17
+ return calculateDependentPosition(canvas, dependsOnNodeIds);
18
+ }
19
+ /**
20
+ * Calculate position in the leftmost column (for items with no dependencies)
21
+ */
22
+ function calculateLeftColumnPosition(canvas) {
23
+ // Find all nodes that have no incoming edges (no dependencies)
24
+ const nodesWithNoDeps = getNodesWithNoDependencies(canvas);
25
+ if (nodesWithNoDeps.length === 0) {
26
+ return { x: START_X, y: START_Y };
27
+ }
28
+ // Find the lowest Y position among left column nodes
29
+ const maxY = Math.max(...nodesWithNoDeps.map(n => n.y + n.height));
30
+ return { x: START_X, y: maxY + VERTICAL_GAP };
31
+ }
32
+ /**
33
+ * Calculate position for a node that has dependencies
34
+ */
35
+ function calculateDependentPosition(canvas, blockerNodeIds) {
36
+ // Get blocker nodes
37
+ const blockerNodes = blockerNodeIds
38
+ .map(id => canvas.nodes.find(n => n.id === id))
39
+ .filter((n) => n !== undefined);
40
+ if (blockerNodes.length === 0) {
41
+ return calculateLeftColumnPosition(canvas);
42
+ }
43
+ // Calculate X: to the right of the rightmost blocker
44
+ const maxBlockerX = Math.max(...blockerNodes.map(n => n.x + n.width));
45
+ const newX = maxBlockerX + HORIZONTAL_GAP;
46
+ // Calculate Y: average of blocker Y positions
47
+ const avgBlockerY = average(blockerNodes.map(n => n.y));
48
+ // Check for collisions and find available Y
49
+ const newY = findAvailableY(canvas, newX, avgBlockerY);
50
+ return { x: newX, y: newY };
51
+ }
52
+ /**
53
+ * Get all nodes that have no incoming edges (dependencies)
54
+ */
55
+ function getNodesWithNoDependencies(canvas) {
56
+ const nodesWithIncoming = new Set(canvas.edges.map(e => e.toNode));
57
+ return canvas.nodes.filter(n => !nodesWithIncoming.has(n.id));
58
+ }
59
+ /**
60
+ * Find an available Y position at the given X coordinate
61
+ */
62
+ function findAvailableY(canvas, x, preferredY) {
63
+ // Get nodes in the same column (overlapping X range)
64
+ const nodesInColumn = canvas.nodes.filter(n => {
65
+ const nodeRight = n.x + n.width;
66
+ const targetRight = x + NODE_WIDTH;
67
+ return !(nodeRight < x || n.x > targetRight);
68
+ });
69
+ if (nodesInColumn.length === 0) {
70
+ return preferredY;
71
+ }
72
+ // Sort by Y position
73
+ nodesInColumn.sort((a, b) => a.y - b.y);
74
+ // Try preferred Y first
75
+ if (!hasCollision(nodesInColumn, preferredY)) {
76
+ return preferredY;
77
+ }
78
+ // Try positions above and below preferred Y
79
+ for (let offset = VERTICAL_GAP + NODE_HEIGHT; offset < 10000; offset += VERTICAL_GAP + NODE_HEIGHT) {
80
+ // Try below
81
+ const belowY = preferredY + offset;
82
+ if (!hasCollision(nodesInColumn, belowY)) {
83
+ return belowY;
84
+ }
85
+ // Try above
86
+ const aboveY = preferredY - offset;
87
+ if (aboveY >= 0 && !hasCollision(nodesInColumn, aboveY)) {
88
+ return aboveY;
89
+ }
90
+ }
91
+ // Fallback: place at the bottom
92
+ const maxY = Math.max(...nodesInColumn.map(n => n.y + n.height));
93
+ return maxY + VERTICAL_GAP;
94
+ }
95
+ /**
96
+ * Check if placing a node at Y would collide with existing nodes
97
+ */
98
+ function hasCollision(nodes, y) {
99
+ const top = y;
100
+ const bottom = y + NODE_HEIGHT;
101
+ return nodes.some(n => {
102
+ const nodeTop = n.y;
103
+ const nodeBottom = n.y + n.height;
104
+ return !(bottom < nodeTop || top > nodeBottom);
105
+ });
106
+ }
107
+ /**
108
+ * Calculate average of numbers
109
+ */
110
+ function average(numbers) {
111
+ if (numbers.length === 0)
112
+ return 0;
113
+ return numbers.reduce((sum, n) => sum + n, 0) / numbers.length;
114
+ }
115
+ /**
116
+ * Recalculate position for an existing node based on its current dependencies
117
+ */
118
+ export function recalculatePosition(canvas, nodeId, dependsOnNodeIds) {
119
+ // Temporarily remove the node from canvas for position calculation
120
+ const canvasWithoutNode = {
121
+ nodes: canvas.nodes.filter(n => n.id !== nodeId),
122
+ edges: canvas.edges.filter(e => e.fromNode !== nodeId && e.toNode !== nodeId),
123
+ };
124
+ return calculatePosition(canvasWithoutNode, dependsOnNodeIds);
125
+ }
126
+ //# sourceMappingURL=positioning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"positioning.js","sourceRoot":"","sources":["../../src/utils/positioning.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "obsidian-accomplishments-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Model Context Protocol (MCP) server for managing structured project accomplishments in Obsidian",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "obsidian-accomplishments-mcp": "dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "start": "node dist/index.js",
14
+ "dev": "tsc --watch",
15
+ "test": "vitest",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "keywords": [
24
+ "mcp",
25
+ "model-context-protocol",
26
+ "mcp-server",
27
+ "obsidian",
28
+ "accomplishments",
29
+ "project-management",
30
+ "canvas"
31
+ ],
32
+ "author": "Ostan Labs",
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/ostanlabs/obsidian_mcp.git"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/ostanlabs/obsidian_mcp/issues"
40
+ },
41
+ "homepage": "https://github.com/ostanlabs/obsidian_mcp#readme",
42
+ "engines": {
43
+ "node": ">=18"
44
+ },
45
+ "dependencies": {
46
+ "@modelcontextprotocol/sdk": "^1.0.0",
47
+ "yaml": "^2.3.4",
48
+ "zod": "^3.22.4"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^20.10.0",
52
+ "typescript": "^5.3.0",
53
+ "vitest": "^1.0.0"
54
+ }
55
+ }
56
+