obsidian-accomplishments-mcp 0.1.10 → 0.1.12

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 (269) hide show
  1. package/README.md +156 -184
  2. package/dist/index.js +207 -38
  3. package/dist/index.js.map +1 -1
  4. package/dist/integration.test.d.ts +8 -0
  5. package/dist/integration.test.d.ts.map +1 -0
  6. package/dist/integration.test.js +979 -0
  7. package/dist/integration.test.js.map +1 -0
  8. package/dist/models/types.d.ts +1 -2
  9. package/dist/models/types.d.ts.map +1 -1
  10. package/dist/models/types.js.map +1 -1
  11. package/dist/models/v2-types.d.ts +460 -0
  12. package/dist/models/v2-types.d.ts.map +1 -0
  13. package/dist/models/v2-types.js +137 -0
  14. package/dist/models/v2-types.js.map +1 -0
  15. package/dist/models/v2-types.test.d.ts +5 -0
  16. package/dist/models/v2-types.test.d.ts.map +1 -0
  17. package/dist/models/v2-types.test.js +133 -0
  18. package/dist/models/v2-types.test.js.map +1 -0
  19. package/dist/parsers/canvas-parser.d.ts +1 -1
  20. package/dist/parsers/canvas-parser.d.ts.map +1 -1
  21. package/dist/parsers/canvas-parser.js +1 -1
  22. package/dist/parsers/canvas-parser.js.map +1 -1
  23. package/dist/parsers/markdown-parser.js +9 -9
  24. package/dist/parsers/markdown-parser.js.map +1 -1
  25. package/dist/services/v2/archive-manager.d.ts +96 -0
  26. package/dist/services/v2/archive-manager.d.ts.map +1 -0
  27. package/dist/services/v2/archive-manager.js +281 -0
  28. package/dist/services/v2/archive-manager.js.map +1 -0
  29. package/dist/services/v2/canvas-manager.d.ts +155 -0
  30. package/dist/services/v2/canvas-manager.d.ts.map +1 -0
  31. package/dist/services/v2/canvas-manager.js +540 -0
  32. package/dist/services/v2/canvas-manager.js.map +1 -0
  33. package/dist/services/v2/canvas-manager.test.d.ts +5 -0
  34. package/dist/services/v2/canvas-manager.test.d.ts.map +1 -0
  35. package/dist/services/v2/canvas-manager.test.js +327 -0
  36. package/dist/services/v2/canvas-manager.test.js.map +1 -0
  37. package/dist/services/v2/cascade-manager.d.ts +54 -0
  38. package/dist/services/v2/cascade-manager.d.ts.map +1 -0
  39. package/dist/services/v2/cascade-manager.js +220 -0
  40. package/dist/services/v2/cascade-manager.js.map +1 -0
  41. package/dist/services/v2/cycle-detector.d.ts +76 -0
  42. package/dist/services/v2/cycle-detector.d.ts.map +1 -0
  43. package/dist/services/v2/cycle-detector.js +183 -0
  44. package/dist/services/v2/cycle-detector.js.map +1 -0
  45. package/dist/services/v2/cycle-detector.test.d.ts +7 -0
  46. package/dist/services/v2/cycle-detector.test.d.ts.map +1 -0
  47. package/dist/services/v2/cycle-detector.test.js +125 -0
  48. package/dist/services/v2/cycle-detector.test.js.map +1 -0
  49. package/dist/services/v2/entity-parser.d.ts +54 -0
  50. package/dist/services/v2/entity-parser.d.ts.map +1 -0
  51. package/dist/services/v2/entity-parser.js +418 -0
  52. package/dist/services/v2/entity-parser.js.map +1 -0
  53. package/dist/services/v2/entity-parser.test.d.ts +5 -0
  54. package/dist/services/v2/entity-parser.test.d.ts.map +1 -0
  55. package/dist/services/v2/entity-parser.test.js +637 -0
  56. package/dist/services/v2/entity-parser.test.js.map +1 -0
  57. package/dist/services/v2/entity-serializer.d.ts +94 -0
  58. package/dist/services/v2/entity-serializer.d.ts.map +1 -0
  59. package/dist/services/v2/entity-serializer.js +583 -0
  60. package/dist/services/v2/entity-serializer.js.map +1 -0
  61. package/dist/services/v2/entity-serializer.test.d.ts +5 -0
  62. package/dist/services/v2/entity-serializer.test.d.ts.map +1 -0
  63. package/dist/services/v2/entity-serializer.test.js +241 -0
  64. package/dist/services/v2/entity-serializer.test.js.map +1 -0
  65. package/dist/services/v2/entity-validator.d.ts +65 -0
  66. package/dist/services/v2/entity-validator.d.ts.map +1 -0
  67. package/dist/services/v2/entity-validator.js +573 -0
  68. package/dist/services/v2/entity-validator.js.map +1 -0
  69. package/dist/services/v2/entity-validator.test.d.ts +5 -0
  70. package/dist/services/v2/entity-validator.test.d.ts.map +1 -0
  71. package/dist/services/v2/entity-validator.test.js +519 -0
  72. package/dist/services/v2/entity-validator.test.js.map +1 -0
  73. package/dist/services/v2/file-manager.d.ts +73 -0
  74. package/dist/services/v2/file-manager.d.ts.map +1 -0
  75. package/dist/services/v2/file-manager.js +310 -0
  76. package/dist/services/v2/file-manager.js.map +1 -0
  77. package/dist/services/v2/file-manager.test.d.ts +5 -0
  78. package/dist/services/v2/file-manager.test.d.ts.map +1 -0
  79. package/dist/services/v2/file-manager.test.js +339 -0
  80. package/dist/services/v2/file-manager.test.js.map +1 -0
  81. package/dist/services/v2/index-manager.d.ts +68 -0
  82. package/dist/services/v2/index-manager.d.ts.map +1 -0
  83. package/dist/services/v2/index-manager.js +228 -0
  84. package/dist/services/v2/index-manager.js.map +1 -0
  85. package/dist/services/v2/index-manager.test.d.ts +5 -0
  86. package/dist/services/v2/index-manager.test.d.ts.map +1 -0
  87. package/dist/services/v2/index-manager.test.js +386 -0
  88. package/dist/services/v2/index-manager.test.js.map +1 -0
  89. package/dist/services/v2/index-service.d.ts +82 -0
  90. package/dist/services/v2/index-service.d.ts.map +1 -0
  91. package/dist/services/v2/index-service.js +274 -0
  92. package/dist/services/v2/index-service.js.map +1 -0
  93. package/dist/services/v2/index-service.test.d.ts +5 -0
  94. package/dist/services/v2/index-service.test.d.ts.map +1 -0
  95. package/dist/services/v2/index-service.test.js +117 -0
  96. package/dist/services/v2/index-service.test.js.map +1 -0
  97. package/dist/services/v2/lifecycle-manager.d.ts +59 -0
  98. package/dist/services/v2/lifecycle-manager.d.ts.map +1 -0
  99. package/dist/services/v2/lifecycle-manager.js +310 -0
  100. package/dist/services/v2/lifecycle-manager.js.map +1 -0
  101. package/dist/services/v2/lifecycle-manager.test.d.ts +5 -0
  102. package/dist/services/v2/lifecycle-manager.test.d.ts.map +1 -0
  103. package/dist/services/v2/lifecycle-manager.test.js +141 -0
  104. package/dist/services/v2/lifecycle-manager.test.js.map +1 -0
  105. package/dist/services/v2/path-resolver.d.ts +64 -0
  106. package/dist/services/v2/path-resolver.d.ts.map +1 -0
  107. package/dist/services/v2/path-resolver.js +174 -0
  108. package/dist/services/v2/path-resolver.js.map +1 -0
  109. package/dist/services/v2/progress-computer.d.ts +46 -0
  110. package/dist/services/v2/progress-computer.d.ts.map +1 -0
  111. package/dist/services/v2/progress-computer.js +200 -0
  112. package/dist/services/v2/progress-computer.js.map +1 -0
  113. package/dist/services/v2/search-service.d.ts +68 -0
  114. package/dist/services/v2/search-service.d.ts.map +1 -0
  115. package/dist/services/v2/search-service.js +194 -0
  116. package/dist/services/v2/search-service.js.map +1 -0
  117. package/dist/services/v2/transitive-dependency-remover.d.ts +54 -0
  118. package/dist/services/v2/transitive-dependency-remover.d.ts.map +1 -0
  119. package/dist/services/v2/transitive-dependency-remover.js +156 -0
  120. package/dist/services/v2/transitive-dependency-remover.js.map +1 -0
  121. package/dist/services/v2/transitive-dependency-remover.test.d.ts +7 -0
  122. package/dist/services/v2/transitive-dependency-remover.test.d.ts.map +1 -0
  123. package/dist/services/v2/transitive-dependency-remover.test.js +119 -0
  124. package/dist/services/v2/transitive-dependency-remover.test.js.map +1 -0
  125. package/dist/services/v2/v2-runtime.d.ts +374 -0
  126. package/dist/services/v2/v2-runtime.d.ts.map +1 -0
  127. package/dist/services/v2/v2-runtime.js +1908 -0
  128. package/dist/services/v2/v2-runtime.js.map +1 -0
  129. package/dist/services/v2/v2-runtime.test.d.ts +5 -0
  130. package/dist/services/v2/v2-runtime.test.d.ts.map +1 -0
  131. package/dist/services/v2/v2-runtime.test.js +658 -0
  132. package/dist/services/v2/v2-runtime.test.js.map +1 -0
  133. package/dist/services/v2/workstream-normalizer.d.ts +59 -0
  134. package/dist/services/v2/workstream-normalizer.d.ts.map +1 -0
  135. package/dist/services/v2/workstream-normalizer.js +137 -0
  136. package/dist/services/v2/workstream-normalizer.js.map +1 -0
  137. package/dist/services/v2/workstream-normalizer.test.d.ts +7 -0
  138. package/dist/services/v2/workstream-normalizer.test.d.ts.map +1 -0
  139. package/dist/services/v2/workstream-normalizer.test.js +130 -0
  140. package/dist/services/v2/workstream-normalizer.test.js.map +1 -0
  141. package/dist/test-runner.d.ts +4 -1
  142. package/dist/test-runner.d.ts.map +1 -1
  143. package/dist/test-runner.js +44 -249
  144. package/dist/test-runner.js.map +1 -1
  145. package/dist/tools/batch-operations-tools.d.ts +54 -0
  146. package/dist/tools/batch-operations-tools.d.ts.map +1 -0
  147. package/dist/tools/batch-operations-tools.js +370 -0
  148. package/dist/tools/batch-operations-tools.js.map +1 -0
  149. package/dist/tools/decision-document-tools.d.ts +78 -0
  150. package/dist/tools/decision-document-tools.d.ts.map +1 -0
  151. package/dist/tools/decision-document-tools.js +260 -0
  152. package/dist/tools/decision-document-tools.js.map +1 -0
  153. package/dist/tools/entity-management-tools.d.ts +79 -0
  154. package/dist/tools/entity-management-tools.d.ts.map +1 -0
  155. package/dist/tools/entity-management-tools.js +851 -0
  156. package/dist/tools/entity-management-tools.js.map +1 -0
  157. package/dist/tools/entity-management-tools.test.d.ts +5 -0
  158. package/dist/tools/entity-management-tools.test.d.ts.map +1 -0
  159. package/dist/tools/entity-management-tools.test.js +530 -0
  160. package/dist/tools/entity-management-tools.test.js.map +1 -0
  161. package/dist/tools/index.d.ts +15 -331
  162. package/dist/tools/index.d.ts.map +1 -1
  163. package/dist/tools/index.js +510 -47
  164. package/dist/tools/index.js.map +1 -1
  165. package/dist/tools/index.test.d.ts +8 -0
  166. package/dist/tools/index.test.d.ts.map +1 -0
  167. package/dist/tools/index.test.js +429 -0
  168. package/dist/tools/index.test.js.map +1 -0
  169. package/dist/tools/project-understanding-tools.d.ts +75 -0
  170. package/dist/tools/project-understanding-tools.d.ts.map +1 -0
  171. package/dist/tools/project-understanding-tools.js +751 -0
  172. package/dist/tools/project-understanding-tools.js.map +1 -0
  173. package/dist/tools/search-navigation-tools.d.ts +77 -0
  174. package/dist/tools/search-navigation-tools.d.ts.map +1 -0
  175. package/dist/tools/search-navigation-tools.js +379 -0
  176. package/dist/tools/search-navigation-tools.js.map +1 -0
  177. package/dist/tools/tool-types.d.ts +703 -0
  178. package/dist/tools/tool-types.d.ts.map +1 -0
  179. package/dist/tools/tool-types.js +7 -0
  180. package/dist/tools/tool-types.js.map +1 -0
  181. package/dist/utils/config.d.ts +0 -4
  182. package/dist/utils/config.d.ts.map +1 -1
  183. package/dist/utils/config.js +2 -19
  184. package/dist/utils/config.js.map +1 -1
  185. package/package.json +16 -1
  186. package/dist/services/accomplishment-service.d.ts +0 -33
  187. package/dist/services/accomplishment-service.d.ts.map +0 -1
  188. package/dist/services/accomplishment-service.js +0 -296
  189. package/dist/services/accomplishment-service.js.map +0 -1
  190. package/dist/services/canvas-service.d.ts +0 -96
  191. package/dist/services/canvas-service.d.ts.map +0 -1
  192. package/dist/services/canvas-service.js +0 -231
  193. package/dist/services/canvas-service.js.map +0 -1
  194. package/dist/services/context-doc-service.d.ts +0 -70
  195. package/dist/services/context-doc-service.d.ts.map +0 -1
  196. package/dist/services/context-doc-service.js +0 -229
  197. package/dist/services/context-doc-service.js.map +0 -1
  198. package/dist/services/dependency-service.d.ts +0 -22
  199. package/dist/services/dependency-service.d.ts.map +0 -1
  200. package/dist/services/dependency-service.js +0 -99
  201. package/dist/services/dependency-service.js.map +0 -1
  202. package/dist/services/status-indicator-service.d.ts +0 -40
  203. package/dist/services/status-indicator-service.d.ts.map +0 -1
  204. package/dist/services/status-indicator-service.js +0 -173
  205. package/dist/services/status-indicator-service.js.map +0 -1
  206. package/dist/services/task-service.d.ts +0 -32
  207. package/dist/services/task-service.d.ts.map +0 -1
  208. package/dist/services/task-service.js +0 -152
  209. package/dist/services/task-service.js.map +0 -1
  210. package/dist/test-real-vault.d.ts +0 -6
  211. package/dist/test-real-vault.d.ts.map +0 -1
  212. package/dist/test-real-vault.js +0 -30
  213. package/dist/test-real-vault.js.map +0 -1
  214. package/dist/tools/batch-operations.d.ts +0 -246
  215. package/dist/tools/batch-operations.d.ts.map +0 -1
  216. package/dist/tools/batch-operations.js +0 -235
  217. package/dist/tools/batch-operations.js.map +0 -1
  218. package/dist/tools/get-accomplishment.d.ts +0 -42
  219. package/dist/tools/get-accomplishment.d.ts.map +0 -1
  220. package/dist/tools/get-accomplishment.js +0 -93
  221. package/dist/tools/get-accomplishment.js.map +0 -1
  222. package/dist/tools/get-accomplishments-graph.d.ts +0 -26
  223. package/dist/tools/get-accomplishments-graph.d.ts.map +0 -1
  224. package/dist/tools/get-accomplishments-graph.js +0 -137
  225. package/dist/tools/get-accomplishments-graph.js.map +0 -1
  226. package/dist/tools/get-blocked-items.d.ts +0 -15
  227. package/dist/tools/get-blocked-items.d.ts.map +0 -1
  228. package/dist/tools/get-blocked-items.js +0 -73
  229. package/dist/tools/get-blocked-items.js.map +0 -1
  230. package/dist/tools/get-current-work.d.ts +0 -15
  231. package/dist/tools/get-current-work.d.ts.map +0 -1
  232. package/dist/tools/get-current-work.js +0 -68
  233. package/dist/tools/get-current-work.js.map +0 -1
  234. package/dist/tools/get-project-status.d.ts +0 -26
  235. package/dist/tools/get-project-status.d.ts.map +0 -1
  236. package/dist/tools/get-project-status.js +0 -98
  237. package/dist/tools/get-project-status.js.map +0 -1
  238. package/dist/tools/get-ready-to-start.d.ts +0 -15
  239. package/dist/tools/get-ready-to-start.d.ts.map +0 -1
  240. package/dist/tools/get-ready-to-start.js +0 -47
  241. package/dist/tools/get-ready-to-start.js.map +0 -1
  242. package/dist/tools/list-accomplishments.d.ts +0 -42
  243. package/dist/tools/list-accomplishments.d.ts.map +0 -1
  244. package/dist/tools/list-accomplishments.js +0 -40
  245. package/dist/tools/list-accomplishments.js.map +0 -1
  246. package/dist/tools/manage-accomplishment.d.ts +0 -147
  247. package/dist/tools/manage-accomplishment.d.ts.map +0 -1
  248. package/dist/tools/manage-accomplishment.js +0 -153
  249. package/dist/tools/manage-accomplishment.js.map +0 -1
  250. package/dist/tools/manage-dependency.d.ts +0 -41
  251. package/dist/tools/manage-dependency.d.ts.map +0 -1
  252. package/dist/tools/manage-dependency.js +0 -66
  253. package/dist/tools/manage-dependency.js.map +0 -1
  254. package/dist/tools/manage-task.d.ts +0 -119
  255. package/dist/tools/manage-task.d.ts.map +0 -1
  256. package/dist/tools/manage-task.js +0 -126
  257. package/dist/tools/manage-task.js.map +0 -1
  258. package/dist/tools/reconcile-canvas.d.ts +0 -33
  259. package/dist/tools/reconcile-canvas.d.ts.map +0 -1
  260. package/dist/tools/reconcile-canvas.js +0 -41
  261. package/dist/tools/reconcile-canvas.js.map +0 -1
  262. package/dist/tools/set-work-focus.d.ts +0 -48
  263. package/dist/tools/set-work-focus.d.ts.map +0 -1
  264. package/dist/tools/set-work-focus.js +0 -78
  265. package/dist/tools/set-work-focus.js.map +0 -1
  266. package/dist/tools/sync-dependencies.d.ts +0 -33
  267. package/dist/tools/sync-dependencies.d.ts.map +0 -1
  268. package/dist/tools/sync-dependencies.js +0 -144
  269. package/dist/tools/sync-dependencies.js.map +0 -1
