@engramm/dev-workflow 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 (234) hide show
  1. package/dist/agents/context-builder.d.ts +11 -0
  2. package/dist/agents/context-builder.d.ts.map +1 -0
  3. package/dist/agents/context-builder.js +62 -0
  4. package/dist/agents/context-builder.js.map +1 -0
  5. package/dist/agents/loader.d.ts +3 -0
  6. package/dist/agents/loader.d.ts.map +1 -0
  7. package/dist/agents/loader.js +54 -0
  8. package/dist/agents/loader.js.map +1 -0
  9. package/dist/agents/registry.d.ts +10 -0
  10. package/dist/agents/registry.d.ts.map +1 -0
  11. package/dist/agents/registry.js +35 -0
  12. package/dist/agents/registry.js.map +1 -0
  13. package/dist/agents/types.d.ts +20 -0
  14. package/dist/agents/types.d.ts.map +1 -0
  15. package/dist/agents/types.js +2 -0
  16. package/dist/agents/types.js.map +1 -0
  17. package/dist/cli/agent.d.ts +2 -0
  18. package/dist/cli/agent.d.ts.map +1 -0
  19. package/dist/cli/agent.js +101 -0
  20. package/dist/cli/agent.js.map +1 -0
  21. package/dist/cli/config.d.ts +2 -0
  22. package/dist/cli/config.d.ts.map +1 -0
  23. package/dist/cli/config.js +100 -0
  24. package/dist/cli/config.js.map +1 -0
  25. package/dist/cli/doctor.d.ts +2 -0
  26. package/dist/cli/doctor.d.ts.map +1 -0
  27. package/dist/cli/doctor.js +123 -0
  28. package/dist/cli/doctor.js.map +1 -0
  29. package/dist/cli/index.d.ts +3 -0
  30. package/dist/cli/index.d.ts.map +1 -0
  31. package/dist/cli/index.js +94 -0
  32. package/dist/cli/index.js.map +1 -0
  33. package/dist/cli/init.d.ts +7 -0
  34. package/dist/cli/init.d.ts.map +1 -0
  35. package/dist/cli/init.js +177 -0
  36. package/dist/cli/init.js.map +1 -0
  37. package/dist/cli/run.d.ts +4 -0
  38. package/dist/cli/run.d.ts.map +1 -0
  39. package/dist/cli/run.js +191 -0
  40. package/dist/cli/run.js.map +1 -0
  41. package/dist/cli/search.d.ts +2 -0
  42. package/dist/cli/search.d.ts.map +1 -0
  43. package/dist/cli/search.js +75 -0
  44. package/dist/cli/search.js.map +1 -0
  45. package/dist/cli/serve.d.ts +2 -0
  46. package/dist/cli/serve.d.ts.map +1 -0
  47. package/dist/cli/serve.js +34 -0
  48. package/dist/cli/serve.js.map +1 -0
  49. package/dist/cli/status.d.ts +2 -0
  50. package/dist/cli/status.d.ts.map +1 -0
  51. package/dist/cli/status.js +89 -0
  52. package/dist/cli/status.js.map +1 -0
  53. package/dist/cli/task.d.ts +2 -0
  54. package/dist/cli/task.d.ts.map +1 -0
  55. package/dist/cli/task.js +153 -0
  56. package/dist/cli/task.js.map +1 -0
  57. package/dist/cli/vault-io.d.ts +3 -0
  58. package/dist/cli/vault-io.d.ts.map +1 -0
  59. package/dist/cli/vault-io.js +75 -0
  60. package/dist/cli/vault-io.js.map +1 -0
  61. package/dist/hooks/post-edit.d.ts +3 -0
  62. package/dist/hooks/post-edit.d.ts.map +1 -0
  63. package/dist/hooks/post-edit.js +43 -0
  64. package/dist/hooks/post-edit.js.map +1 -0
  65. package/dist/hooks/post-task.d.ts +3 -0
  66. package/dist/hooks/post-task.d.ts.map +1 -0
  67. package/dist/hooks/post-task.js +25 -0
  68. package/dist/hooks/post-task.js.map +1 -0
  69. package/dist/hooks/pre-compact.d.ts +7 -0
  70. package/dist/hooks/pre-compact.d.ts.map +1 -0
  71. package/dist/hooks/pre-compact.js +34 -0
  72. package/dist/hooks/pre-compact.js.map +1 -0
  73. package/dist/hooks/session-end.d.ts +3 -0
  74. package/dist/hooks/session-end.d.ts.map +1 -0
  75. package/dist/hooks/session-end.js +80 -0
  76. package/dist/hooks/session-end.js.map +1 -0
  77. package/dist/hooks/session-start.d.ts +3 -0
  78. package/dist/hooks/session-start.d.ts.map +1 -0
  79. package/dist/hooks/session-start.js +108 -0
  80. package/dist/hooks/session-start.js.map +1 -0
  81. package/dist/index.d.ts +33 -0
  82. package/dist/index.d.ts.map +1 -0
  83. package/dist/index.js +27 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/intelligence/collector.d.ts +12 -0
  86. package/dist/intelligence/collector.d.ts.map +1 -0
  87. package/dist/intelligence/collector.js +93 -0
  88. package/dist/intelligence/collector.js.map +1 -0
  89. package/dist/intelligence/ranker.d.ts +5 -0
  90. package/dist/intelligence/ranker.d.ts.map +1 -0
  91. package/dist/intelligence/ranker.js +107 -0
  92. package/dist/intelligence/ranker.js.map +1 -0
  93. package/dist/intelligence/store.d.ts +17 -0
  94. package/dist/intelligence/store.d.ts.map +1 -0
  95. package/dist/intelligence/store.js +75 -0
  96. package/dist/intelligence/store.js.map +1 -0
  97. package/dist/intelligence/sync.d.ts +3 -0
  98. package/dist/intelligence/sync.d.ts.map +1 -0
  99. package/dist/intelligence/sync.js +83 -0
  100. package/dist/intelligence/sync.js.map +1 -0
  101. package/dist/intelligence/types.d.ts +35 -0
  102. package/dist/intelligence/types.d.ts.map +1 -0
  103. package/dist/intelligence/types.js +2 -0
  104. package/dist/intelligence/types.js.map +1 -0
  105. package/dist/lib/context.d.ts +3 -0
  106. package/dist/lib/context.d.ts.map +1 -0
  107. package/dist/lib/context.js +56 -0
  108. package/dist/lib/context.js.map +1 -0
  109. package/dist/lib/conventions-detect.d.ts +12 -0
  110. package/dist/lib/conventions-detect.d.ts.map +1 -0
  111. package/dist/lib/conventions-detect.js +337 -0
  112. package/dist/lib/conventions-detect.js.map +1 -0
  113. package/dist/lib/frontmatter.d.ts +7 -0
  114. package/dist/lib/frontmatter.d.ts.map +1 -0
  115. package/dist/lib/frontmatter.js +45 -0
  116. package/dist/lib/frontmatter.js.map +1 -0
  117. package/dist/lib/fs-helpers.d.ts +6 -0
  118. package/dist/lib/fs-helpers.d.ts.map +1 -0
  119. package/dist/lib/fs-helpers.js +24 -0
  120. package/dist/lib/fs-helpers.js.map +1 -0
  121. package/dist/lib/interpolate.d.ts +2 -0
  122. package/dist/lib/interpolate.d.ts.map +1 -0
  123. package/dist/lib/interpolate.js +4 -0
  124. package/dist/lib/interpolate.js.map +1 -0
  125. package/dist/lib/output.d.ts +27 -0
  126. package/dist/lib/output.d.ts.map +1 -0
  127. package/dist/lib/output.js +85 -0
  128. package/dist/lib/output.js.map +1 -0
  129. package/dist/lib/reader.d.ts +14 -0
  130. package/dist/lib/reader.d.ts.map +1 -0
  131. package/dist/lib/reader.js +75 -0
  132. package/dist/lib/reader.js.map +1 -0
  133. package/dist/lib/stack-detect.d.ts +12 -0
  134. package/dist/lib/stack-detect.d.ts.map +1 -0
  135. package/dist/lib/stack-detect.js +302 -0
  136. package/dist/lib/stack-detect.js.map +1 -0
  137. package/dist/lib/statusline.d.ts +3 -0
  138. package/dist/lib/statusline.d.ts.map +1 -0
  139. package/dist/lib/statusline.js +40 -0
  140. package/dist/lib/statusline.js.map +1 -0
  141. package/dist/lib/templates.d.ts +3 -0
  142. package/dist/lib/templates.d.ts.map +1 -0
  143. package/dist/lib/templates.js +174 -0
  144. package/dist/lib/templates.js.map +1 -0
  145. package/dist/lib/types.d.ts +44 -0
  146. package/dist/lib/types.d.ts.map +1 -0
  147. package/dist/lib/types.js +2 -0
  148. package/dist/lib/types.js.map +1 -0
  149. package/dist/lib/writer.d.ts +13 -0
  150. package/dist/lib/writer.d.ts.map +1 -0
  151. package/dist/lib/writer.js +97 -0
  152. package/dist/lib/writer.js.map +1 -0
  153. package/dist/mcp/handlers.d.ts +34 -0
  154. package/dist/mcp/handlers.d.ts.map +1 -0
  155. package/dist/mcp/handlers.js +256 -0
  156. package/dist/mcp/handlers.js.map +1 -0
  157. package/dist/mcp/server.d.ts +20 -0
  158. package/dist/mcp/server.d.ts.map +1 -0
  159. package/dist/mcp/server.js +89 -0
  160. package/dist/mcp/server.js.map +1 -0
  161. package/dist/mcp/tools.d.ts +11 -0
  162. package/dist/mcp/tools.d.ts.map +1 -0
  163. package/dist/mcp/tools.js +148 -0
  164. package/dist/mcp/tools.js.map +1 -0
  165. package/dist/tasks/manager.d.ts +14 -0
  166. package/dist/tasks/manager.d.ts.map +1 -0
  167. package/dist/tasks/manager.js +151 -0
  168. package/dist/tasks/manager.js.map +1 -0
  169. package/dist/tasks/tracker.d.ts +11 -0
  170. package/dist/tasks/tracker.d.ts.map +1 -0
  171. package/dist/tasks/tracker.js +31 -0
  172. package/dist/tasks/tracker.js.map +1 -0
  173. package/dist/tasks/types.d.ts +19 -0
  174. package/dist/tasks/types.d.ts.map +1 -0
  175. package/dist/tasks/types.js +2 -0
  176. package/dist/tasks/types.js.map +1 -0
  177. package/dist/workflow/builtin.d.ts +4 -0
  178. package/dist/workflow/builtin.d.ts.map +1 -0
  179. package/dist/workflow/builtin.js +93 -0
  180. package/dist/workflow/builtin.js.map +1 -0
  181. package/dist/workflow/engine.d.ts +38 -0
  182. package/dist/workflow/engine.d.ts.map +1 -0
  183. package/dist/workflow/engine.js +217 -0
  184. package/dist/workflow/engine.js.map +1 -0
  185. package/dist/workflow/loader.d.ts +4 -0
  186. package/dist/workflow/loader.d.ts.map +1 -0
  187. package/dist/workflow/loader.js +106 -0
  188. package/dist/workflow/loader.js.map +1 -0
  189. package/dist/workflow/state.d.ts +11 -0
  190. package/dist/workflow/state.d.ts.map +1 -0
  191. package/dist/workflow/state.js +49 -0
  192. package/dist/workflow/state.js.map +1 -0
  193. package/dist/workflow/types.d.ts +36 -0
  194. package/dist/workflow/types.d.ts.map +1 -0
  195. package/dist/workflow/types.js +2 -0
  196. package/dist/workflow/types.js.map +1 -0
  197. package/package.json +54 -0
  198. package/templates/agents/architect.md +46 -0
  199. package/templates/agents/coder.md +46 -0
  200. package/templates/agents/committer.md +29 -0
  201. package/templates/agents/debugger.md +54 -0
  202. package/templates/agents/planner.md +45 -0
  203. package/templates/agents/reader.md +48 -0
  204. package/templates/agents/reviewer.md +48 -0
  205. package/templates/agents/tester.md +41 -0
  206. package/templates/claude/agents/researcher.md +47 -0
  207. package/templates/claude/agents/writer.md +29 -0
  208. package/templates/claude/commands/git/changelog.md +41 -0
  209. package/templates/claude/commands/git/merge.md +37 -0
  210. package/templates/claude/commands/git/new-branch.md +34 -0
  211. package/templates/claude/commands/git/pr-review.md +64 -0
  212. package/templates/claude/commands/session/handover.md +49 -0
  213. package/templates/claude/commands/session/resume.md +43 -0
  214. package/templates/claude/commands/session/review.md +81 -0
  215. package/templates/claude/commands/task.md +52 -0
  216. package/templates/claude/commands/vault/adr.md +39 -0
  217. package/templates/claude/commands/vault/analyze.md +110 -0
  218. package/templates/claude/commands/vault/bug.md +31 -0
  219. package/templates/claude/commands/vault/debt.md +28 -0
  220. package/templates/claude/commands/vault/deps.md +36 -0
  221. package/templates/claude/commands/vault/from-spec.md +306 -0
  222. package/templates/claude/commands/vault/search.md +31 -0
  223. package/templates/claude/commands/vault/security-scan.md +50 -0
  224. package/templates/claude/commands/vault/test-gaps.md +38 -0
  225. package/templates/claude/commands/workflow/dev.md +913 -0
  226. package/templates/claude/commands/workflow.md +47 -0
  227. package/templates/claude/settings.json +52 -0
  228. package/templates/claude/skills/obsidian-markdown/SKILL.md +196 -0
  229. package/templates/claude/skills/obsidian-markdown/references/CALLOUTS.md +58 -0
  230. package/templates/claude/skills/obsidian-markdown/references/EMBEDS.md +63 -0
  231. package/templates/claude/skills/obsidian-markdown/references/PROPERTIES.md +61 -0
  232. package/templates/workflows/deploy.yaml +21 -0
  233. package/templates/workflows/release.yaml +26 -0
  234. package/templates/workflows/spike.yaml +14 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/intelligence/sync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA2FpD,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAYjF"}