@@ -0,0 +1,94 @@
1
+ /**
2
+ * V2 Entity Serializer
3
+ *
4
+ * Serializes Entity objects to markdown files with YAML frontmatter.
5
+ */
6
+ import { Entity } from '../../models/v2-types.js';
7
+ export interface SerializeOptions {
8
+ /** Include content/body section */
9
+ includeContent?: boolean;
10
+ /** Pretty print YAML (default: true) */
11
+ prettyPrint?: boolean;
12
+ /** Fields to exclude from frontmatter */
13
+ excludeFields?: string[];
14
+ }
15
+ /**
16
+ * Serializes Entity objects to markdown with YAML frontmatter.
17
+ */
18
+ export declare class EntitySerializer {
19
+ /** Serialize an Entity to markdown string */
20
+ serialize(entity: Entity, options?: SerializeOptions): string;
21
+ /** Convert entity to frontmatter object */
22
+ private entityToFrontmatter;
23
+ /** Get base frontmatter fields common to all entities */
24
+ private getBaseFrontmatter;
25
+ /** Get milestone-specific frontmatter */
26
+ private getMilestoneFrontmatter;
27
+ /** Get story-specific frontmatter */
28
+ private getStoryFrontmatter;
29
+ /** Get task-specific frontmatter */
30
+ private getTaskFrontmatter;
31
+ /** Get decision-specific frontmatter */
32
+ private getDecisionFrontmatter;
33
+ /** Get document-specific frontmatter */
34
+ private getDocumentFrontmatter;
35
+ /** Get feature-specific frontmatter */
36
+ private getFeatureFrontmatter;
37
+ /** Get content/body from entity */
38
+ private getEntityContent;
39
+ /** Build milestone content with objective and related queries */
40
+ private buildMilestoneContent;
41
+ /** Build story content with outcome and notes */
42
+ private buildStoryContent;
43
+ /** Build task content with description and notes */
44
+ private buildTaskContent;
45
+ /** Build decision content with context, decision, and rationale */
46
+ private buildDecisionContent;
47
+ /** Build document content */
48
+ private buildDocumentContent;
49
+ /** Build feature content */
50
+ private buildFeatureContent;
51
+ /** Build related section with Dataview queries for milestone/story/task */
52
+ private buildRelatedSection;
53
+ /** Build related section for decisions */
54
+ private buildDecisionRelatedSection;
55
+ /** Build related section for documents */
56
+ private buildDocumentRelatedSection;
57
+ /** Build related section for features */
58
+ private buildFeatureRelatedSection;
59
+ /** Convert object to YAML string */
60
+ private toYaml;
61
+ /** Convert a value to YAML representation */
62
+ private valueToYaml;
63
+ /** Convert array of objects to YAML */
64
+ private arrayOfObjectsToYaml;
65
+ /** Convert object to YAML */
66
+ private objectToYaml;
67
+ /** Check if string needs quoting */
68
+ private needsQuoting;
69
+ /** Escape string for YAML */
70
+ private escapeString;
71
+ /** Serialize inline tasks for frontmatter */
72
+ private serializeInlineTasks;
73
+ /** Remove undefined/null values from object */
74
+ private cleanObject;
75
+ /**
76
+ * Strip dataview blocks and their section headers from content.
77
+ * This prevents duplication when re-serializing entities.
78
+ *
79
+ * Removes:
80
+ * - Dataview code blocks (```dataview ... ```)
81
+ * - Section headers that precede dataview blocks (## 🔗 Implemented By, etc.)
82
+ */
83
+ private stripDataviewBlocks;
84
+ }
85
+ /**
86
+ * Generate CSS classes for visual differentiation on canvas.
87
+ *
88
+ * CSS classes control:
89
+ * - Border thickness: entity type (milestone=4px, story=2px, task=1px)
90
+ * - Border color: workstream type
91
+ * - Visual state: status indicators
92
+ */
93
+ export declare function generateCssClasses(entity: Entity): string[];
94
+ //# sourceMappingURL=entity-serializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-serializer.d.ts","sourceRoot":"","sources":["../../../src/services/v2/entity-serializer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,MAAM,EAQP,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wCAAwC;IACxC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAMD;;GAEG;AACH,qBAAa,gBAAgB;IAK3B,6CAA6C;IAC7C,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM;IAoBjE,2CAA2C;IAC3C,OAAO,CAAC,mBAAmB;IAoC3B,yDAAyD;IACzD,OAAO,CAAC,kBAAkB;IAe1B,yCAAyC;IACzC,OAAO,CAAC,uBAAuB;IAgB/B,qCAAqC;IACrC,OAAO,CAAC,mBAAmB;IAgB3B,oCAAoC;IACpC,OAAO,CAAC,kBAAkB;IAe1B,wCAAwC;IACxC,OAAO,CAAC,sBAAsB;IAe9B,wCAAwC;IACxC,OAAO,CAAC,sBAAsB;IAkB9B,uCAAuC;IACvC,OAAO,CAAC,qBAAqB;IAkB7B,mCAAmC;IACnC,OAAO,CAAC,gBAAgB;IAiBxB,iEAAiE;IACjE,OAAO,CAAC,qBAAqB;IAa7B,iDAAiD;IACjD,OAAO,CAAC,iBAAiB;IAiBzB,oDAAoD;IACpD,OAAO,CAAC,gBAAgB;IAqBxB,mEAAmE;IACnE,OAAO,CAAC,oBAAoB;IAqB5B,6BAA6B;IAC7B,OAAO,CAAC,oBAAoB;IAiB5B,4BAA4B;IAC5B,OAAO,CAAC,mBAAmB;IAiB3B,2EAA2E;IAC3E,OAAO,CAAC,mBAAmB;IAwC3B,0CAA0C;IAC1C,OAAO,CAAC,2BAA2B;IAmBnC,0CAA0C;IAC1C,OAAO,CAAC,2BAA2B;IAoBnC,yCAAyC;IACzC,OAAO,CAAC,0BAA0B;IAiClC,oCAAoC;IACpC,OAAO,CAAC,MAAM;IAad,6CAA6C;IAC7C,OAAO,CAAC,WAAW;IAqCnB,uCAAuC;IACvC,OAAO,CAAC,oBAAoB;IAoB5B,6BAA6B;IAC7B,OAAO,CAAC,YAAY;IAYpB,oCAAoC;IACpC,OAAO,CAAC,YAAY;IAUpB,6BAA6B;IAC7B,OAAO,CAAC,YAAY;IAYpB,6CAA6C;IAC7C,OAAO,CAAC,oBAAoB;IAW5B,+CAA+C;IAC/C,OAAO,CAAC,WAAW;IAYnB;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;CAqB5B;AAMD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAwB3D"}
@@ -0,0 +1,583 @@
1
+ /**
2
+ * V2 Entity Serializer
3
+ *
4
+ * Serializes Entity objects to markdown files with YAML frontmatter.
5
+ */
6
+ // =============================================================================
7
+ // Entity Serializer Class
8
+ // =============================================================================
9
+ /**
10
+ * Serializes Entity objects to markdown with YAML frontmatter.
11
+ */
12
+ export class EntitySerializer {
13
+ // ---------------------------------------------------------------------------
14
+ // Main Serialize Method
15
+ // ---------------------------------------------------------------------------
16
+ /** Serialize an Entity to markdown string */
17
+ serialize(entity, options = {}) {
18
+ const { includeContent = true, excludeFields = [] } = options;
19
+ // Get frontmatter data based on entity type
20
+ const frontmatter = this.entityToFrontmatter(entity, excludeFields);
21
+ // Build YAML frontmatter
22
+ const yaml = this.toYaml(frontmatter);
23
+ // Get content/body
24
+ const content = includeContent ? this.getEntityContent(entity) : '';
25
+ // Combine frontmatter and content
26
+ return `---\n${yaml}---\n${content ? `\n${content}` : ''}`;
27
+ }
28
+ // ---------------------------------------------------------------------------
29
+ // Entity to Frontmatter Conversion
30
+ // ---------------------------------------------------------------------------
31
+ /** Convert entity to frontmatter object */
32
+ entityToFrontmatter(entity, excludeFields) {
33
+ const base = this.getBaseFrontmatter(entity);
34
+ let specific;
35
+ switch (entity.type) {
36
+ case 'milestone':
37
+ specific = this.getMilestoneFrontmatter(entity);
38
+ break;
39
+ case 'story':
40
+ specific = this.getStoryFrontmatter(entity);
41
+ break;
42
+ case 'task':
43
+ specific = this.getTaskFrontmatter(entity);
44
+ break;
45
+ case 'decision':
46
+ specific = this.getDecisionFrontmatter(entity);
47
+ break;
48
+ case 'document':
49
+ specific = this.getDocumentFrontmatter(entity);
50
+ break;
51
+ case 'feature':
52
+ specific = this.getFeatureFrontmatter(entity);
53
+ break;
54
+ }
55
+ const combined = { ...base, ...specific };
56
+ // Remove excluded fields
57
+ for (const field of excludeFields) {
58
+ delete combined[field];
59
+ }
60
+ // Remove undefined/null values
61
+ return this.cleanObject(combined);
62
+ }
63
+ /** Get base frontmatter fields common to all entities */
64
+ getBaseFrontmatter(entity) {
65
+ return {
66
+ id: entity.id,
67
+ type: entity.type,
68
+ title: entity.title,
69
+ workstream: entity.workstream,
70
+ status: entity.status,
71
+ archived: entity.archived || undefined,
72
+ canvas_source: entity.canvas_source || undefined,
73
+ cssclasses: entity.cssclasses?.length ? entity.cssclasses : undefined,
74
+ created_at: entity.created_at,
75
+ updated_at: entity.updated_at,
76
+ };
77
+ }
78
+ /** Get milestone-specific frontmatter */
79
+ getMilestoneFrontmatter(entity) {
80
+ return {
81
+ target_date: entity.target_date,
82
+ owner: entity.owner,
83
+ priority: entity.priority,
84
+ // Hierarchy
85
+ children: entity.children?.length ? entity.children : undefined,
86
+ // Dependencies
87
+ depends_on: entity.depends_on?.length ? entity.depends_on : undefined,
88
+ blocks: entity.blocks?.length ? entity.blocks : undefined,
89
+ // Implementation
90
+ implements: entity.implements?.length ? entity.implements : undefined,
91
+ success_criteria: entity.success_criteria?.length ? entity.success_criteria : undefined,
92
+ };
93
+ }
94
+ /** Get story-specific frontmatter */
95
+ getStoryFrontmatter(entity) {
96
+ return {
97
+ priority: entity.priority,
98
+ // Hierarchy
99
+ parent: entity.parent,
100
+ children: entity.children?.length ? entity.children : undefined,
101
+ // Dependencies
102
+ depends_on: entity.depends_on?.length ? entity.depends_on : undefined,
103
+ blocks: entity.blocks?.length ? entity.blocks : undefined,
104
+ // Implementation
105
+ implements: entity.implements?.length ? entity.implements : undefined,
106
+ acceptance_criteria: entity.acceptance_criteria?.length ? entity.acceptance_criteria : undefined,
107
+ tasks: entity.tasks?.length ? this.serializeInlineTasks(entity.tasks) : undefined,
108
+ };
109
+ }
110
+ /** Get task-specific frontmatter */
111
+ getTaskFrontmatter(entity) {
112
+ return {
113
+ // Hierarchy
114
+ parent: entity.parent,
115
+ // Dependencies
116
+ depends_on: entity.depends_on?.length ? entity.depends_on : undefined,
117
+ blocks: entity.blocks?.length ? entity.blocks : undefined,
118
+ // Task-specific
119
+ goal: entity.goal,
120
+ estimate_hrs: entity.estimate_hrs,
121
+ actual_hrs: entity.actual_hrs,
122
+ assignee: entity.assignee,
123
+ };
124
+ }
125
+ /** Get decision-specific frontmatter */
126
+ getDecisionFrontmatter(entity) {
127
+ return {
128
+ decided_by: entity.decided_by,
129
+ decided_on: entity.decided_on,
130
+ // Dependencies
131
+ depends_on: entity.depends_on?.length ? entity.depends_on : undefined,
132
+ // Entities affected by this decision (renamed from blocks)
133
+ affects: entity.affects?.length ? entity.affects : undefined,
134
+ // Supersession
135
+ supersedes: entity.supersedes,
136
+ superseded_by: entity.superseded_by,
137
+ alternatives: entity.alternatives?.length ? entity.alternatives : undefined,
138
+ };
139
+ }
140
+ /** Get document-specific frontmatter */
141
+ getDocumentFrontmatter(entity) {
142
+ return {
143
+ doc_type: entity.doc_type,
144
+ version: entity.version,
145
+ owner: entity.owner,
146
+ // Dependencies
147
+ depends_on: entity.depends_on?.length ? entity.depends_on : undefined,
148
+ blocks: entity.blocks?.length ? entity.blocks : undefined,
149
+ // Implementation
150
+ implemented_by: entity.implemented_by?.length ? entity.implemented_by : undefined,
151
+ // Feature relationships
152
+ documents: entity.documents?.length ? entity.documents : undefined,
153
+ // Versioning
154
+ previous_version: entity.previous_version,
155
+ next_version: entity.next_version,
156
+ };
157
+ }
158
+ /** Get feature-specific frontmatter */
159
+ getFeatureFrontmatter(entity) {
160
+ return {
161
+ user_story: entity.user_story,
162
+ tier: entity.tier,
163
+ phase: entity.phase,
164
+ // Relationships (auto-synced)
165
+ implemented_by: entity.implemented_by?.length ? entity.implemented_by : undefined,
166
+ documented_by: entity.documented_by?.length ? entity.documented_by : undefined,
167
+ decided_by: entity.decided_by?.length ? entity.decided_by : undefined,
168
+ // Test references
169
+ test_refs: entity.test_refs?.length ? entity.test_refs : undefined,
170
+ };
171
+ }
172
+ // ---------------------------------------------------------------------------
173
+ // Content Extraction
174
+ // ---------------------------------------------------------------------------
175
+ /** Get content/body from entity */
176
+ getEntityContent(entity) {
177
+ switch (entity.type) {
178
+ case 'milestone':
179
+ return this.buildMilestoneContent(entity);
180
+ case 'story':
181
+ return this.buildStoryContent(entity);
182
+ case 'task':
183
+ return this.buildTaskContent(entity);
184
+ case 'decision':
185
+ return this.buildDecisionContent(entity);
186
+ case 'document':
187
+ return this.buildDocumentContent(entity);
188
+ case 'feature':
189
+ return this.buildFeatureContent(entity);
190
+ }
191
+ }
192
+ /** Build milestone content with objective and related queries */
193
+ buildMilestoneContent(entity) {
194
+ const sections = [];
195
+ if (entity.objective) {
196
+ sections.push(entity.objective);
197
+ }
198
+ // Add Dataview queries for related items
199
+ sections.push(this.buildRelatedSection(entity.id, 'milestone'));
200
+ return sections.join('\n\n');
201
+ }
202
+ /** Build story content with outcome and notes */
203
+ buildStoryContent(entity) {
204
+ const sections = [];
205
+ if (entity.outcome) {
206
+ sections.push(`## Outcome\n\n${entity.outcome}`);
207
+ }
208
+ if (entity.notes) {
209
+ sections.push(`## Notes\n\n${entity.notes}`);
210
+ }
211
+ // Add Dataview queries for related items
212
+ sections.push(this.buildRelatedSection(entity.id, 'story'));
213
+ return sections.join('\n\n');
214
+ }
215
+ /** Build task content with description and notes */
216
+ buildTaskContent(entity) {
217
+ const sections = [];
218
+ if (entity.description) {
219
+ sections.push(`## Description\n\n${entity.description}`);
220
+ }
221
+ if (entity.technical_notes) {
222
+ sections.push(`## Technical Notes\n\n${entity.technical_notes}`);
223
+ }
224
+ if (entity.notes) {
225
+ sections.push(`## Notes\n\n${entity.notes}`);
226
+ }
227
+ // Add Dataview queries for related items
228
+ sections.push(this.buildRelatedSection(entity.id, 'task'));
229
+ return sections.join('\n\n');
230
+ }
231
+ /** Build decision content with context, decision, and rationale */
232
+ buildDecisionContent(entity) {
233
+ const sections = [];
234
+ if (entity.context) {
235
+ sections.push(`## Context\n\n${entity.context}`);
236
+ }
237
+ if (entity.decision) {
238
+ sections.push(`## Decision\n\n${entity.decision}`);
239
+ }
240
+ if (entity.rationale) {
241
+ sections.push(`## Rationale\n\n${entity.rationale}`);
242
+ }
243
+ // Add Dataview query for entities this decision enables
244
+ sections.push(this.buildDecisionRelatedSection(entity.id));
245
+ return sections.join('\n\n');
246
+ }
247
+ /** Build document content */
248
+ buildDocumentContent(entity) {
249
+ const sections = [];
250
+ if (entity.content) {
251
+ // Strip existing dataview blocks to prevent duplication
252
+ const cleanContent = this.stripDataviewBlocks(entity.content);
253
+ if (cleanContent) {
254
+ sections.push(cleanContent);
255
+ }
256
+ }
257
+ // Add Dataview query for entities implementing this document
258
+ sections.push(this.buildDocumentRelatedSection(entity.id));
259
+ return sections.join('\n\n');
260
+ }
261
+ /** Build feature content */
262
+ buildFeatureContent(entity) {
263
+ const sections = [];
264
+ if (entity.content) {
265
+ // Strip existing dataview blocks to prevent duplication
266
+ const cleanContent = this.stripDataviewBlocks(entity.content);
267
+ if (cleanContent) {
268
+ sections.push(cleanContent);
269
+ }
270
+ }
271
+ // Add Dataview queries for related items
272
+ sections.push(this.buildFeatureRelatedSection(entity.id));
273
+ return sections.join('\n\n');
274
+ }
275
+ /** Build related section with Dataview queries for milestone/story/task */
276
+ buildRelatedSection(entityId, entityType) {
277
+ const sections = [];
278
+ // Documents this entity implements (milestone, story only)
279
+ if (entityType === 'milestone' || entityType === 'story') {
280
+ sections.push(`## 📄 Documents
281
+
282
+ \`\`\`dataview
283
+ TABLE title as "Document", document_type as "Type", version as "Version"
284
+ FROM "documents"
285
+ WHERE contains(this.implements, id)
286
+ SORT title ASC
287
+ \`\`\``);
288
+ }
289
+ // Decisions that enable this entity
290
+ sections.push(`## 🎯 Decisions
291
+
292
+ \`\`\`dataview
293
+ TABLE title as "Decision", status as "Status", decided_at as "Date"
294
+ FROM "decisions"
295
+ WHERE contains(enables, "${entityId}")
296
+ SORT decided_at DESC
297
+ \`\`\``);
298
+ // For tasks: also show decisions this task depends on
299
+ if (entityType === 'task') {
300
+ sections.push(`### Blocking Decisions
301
+
302
+ \`\`\`dataview
303
+ TABLE title as "Decision", status as "Status"
304
+ FROM "decisions"
305
+ WHERE contains(this.depends_on, id)
306
+ SORT title ASC
307
+ \`\`\``);
308
+ }
309
+ return sections.join('\n\n');
310
+ }
311
+ /** Build related section for decisions */
312
+ buildDecisionRelatedSection(decisionId) {
313
+ return `## 🔗 Enabled Entities
314
+
315
+ \`\`\`dataview
316
+ TABLE title as "Entity", type as "Type", status as "Status"
317
+ WHERE contains(file.frontmatter.depends_on, "${decisionId}") OR contains(file.frontmatter.enabled_by, "${decisionId}")
318
+ SORT type ASC, title ASC
319
+ \`\`\`
320
+
321
+ ## 📄 Affected Documents
322
+
323
+ \`\`\`dataview
324
+ TABLE title as "Document", version as "Version"
325
+ FROM "documents"
326
+ WHERE contains(this.affects_documents, id)
327
+ SORT title ASC
328
+ \`\`\``;
329
+ }
330
+ /** Build related section for documents */
331
+ buildDocumentRelatedSection(documentId) {
332
+ return `## 🔗 Implemented By
333
+
334
+ \`\`\`dataview
335
+ TABLE title as "Entity", type as "Type", status as "Status"
336
+ FROM ""
337
+ WHERE contains(implements, "${documentId}")
338
+ SORT type ASC, title ASC
339
+ \`\`\`
340
+
341
+ ## 🎯 Related Decisions
342
+
343
+ \`\`\`dataview
344
+ TABLE title as "Decision", status as "Status", decided_at as "Date"
345
+ FROM "decisions"
346
+ WHERE contains(affects_documents, "${documentId}")
347
+ SORT decided_at DESC
348
+ \`\`\``;
349
+ }
350
+ /** Build related section for features */
351
+ buildFeatureRelatedSection(featureId) {
352
+ return `## 🔗 Implemented By
353
+
354
+ \`\`\`dataview
355
+ TABLE title as "Entity", type as "Type", status as "Status"
356
+ FROM ""
357
+ WHERE contains(implements, "${featureId}")
358
+ SORT type ASC, title ASC
359
+ \`\`\`
360
+
361
+ ## 📄 Documentation
362
+
363
+ \`\`\`dataview
364
+ TABLE title as "Document", doc_type as "Type", status as "Status"
365
+ FROM "documents"
366
+ WHERE contains(documents, "${featureId}")
367
+ SORT title ASC
368
+ \`\`\`
369
+
370
+ ## 🎯 Related Decisions
371
+
372
+ \`\`\`dataview
373
+ TABLE title as "Decision", status as "Status", decided_on as "Date"
374
+ FROM "decisions"
375
+ WHERE contains(affects, "${featureId}")
376
+ SORT decided_on DESC
377
+ \`\`\``;
378
+ }
379
+ // ---------------------------------------------------------------------------
380
+ // YAML Serialization
381
+ // ---------------------------------------------------------------------------
382
+ /** Convert object to YAML string */
383
+ toYaml(obj) {
384
+ const lines = [];
385
+ for (const [key, value] of Object.entries(obj)) {
386
+ if (value === undefined || value === null)
387
+ continue;
388
+ const yamlValue = this.valueToYaml(value, 0);
389
+ lines.push(`${key}: ${yamlValue}`);
390
+ }
391
+ return lines.join('\n') + '\n';
392
+ }
393
+ /** Convert a value to YAML representation */
394
+ valueToYaml(value, indent) {
395
+ if (value === null || value === undefined) {
396
+ return 'null';
397
+ }
398
+ if (typeof value === 'string') {
399
+ // Check if string needs quoting
400
+ if (this.needsQuoting(value)) {
401
+ return `"${this.escapeString(value)}"`;
402
+ }
403
+ return value;
404
+ }
405
+ if (typeof value === 'number' || typeof value === 'boolean') {
406
+ return String(value);
407
+ }
408
+ if (Array.isArray(value)) {
409
+ if (value.length === 0)
410
+ return '[]';
411
+ // Check if array contains objects
412
+ if (typeof value[0] === 'object' && value[0] !== null) {
413
+ return this.arrayOfObjectsToYaml(value, indent);
414
+ }
415
+ // Simple array - inline format
416
+ const items = value.map(v => this.valueToYaml(v, indent));
417
+ return `[${items.join(', ')}]`;
418
+ }
419
+ if (typeof value === 'object') {
420
+ return this.objectToYaml(value, indent + 2);
421
+ }
422
+ return String(value);
423
+ }
424
+ /** Convert array of objects to YAML */
425
+ arrayOfObjectsToYaml(arr, indent) {
426
+ const lines = [''];
427
+ const pad = ' '.repeat(indent + 2);
428
+ for (const item of arr) {
429
+ const entries = Object.entries(item);
430
+ if (entries.length === 0)
431
+ continue;
432
+ const [firstKey, firstValue] = entries[0];
433
+ lines.push(`${pad}- ${firstKey}: ${this.valueToYaml(firstValue, indent + 4)}`);
434
+ for (let i = 1; i < entries.length; i++) {
435
+ const [key, val] = entries[i];
436
+ lines.push(`${pad} ${key}: ${this.valueToYaml(val, indent + 4)}`);
437
+ }
438
+ }
439
+ return lines.join('\n');
440
+ }
441
+ /** Convert object to YAML */
442
+ objectToYaml(obj, indent) {
443
+ const lines = [''];
444
+ const pad = ' '.repeat(indent);
445
+ for (const [key, value] of Object.entries(obj)) {
446
+ if (value === undefined || value === null)
447
+ continue;
448
+ lines.push(`${pad}${key}: ${this.valueToYaml(value, indent)}`);
449
+ }
450
+ return lines.join('\n');
451
+ }
452
+ /** Check if string needs quoting */
453
+ needsQuoting(str) {
454
+ // Quote if contains special characters or looks like other types
455
+ if (/^[\d.]+$/.test(str))
456
+ return true; // Looks like number
457
+ if (/^(true|false|null|yes|no|on|off)$/i.test(str))
458
+ return true;
459
+ if (/[:#\[\]{}|>&*!?,]/.test(str))
460
+ return true;
461
+ if (str.includes('\n'))
462
+ return true;
463
+ if (str.startsWith(' ') || str.endsWith(' '))
464
+ return true;
465
+ return false;
466
+ }
467
+ /** Escape string for YAML */
468
+ escapeString(str) {
469
+ return str
470
+ .replace(/\\/g, '\\\\')
471
+ .replace(/"/g, '\\"')
472
+ .replace(/\n/g, '\\n')
473
+ .replace(/\t/g, '\\t');
474
+ }
475
+ // ---------------------------------------------------------------------------
476
+ // Helper Methods
477
+ // ---------------------------------------------------------------------------
478
+ /** Serialize inline tasks for frontmatter */
479
+ serializeInlineTasks(tasks) {
480
+ return tasks.map(task => ({
481
+ number: task.number,
482
+ name: task.name,
483
+ goal: task.goal,
484
+ status: task.status,
485
+ estimate_hrs: task.estimate_hrs,
486
+ description: task.description,
487
+ }));
488
+ }
489
+ /** Remove undefined/null values from object */
490
+ cleanObject(obj) {
491
+ const cleaned = {};
492
+ for (const [key, value] of Object.entries(obj)) {
493
+ if (value !== undefined && value !== null) {
494
+ cleaned[key] = value;
495
+ }
496
+ }
497
+ return cleaned;
498
+ }
499
+ /**
500
+ * Strip dataview blocks and their section headers from content.
501
+ * This prevents duplication when re-serializing entities.
502
+ *
503
+ * Removes:
504
+ * - Dataview code blocks (```dataview ... ```)
505
+ * - Section headers that precede dataview blocks (## 🔗 Implemented By, etc.)
506
+ */
507
+ stripDataviewBlocks(content) {
508
+ // Pattern to match section headers followed by dataview blocks
509
+ // Matches: ## Header\n\n```dataview...```
510
+ const sectionWithDataviewPattern = /^##\s+[^\n]+\n+```dataview[\s\S]*?```\n*/gm;
511
+ // Pattern to match standalone dataview blocks
512
+ const standaloneDataviewPattern = /```dataview[\s\S]*?```\n*/g;
513
+ let cleaned = content;
514
+ // First remove section headers with their dataview blocks
515
+ cleaned = cleaned.replace(sectionWithDataviewPattern, '');
516
+ // Then remove any remaining standalone dataview blocks
517
+ cleaned = cleaned.replace(standaloneDataviewPattern, '');
518
+ // Clean up excessive newlines
519
+ cleaned = cleaned.replace(/\n{3,}/g, '\n\n');
520
+ return cleaned.trim();
521
+ }
522
+ }
523
+ // =============================================================================
524
+ // CSS Classes Generator
525
+ // =============================================================================
526
+ /**
527
+ * Generate CSS classes for visual differentiation on canvas.
528
+ *
529
+ * CSS classes control:
530
+ * - Border thickness: entity type (milestone=4px, story=2px, task=1px)
531
+ * - Border color: workstream type
532
+ * - Visual state: status indicators
533
+ */
534
+ export function generateCssClasses(entity) {
535
+ const classes = [];
536
+ // Type class - controls border thickness and node size
537
+ classes.push(`canvas-${entity.type}`);
538
+ // Workstream class - controls border color
539
+ const workstream = getWorkstreamFromEntity(entity);
540
+ if (workstream) {
541
+ classes.push(`canvas-workstream-${normalizeForCss(workstream)}`);
542
+ }
543
+ // Status class - controls visual state (opacity, badges, etc.)
544
+ if (entity.status) {
545
+ classes.push(`canvas-status-${normalizeForCss(entity.status)}`);
546
+ }
547
+ // Priority class (optional, for milestones and stories)
548
+ const priority = getPriorityFromEntity(entity);
549
+ if (priority) {
550
+ classes.push(`canvas-priority-${normalizeForCss(priority)}`);
551
+ }
552
+ return classes;
553
+ }
554
+ /**
555
+ * Get workstream from entity for CSS class generation.
556
+ */
557
+ function getWorkstreamFromEntity(entity) {
558
+ return entity.workstream || null;
559
+ }
560
+ /**
561
+ * Get priority from entity if applicable.
562
+ */
563
+ function getPriorityFromEntity(entity) {
564
+ switch (entity.type) {
565
+ case 'milestone':
566
+ return entity.priority;
567
+ case 'story':
568
+ return entity.priority;
569
+ default:
570
+ return null;
571
+ }
572
+ }
573
+ /**
574
+ * Normalize a string for use in CSS class names.
575
+ * Converts to lowercase and replaces spaces with hyphens.
576
+ */
577
+ function normalizeForCss(value) {
578
+ return value
579
+ .toLowerCase()
580
+ .replace(/\s+/g, '-')
581
+ .replace(/[^a-z0-9-]/g, '');
582
+ }
583
+ //# sourceMappingURL=entity-serializer.js.map