@@ -0,0 +1,83 @@
1
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ function now() {
4
+ return new Date().toISOString();
5
+ }
6
+ function makeId(category, content) {
7
+ const slug = content
8
+ .toLowerCase()
9
+ .replace(/[^a-z0-9]+/g, "-")
10
+ .slice(0, 40)
11
+ .replace(/-$/, "");
12
+ return `${category}:${slug}`;
13
+ }
14
+ function extractBullets(content, sectionHeader) {
15
+ const headerIndex = content.indexOf(sectionHeader);
16
+ if (headerIndex === -1)
17
+ return [];
18
+ const afterHeader = content.slice(headerIndex + sectionHeader.length);
19
+ const nextSection = afterHeader.match(/\n## /);
20
+ const sectionContent = nextSection
21
+ ? afterHeader.slice(0, nextSection.index)
22
+ : afterHeader;
23
+ return sectionContent
24
+ .split("\n")
25
+ .filter((line) => line.startsWith("- "))
26
+ .map((line) => line.slice(2).trim())
27
+ .filter((line) => line.length > 0);
28
+ }
29
+ function syncMarkdownFile(store, filepath, category, source) {
30
+ if (!existsSync(filepath))
31
+ return;
32
+ const content = readFileSync(filepath, "utf-8");
33
+ const sections = content.match(/^## .+$/gm) ?? [];
34
+ for (const sectionHeader of sections) {
35
+ const bullets = extractBullets(content, sectionHeader);
36
+ const sectionName = sectionHeader.replace(/^## /, "");
37
+ for (const bullet of bullets) {
38
+ const id = makeId(category, bullet);
39
+ store.upsertNode({
40
+ id,
41
+ category,
42
+ content: `[${sectionName}] ${bullet}`,
43
+ source,
44
+ confidence: 0.5,
45
+ accessCount: 0,
46
+ lastAccessed: now(),
47
+ createdAt: now(),
48
+ });
49
+ }
50
+ }
51
+ }
52
+ function syncRecordFiles(store, directory, category, source) {
53
+ if (!existsSync(directory))
54
+ return;
55
+ const files = readdirSync(directory).filter((f) => f.endsWith(".md"));
56
+ for (const file of files) {
57
+ const content = readFileSync(join(directory, file), "utf-8");
58
+ const titleMatch = content.match(/^# (.+)$/m);
59
+ const title = titleMatch ? titleMatch[1] : file.replace(".md", "");
60
+ const id = makeId(category, title);
61
+ store.upsertNode({
62
+ id,
63
+ category,
64
+ content: title,
65
+ source,
66
+ confidence: 0.6,
67
+ accessCount: 0,
68
+ lastAccessed: now(),
69
+ createdAt: now(),
70
+ });
71
+ }
72
+ }
73
+ export function syncFromVault(store, vaultPath) {
74
+ const before = store.nodeCount();
75
+ syncMarkdownFile(store, join(vaultPath, "conventions.md"), "convention", "vault:conventions");
76
+ syncMarkdownFile(store, join(vaultPath, "knowledge.md"), "gotcha", "vault:knowledge");
77
+ syncRecordFiles(store, join(vaultPath, "architecture"), "decision", "vault:adr");
78
+ syncRecordFiles(store, join(vaultPath, "bugs"), "gotcha", "vault:bugs");
79
+ syncRecordFiles(store, join(vaultPath, "debt"), "pattern", "vault:debt");
80
+ store.save();
81
+ return store.nodeCount() - before;
82
+ }
83
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/intelligence/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export type PatternCategory = "file" | "convention" | "pattern" | "gotcha" | "decision" | "task" | "session";
2
+ export type EdgeRelation = "related" | "depends" | "conflicts" | "part-of" | "co-edited";
3
+ export interface PatternNode {
4
+ id: string;
5
+ category: PatternCategory;
6
+ content: string;
7
+ source: string;
8
+ confidence: number;
9
+ accessCount: number;
10
+ lastAccessed: string;
11
+ createdAt: string;
12
+ }
13
+ export interface PatternEdge {
14
+ from: string;
15
+ to: string;
16
+ relation: EdgeRelation;
17
+ weight: number;
18
+ }
19
+ export interface IntelligenceGraph {
20
+ version: 1;
21
+ updatedAt: string;
22
+ nodes: Record<string, PatternNode>;
23
+ edges: PatternEdge[];
24
+ }
25
+ export interface ScoringContext {
26
+ branch: string;
27
+ taskTitle: string | null;
28
+ recentFiles: string[];
29
+ query: string | null;
30
+ }
31
+ export interface ScoredNode {
32
+ node: PatternNode;
33
+ score: number;
34
+ }
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/intelligence/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7G,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC;AAEzF,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACnC,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/intelligence/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { ProjectContext } from "./types.js";
2
+ export declare function detectContext(cwd?: string): ProjectContext | null;
3
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/lib/context.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA4CjD,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAsB,GAAG,cAAc,GAAG,IAAI,CAehF"}
@@ -0,0 +1,56 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { join, basename } from "node:path";
4
+ const VAULT_DIR = ".dev-vault";
5
+ function git(args, cwd) {
6
+ try {
7
+ return execFileSync("git", args, { cwd, encoding: "utf-8" }).trim();
8
+ }
9
+ catch {
10
+ return "";
11
+ }
12
+ }
13
+ function resolveProjectRoot(startDir) {
14
+ let dir = startDir;
15
+ const root = "/";
16
+ while (dir !== root) {
17
+ if (existsSync(join(dir, ".git")))
18
+ return dir;
19
+ dir = join(dir, "..");
20
+ }
21
+ return null;
22
+ }
23
+ function resolveProjectName(projectRoot) {
24
+ const remote = git(["remote", "get-url", "origin"], projectRoot);
25
+ if (remote) {
26
+ const match = remote.match(/\/([^/]+?)(?:\.git)?$/);
27
+ if (match?.[1])
28
+ return match[1];
29
+ }
30
+ return basename(projectRoot);
31
+ }
32
+ function resolveParentBranch(projectRoot) {
33
+ const mainExists = git(["rev-parse", "--verify", "main"], projectRoot);
34
+ if (mainExists)
35
+ return "main";
36
+ const masterExists = git(["rev-parse", "--verify", "master"], projectRoot);
37
+ if (masterExists)
38
+ return "master";
39
+ return "main";
40
+ }
41
+ export function detectContext(cwd = process.cwd()) {
42
+ const projectRoot = resolveProjectRoot(cwd);
43
+ if (!projectRoot)
44
+ return null;
45
+ const branch = git(["branch", "--show-current"], projectRoot) || "main";
46
+ const remote = git(["remote", "get-url", "origin"], projectRoot) || null;
47
+ return {
48
+ projectName: resolveProjectName(projectRoot),
49
+ branch,
50
+ parentBranch: resolveParentBranch(projectRoot),
51
+ vaultPath: join(projectRoot, VAULT_DIR),
52
+ projectRoot,
53
+ gitRemote: remote,
54
+ };
55
+ }
56
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/lib/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG3C,MAAM,SAAS,GAAG,YAAY,CAAC;AAE/B,SAAS,GAAG,CAAC,IAAc,EAAE,GAAW;IACtC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,MAAM,IAAI,GAAG,GAAG,CAAC;IAEjB,OAAO,GAAG,KAAK,IAAI,EAAE,CAAC;QACpB,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAC9C,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,WAAmB;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC;IACjE,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACpD,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,mBAAmB,CAAC,WAAmB;IAC9C,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IACvE,IAAI,UAAU;QAAE,OAAO,MAAM,CAAC;IAE9B,MAAM,YAAY,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC;IAC3E,IAAI,YAAY;QAAE,OAAO,QAAQ,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACvD,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC;IACxE,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,IAAI,IAAI,CAAC;IAEzE,OAAO;QACL,WAAW,EAAE,kBAAkB,CAAC,WAAW,CAAC;QAC5C,MAAM;QACN,YAAY,EAAE,mBAAmB,CAAC,WAAW,CAAC;QAC9C,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC;QACvC,WAAW;QACX,SAAS,EAAE,MAAM;KAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ interface ConventionsInfo {
2
+ fileStructure: string[];
3
+ naming: string[];
4
+ codeStyle: string[];
5
+ patterns: string[];
6
+ git: string[];
7
+ testing: string[];
8
+ }
9
+ export declare function detectConventions(projectRoot: string): ConventionsInfo;
10
+ export declare function renderConventionsMarkdown(projectName: string, conventions: ConventionsInfo): string;
11
+ export {};
12
+ //# sourceMappingURL=conventions-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conventions-detect.d.ts","sourceRoot":"","sources":["../../src/lib/conventions-detect.ts"],"names":[],"mappings":"AAGA,UAAU,eAAe;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAqRD,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CA2BtE;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,GAAG,MAAM,CA6BnG"}
@@ -0,0 +1,337 @@
1
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ const SKIP_DIRS = new Set([
4
+ "node_modules", "vendor", "dist", "build", "out", "target",
5
+ "__pycache__", "coverage",
6
+ ]);
7
+ function findAllFiles(projectRoot, filename, maxDepth = 4) {
8
+ const found = [];
9
+ function scan(directory, depth) {
10
+ if (depth > maxDepth)
11
+ return;
12
+ const filePath = join(directory, filename);
13
+ if (existsSync(filePath))
14
+ found.push(filePath);
15
+ if (depth < maxDepth) {
16
+ let entries;
17
+ try {
18
+ entries = readdirSync(directory, { withFileTypes: true });
19
+ }
20
+ catch {
21
+ return;
22
+ }
23
+ for (const entry of entries) {
24
+ if (!entry.isDirectory())
25
+ continue;
26
+ if (entry.name.startsWith("."))
27
+ continue;
28
+ if (SKIP_DIRS.has(entry.name))
29
+ continue;
30
+ scan(join(directory, entry.name), depth + 1);
31
+ }
32
+ }
33
+ }
34
+ scan(projectRoot, 0);
35
+ return found;
36
+ }
37
+ function readJsonOrNull(filepath) {
38
+ try {
39
+ if (!existsSync(filepath))
40
+ return null;
41
+ return JSON.parse(readFileSync(filepath, "utf-8"));
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ function readFileOrNull(filepath) {
48
+ try {
49
+ if (!existsSync(filepath))
50
+ return null;
51
+ return readFileSync(filepath, "utf-8");
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ }
57
+ function detectFromTsconfigs(projectRoot, conventions) {
58
+ const tsconfigPaths = findAllFiles(projectRoot, "tsconfig.json");
59
+ for (const tsconfigPath of tsconfigPaths) {
60
+ const tsconfig = readJsonOrNull(tsconfigPath);
61
+ if (!tsconfig)
62
+ continue;
63
+ const compilerOptions = tsconfig["compilerOptions"];
64
+ if (!compilerOptions)
65
+ continue;
66
+ if (compilerOptions["strict"] === true)
67
+ conventions.codeStyle.push("TypeScript strict mode enabled");
68
+ if (compilerOptions["noUncheckedIndexedAccess"] === true)
69
+ conventions.codeStyle.push("noUncheckedIndexedAccess: indexed access requires undefined check");
70
+ if (compilerOptions["noUnusedLocals"] === true)
71
+ conventions.codeStyle.push("No unused local variables allowed");
72
+ if (compilerOptions["noUnusedParameters"] === true)
73
+ conventions.codeStyle.push("No unused parameters allowed");
74
+ if (compilerOptions["exactOptionalPropertyTypes"] === true)
75
+ conventions.codeStyle.push("Exact optional property types");
76
+ const module = compilerOptions["module"];
77
+ if (module)
78
+ conventions.codeStyle.push(`Module system: ${module}`);
79
+ const rootDir = compilerOptions["rootDir"];
80
+ const outDir = compilerOptions["outDir"];
81
+ if (rootDir && outDir) {
82
+ conventions.fileStructure.push(`Source in ${rootDir}/, output in ${outDir}/`);
83
+ }
84
+ break; // first tsconfig is enough for conventions
85
+ }
86
+ }
87
+ function detectFromRust(projectRoot, conventions) {
88
+ const cargoPaths = findAllFiles(projectRoot, "Cargo.toml");
89
+ for (const cargoPath of cargoPaths) {
90
+ const content = readFileOrNull(cargoPath);
91
+ if (!content)
92
+ continue;
93
+ const edition = content.match(/^edition\s*=\s*"(\d+)"/m);
94
+ if (edition) {
95
+ conventions.codeStyle.push(`Rust edition: ${edition[1]}`);
96
+ break;
97
+ }
98
+ }
99
+ // rustfmt
100
+ const rustfmtPaths = [
101
+ join(projectRoot, "rustfmt.toml"),
102
+ join(projectRoot, ".rustfmt.toml"),
103
+ ];
104
+ for (const rustfmtPath of rustfmtPaths) {
105
+ const content = readFileOrNull(rustfmtPath);
106
+ if (!content)
107
+ continue;
108
+ const rules = [];
109
+ const edition = content.match(/edition\s*=\s*"?(\d+)"?/);
110
+ if (edition)
111
+ rules.push(`edition ${edition[1]}`);
112
+ const maxWidth = content.match(/max_width\s*=\s*(\d+)/);
113
+ if (maxWidth)
114
+ rules.push(`max width ${maxWidth[1]}`);
115
+ const tabSpaces = content.match(/tab_spaces\s*=\s*(\d+)/);
116
+ if (tabSpaces)
117
+ rules.push(`tab spaces ${tabSpaces[1]}`);
118
+ const useSmallHeuristics = content.match(/use_small_heuristics\s*=\s*"?(\w+)"?/);
119
+ if (useSmallHeuristics)
120
+ rules.push(`heuristics: ${useSmallHeuristics[1]}`);
121
+ if (rules.length > 0) {
122
+ conventions.codeStyle.push(`rustfmt: ${rules.join(", ")}`);
123
+ }
124
+ else {
125
+ conventions.codeStyle.push("rustfmt configured");
126
+ }
127
+ break;
128
+ }
129
+ // clippy
130
+ const clippyPaths = [
131
+ join(projectRoot, "clippy.toml"),
132
+ join(projectRoot, ".clippy.toml"),
133
+ ];
134
+ for (const clippyPath of clippyPaths) {
135
+ if (existsSync(clippyPath)) {
136
+ conventions.codeStyle.push("Clippy configured");
137
+ break;
138
+ }
139
+ }
140
+ // cargo-deny
141
+ if (existsSync(join(projectRoot, "deny.toml"))) {
142
+ conventions.codeStyle.push("cargo-deny: dependency audit configured");
143
+ }
144
+ }
145
+ function detectFromEditorconfig(projectRoot, conventions) {
146
+ const editorConfigPath = join(projectRoot, ".editorconfig");
147
+ const content = readFileOrNull(editorConfigPath);
148
+ if (!content)
149
+ return;
150
+ const indentStyle = content.match(/indent_style\s*=\s*(\w+)/);
151
+ const indentSize = content.match(/indent_size\s*=\s*(\w+)/);
152
+ if (indentStyle) {
153
+ const size = indentSize ? `, size ${indentSize[1]}` : "";
154
+ conventions.codeStyle.push(`Indent: ${indentStyle[1]}${size}`);
155
+ }
156
+ const endOfLine = content.match(/end_of_line\s*=\s*(\w+)/);
157
+ if (endOfLine)
158
+ conventions.codeStyle.push(`Line endings: ${endOfLine[1]}`);
159
+ }
160
+ function detectFromPackageJsons(projectRoot, conventions) {
161
+ const packagePaths = findAllFiles(projectRoot, "package.json");
162
+ for (const packagePath of packagePaths) {
163
+ const packageJson = readJsonOrNull(packagePath);
164
+ if (!packageJson)
165
+ continue;
166
+ const scripts = packageJson["scripts"];
167
+ if (scripts) {
168
+ if (scripts["lint"])
169
+ conventions.codeStyle.push(`Lint: ${scripts["lint"]}`);
170
+ if (scripts["test"])
171
+ conventions.testing.push(`Test: ${scripts["test"]}`);
172
+ if (scripts["build"])
173
+ conventions.patterns.push(`Build: ${scripts["build"]}`);
174
+ if (scripts["format"])
175
+ conventions.codeStyle.push(`Format: ${scripts["format"]}`);
176
+ if (scripts["check"])
177
+ conventions.codeStyle.push(`Check: ${scripts["check"]}`);
178
+ }
179
+ const type = packageJson["type"];
180
+ if (type === "module")
181
+ conventions.patterns.push("ESM modules (type: module)");
182
+ }
183
+ }
184
+ function detectFromPrettier(projectRoot, conventions) {
185
+ const names = [".prettierrc", ".prettierrc.json", ".prettierrc.yml"];
186
+ for (const name of names) {
187
+ const paths = findAllFiles(projectRoot, name, 1);
188
+ for (const configPath of paths) {
189
+ const config = readJsonOrNull(configPath);
190
+ if (!config)
191
+ continue;
192
+ const rules = [];
193
+ if (config["semi"] === false)
194
+ rules.push("no semicolons");
195
+ if (config["singleQuote"] === true)
196
+ rules.push("single quotes");
197
+ if (config["tabWidth"])
198
+ rules.push(`tab width: ${config["tabWidth"]}`);
199
+ if (config["trailingComma"])
200
+ rules.push(`trailing comma: ${config["trailingComma"]}`);
201
+ if (config["printWidth"])
202
+ rules.push(`print width: ${config["printWidth"]}`);
203
+ if (rules.length > 0) {
204
+ conventions.codeStyle.push(`Prettier: ${rules.join(", ")}`);
205
+ }
206
+ return;
207
+ }
208
+ }
209
+ }
210
+ function detectFromBiome(projectRoot, conventions) {
211
+ const biomePath = join(projectRoot, "biome.json");
212
+ if (!existsSync(biomePath))
213
+ return;
214
+ conventions.codeStyle.push("Biome configured (formatter + linter)");
215
+ }
216
+ function detectTestPatterns(projectRoot, conventions) {
217
+ const vitestPaths = findAllFiles(projectRoot, "vitest.config.ts", 2);
218
+ const vitestJsPaths = findAllFiles(projectRoot, "vitest.config.js", 2);
219
+ if (vitestPaths.length > 0 || vitestJsPaths.length > 0) {
220
+ conventions.testing.push("Test framework: Vitest");
221
+ }
222
+ const jestPaths = findAllFiles(projectRoot, "jest.config.ts", 2);
223
+ const jestJsPaths = findAllFiles(projectRoot, "jest.config.js", 2);
224
+ if (jestPaths.length > 0 || jestJsPaths.length > 0) {
225
+ conventions.testing.push("Test framework: Jest");
226
+ }
227
+ // Rust tests
228
+ const cargoPaths = findAllFiles(projectRoot, "Cargo.toml");
229
+ for (const cargoPath of cargoPaths) {
230
+ const content = readFileOrNull(cargoPath);
231
+ if (content && content.includes("[dev-dependencies]")) {
232
+ conventions.testing.push("Rust: dev-dependencies configured (test deps)");
233
+ break;
234
+ }
235
+ }
236
+ const testsDirExists = findAllFiles(projectRoot, "tests", 2).length > 0
237
+ || existsSync(join(projectRoot, "tests"))
238
+ || existsSync(join(projectRoot, "__tests__"));
239
+ if (testsDirExists)
240
+ conventions.testing.push("Tests in dedicated directory");
241
+ }
242
+ function detectGitConventions(projectRoot, conventions) {
243
+ if (existsSync(join(projectRoot, ".gitignore"))) {
244
+ conventions.git.push(".gitignore configured");
245
+ }
246
+ if (existsSync(join(projectRoot, ".husky"))) {
247
+ conventions.git.push("Husky git hooks");
248
+ }
249
+ if (existsSync(join(projectRoot, ".commitlintrc.json")) || existsSync(join(projectRoot, ".commitlintrc.yml"))) {
250
+ conventions.git.push("Commitlint configured");
251
+ }
252
+ // Lefthook
253
+ const lefthookPaths = ["lefthook.yml", "lefthook.yaml", ".lefthook.yml"];
254
+ for (const name of lefthookPaths) {
255
+ const content = readFileOrNull(join(projectRoot, name));
256
+ if (!content)
257
+ continue;
258
+ conventions.git.push("Lefthook git hooks");
259
+ const hooks = [];
260
+ if (content.includes("pre-commit:"))
261
+ hooks.push("pre-commit");
262
+ if (content.includes("pre-push:"))
263
+ hooks.push("pre-push");
264
+ if (content.includes("commit-msg:"))
265
+ hooks.push("commit-msg");
266
+ if (content.includes("post-checkout:"))
267
+ hooks.push("post-checkout");
268
+ if (content.includes("post-merge:"))
269
+ hooks.push("post-merge");
270
+ if (hooks.length > 0) {
271
+ conventions.git.push(`Git hooks: ${hooks.join(", ")}`);
272
+ }
273
+ break;
274
+ }
275
+ }
276
+ function deduplicate(items) {
277
+ const seen = new Set();
278
+ return items.filter((item) => {
279
+ if (seen.has(item))
280
+ return false;
281
+ seen.add(item);
282
+ return true;
283
+ });
284
+ }
285
+ export function detectConventions(projectRoot) {
286
+ const conventions = {
287
+ fileStructure: [],
288
+ naming: [],
289
+ codeStyle: [],
290
+ patterns: [],
291
+ git: [],
292
+ testing: [],
293
+ };
294
+ detectFromTsconfigs(projectRoot, conventions);
295
+ detectFromRust(projectRoot, conventions);
296
+ detectFromEditorconfig(projectRoot, conventions);
297
+ detectFromPackageJsons(projectRoot, conventions);
298
+ detectFromPrettier(projectRoot, conventions);
299
+ detectFromBiome(projectRoot, conventions);
300
+ detectTestPatterns(projectRoot, conventions);
301
+ detectGitConventions(projectRoot, conventions);
302
+ conventions.fileStructure = deduplicate(conventions.fileStructure);
303
+ conventions.naming = deduplicate(conventions.naming);
304
+ conventions.codeStyle = deduplicate(conventions.codeStyle);
305
+ conventions.patterns = deduplicate(conventions.patterns);
306
+ conventions.git = deduplicate(conventions.git);
307
+ conventions.testing = deduplicate(conventions.testing);
308
+ return conventions;
309
+ }
310
+ export function renderConventionsMarkdown(projectName, conventions) {
311
+ const today = new Date().toISOString().slice(0, 10);
312
+ const sections = [
313
+ `---`,
314
+ `updated: ${today}`,
315
+ `tags: [conventions, ${projectName}]`,
316
+ `---`,
317
+ `# ${projectName} — Conventions`,
318
+ ];
319
+ const categories = [
320
+ ["File Structure", conventions.fileStructure],
321
+ ["Naming", conventions.naming],
322
+ ["Code Style", conventions.codeStyle],
323
+ ["Patterns", conventions.patterns],
324
+ ["Git", conventions.git],
325
+ ["Testing", conventions.testing],
326
+ ];
327
+ for (const [title, items] of categories) {
328
+ sections.push("", `## ${title}`);
329
+ if (items.length > 0) {
330
+ for (const item of items) {
331
+ sections.push(`- ${item}`);
332
+ }
333
+ }
334
+ }
335
+ return sections.join("\n") + "\n";
336
+ }
337
+ //# sourceMappingURL=conventions-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conventions-detect.js","sourceRoot":"","sources":["../../src/lib/conventions-detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface Frontmatter {
2
+ fields: Record<string, string | string[]>;
3
+ body: string;
4
+ }
5
+ export declare function parseFrontmatter(raw: string): Frontmatter;
6
+ export declare function serializeFrontmatter(fields: Record<string, unknown>, body: string): string;
7
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/lib/frontmatter.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CA+BzD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAkB1F"}
@@ -0,0 +1,45 @@
1
+ export function parseFrontmatter(raw) {
2
+ const match = raw.match(/^---\n([\s\S]*?)\n---/);
3
+ if (!match?.[1]) {
4
+ return { fields: {}, body: raw };
5
+ }
6
+ const yamlBlock = match[1];
7
+ const fields = {};
8
+ for (const line of yamlBlock.split("\n")) {
9
+ const fieldMatch = line.match(/^(\w[\w-]*):\s*(.+)$/);
10
+ if (!fieldMatch)
11
+ continue;
12
+ const key = fieldMatch[1];
13
+ const value = fieldMatch[2].trim();
14
+ const arrayMatch = value.match(/^\[(.*)]\s*$/);
15
+ if (arrayMatch) {
16
+ fields[key] = arrayMatch[1]
17
+ .split(",")
18
+ .map((item) => item.trim())
19
+ .filter(Boolean);
20
+ }
21
+ else {
22
+ fields[key] = value;
23
+ }
24
+ }
25
+ const bodyStart = raw.indexOf("---", 3);
26
+ const body = bodyStart !== -1 ? raw.slice(bodyStart + 3).replace(/^\n+/, "") : "";
27
+ return { fields, body };
28
+ }
29
+ export function serializeFrontmatter(fields, body) {
30
+ const lines = ["---"];
31
+ for (const [key, value] of Object.entries(fields)) {
32
+ if (Array.isArray(value)) {
33
+ lines.push(`${key}: [${value.join(", ")}]`);
34
+ }
35
+ else {
36
+ lines.push(`${key}: ${String(value)}`);
37
+ }
38
+ }
39
+ lines.push("---");
40
+ if (body) {
41
+ lines.push("", body);
42
+ }
43
+ return lines.join("\n") + "\n";
44
+ }
45
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/lib/frontmatter.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAsC,EAAE,CAAC;IAErD,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU;YAAE,SAAS;QAE1B,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;QAEpC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC/C,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,CAAE;iBACzB,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;iBAC1B,MAAM,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAElF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAA+B,EAAE,IAAY;IAChF,MAAM,KAAK,GAAa,CAAC,KAAK,CAAC,CAAC;IAEhC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAElB,IAAI,IAAI,EAAE,CAAC;QACT,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC"}