vibeman 0.0.0 → 0.0.1

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 (220) hide show
  1. package/README.md +12 -0
  2. package/dist/index.js +116 -0
  3. package/dist/runtime/api/.tsbuildinfo +1 -0
  4. package/dist/runtime/api/agent/agent-service.d.ts +226 -0
  5. package/dist/runtime/api/agent/agent-service.js +901 -0
  6. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.d.ts +61 -0
  7. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.js +373 -0
  8. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.d.ts +34 -0
  9. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.js +281 -0
  10. package/dist/runtime/api/agent/ai-providers/index.d.ts +9 -0
  11. package/dist/runtime/api/agent/ai-providers/index.js +7 -0
  12. package/dist/runtime/api/agent/ai-providers/types.d.ts +180 -0
  13. package/dist/runtime/api/agent/ai-providers/types.js +5 -0
  14. package/dist/runtime/api/agent/codex-cli-provider.test.d.ts +1 -0
  15. package/dist/runtime/api/agent/codex-cli-provider.test.js +88 -0
  16. package/dist/runtime/api/agent/core-agent-service.d.ts +119 -0
  17. package/dist/runtime/api/agent/core-agent-service.js +267 -0
  18. package/dist/runtime/api/agent/parsers.d.ts +15 -0
  19. package/dist/runtime/api/agent/parsers.js +241 -0
  20. package/dist/runtime/api/agent/prompt-service.d.ts +17 -0
  21. package/dist/runtime/api/agent/prompt-service.js +340 -0
  22. package/dist/runtime/api/agent/routing-policy.d.ts +188 -0
  23. package/dist/runtime/api/agent/routing-policy.js +246 -0
  24. package/dist/runtime/api/api/router-helpers.d.ts +32 -0
  25. package/dist/runtime/api/api/router-helpers.js +31 -0
  26. package/dist/runtime/api/api/routers/ai.d.ts +188 -0
  27. package/dist/runtime/api/api/routers/ai.js +410 -0
  28. package/dist/runtime/api/api/routers/executions.d.ts +98 -0
  29. package/dist/runtime/api/api/routers/executions.js +103 -0
  30. package/dist/runtime/api/api/routers/git.d.ts +45 -0
  31. package/dist/runtime/api/api/routers/git.js +35 -0
  32. package/dist/runtime/api/api/routers/settings.d.ts +139 -0
  33. package/dist/runtime/api/api/routers/settings.js +113 -0
  34. package/dist/runtime/api/api/routers/tasks.d.ts +141 -0
  35. package/dist/runtime/api/api/routers/tasks.js +238 -0
  36. package/dist/runtime/api/api/routers/workflows.d.ts +268 -0
  37. package/dist/runtime/api/api/routers/workflows.js +308 -0
  38. package/dist/runtime/api/api/routers/worktrees.d.ts +102 -0
  39. package/dist/runtime/api/api/routers/worktrees.js +80 -0
  40. package/dist/runtime/api/api/trpc.d.ts +118 -0
  41. package/dist/runtime/api/api/trpc.js +34 -0
  42. package/dist/runtime/api/index.d.ts +9 -0
  43. package/dist/runtime/api/index.js +125 -0
  44. package/dist/runtime/api/lib/id-generator.d.ts +70 -0
  45. package/dist/runtime/api/lib/id-generator.js +123 -0
  46. package/dist/runtime/api/lib/image-paste-drop-extension.d.ts +26 -0
  47. package/dist/runtime/api/lib/image-paste-drop-extension.js +125 -0
  48. package/dist/runtime/api/lib/logger.d.ts +11 -0
  49. package/dist/runtime/api/lib/logger.js +188 -0
  50. package/dist/runtime/api/lib/markdown-utils.d.ts +8 -0
  51. package/dist/runtime/api/lib/markdown-utils.js +282 -0
  52. package/dist/runtime/api/lib/markdown-utils.test.d.ts +1 -0
  53. package/dist/runtime/api/lib/markdown-utils.test.js +348 -0
  54. package/dist/runtime/api/lib/server/agent-service-singleton.d.ts +6 -0
  55. package/dist/runtime/api/lib/server/agent-service-singleton.js +27 -0
  56. package/dist/runtime/api/lib/server/git-service-singleton.d.ts +6 -0
  57. package/dist/runtime/api/lib/server/git-service-singleton.js +47 -0
  58. package/dist/runtime/api/lib/server/project-root.d.ts +2 -0
  59. package/dist/runtime/api/lib/server/project-root.js +38 -0
  60. package/dist/runtime/api/lib/server/task-service-singleton.d.ts +7 -0
  61. package/dist/runtime/api/lib/server/task-service-singleton.js +58 -0
  62. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.d.ts +7 -0
  63. package/dist/runtime/api/lib/server/vibing-orchestrator-singleton.js +57 -0
  64. package/dist/runtime/api/lib/tiptap-utils.clamp-selection.test.d.ts +1 -0
  65. package/dist/runtime/api/lib/tiptap-utils.clamp-selection.test.js +27 -0
  66. package/dist/runtime/api/lib/tiptap-utils.d.ts +130 -0
  67. package/dist/runtime/api/lib/tiptap-utils.js +327 -0
  68. package/dist/runtime/api/lib/trpc/client.d.ts +1 -0
  69. package/dist/runtime/api/lib/trpc/client.js +5 -0
  70. package/dist/runtime/api/lib/trpc/server.d.ts +822 -0
  71. package/dist/runtime/api/lib/trpc/server.js +11 -0
  72. package/dist/runtime/api/lib/trpc/ws-server.d.ts +8 -0
  73. package/dist/runtime/api/lib/trpc/ws-server.js +33 -0
  74. package/dist/runtime/api/persistence/database-service.d.ts +14 -0
  75. package/dist/runtime/api/persistence/database-service.js +74 -0
  76. package/dist/runtime/api/persistence/execution-log-persistence.d.ts +90 -0
  77. package/dist/runtime/api/persistence/execution-log-persistence.js +410 -0
  78. package/dist/runtime/api/persistence/execution-log-persistence.test.d.ts +1 -0
  79. package/dist/runtime/api/persistence/execution-log-persistence.test.js +170 -0
  80. package/dist/runtime/api/router.d.ts +825 -0
  81. package/dist/runtime/api/router.js +56 -0
  82. package/dist/runtime/api/settings-service.d.ts +110 -0
  83. package/dist/runtime/api/settings-service.js +611 -0
  84. package/dist/runtime/api/tasks/file-watcher.d.ts +23 -0
  85. package/dist/runtime/api/tasks/file-watcher.js +88 -0
  86. package/dist/runtime/api/tasks/task-file-parser.d.ts +13 -0
  87. package/dist/runtime/api/tasks/task-file-parser.js +161 -0
  88. package/dist/runtime/api/tasks/task-service.d.ts +36 -0
  89. package/dist/runtime/api/tasks/task-service.js +173 -0
  90. package/dist/runtime/api/types/index.d.ts +179 -0
  91. package/dist/runtime/api/types/index.js +1 -0
  92. package/dist/runtime/api/types/settings.d.ts +81 -0
  93. package/dist/runtime/api/types/settings.js +2 -0
  94. package/dist/runtime/api/types.d.ts +2 -0
  95. package/dist/runtime/api/types.js +1 -0
  96. package/dist/runtime/api/utils/env.d.ts +6 -0
  97. package/dist/runtime/api/utils/env.js +12 -0
  98. package/dist/runtime/api/utils/stripNextEnv.d.ts +7 -0
  99. package/dist/runtime/api/utils/stripNextEnv.js +22 -0
  100. package/dist/runtime/api/utils/title-slug.d.ts +6 -0
  101. package/dist/runtime/api/utils/title-slug.js +77 -0
  102. package/dist/runtime/api/utils/url.d.ts +2 -0
  103. package/dist/runtime/api/utils/url.js +19 -0
  104. package/dist/runtime/api/vcs/git-history-service.d.ts +57 -0
  105. package/dist/runtime/api/vcs/git-history-service.js +228 -0
  106. package/dist/runtime/api/vcs/git-service.d.ts +127 -0
  107. package/dist/runtime/api/vcs/git-service.js +284 -0
  108. package/dist/runtime/api/vcs/worktree-service.d.ts +93 -0
  109. package/dist/runtime/api/vcs/worktree-service.js +506 -0
  110. package/dist/runtime/api/vcs/worktree-service.test.d.ts +1 -0
  111. package/dist/runtime/api/vcs/worktree-service.test.js +20 -0
  112. package/dist/runtime/api/workflows/quality-pipeline.d.ts +58 -0
  113. package/dist/runtime/api/workflows/quality-pipeline.js +400 -0
  114. package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +313 -0
  115. package/dist/runtime/api/workflows/vibing-orchestrator.js +1861 -0
  116. package/dist/runtime/web/.next/BUILD_ID +1 -0
  117. package/dist/runtime/web/.next/app-build-manifest.json +59 -0
  118. package/dist/runtime/web/.next/app-path-routes-manifest.json +7 -0
  119. package/dist/runtime/web/.next/build-manifest.json +33 -0
  120. package/dist/runtime/web/.next/package.json +1 -0
  121. package/dist/runtime/web/.next/prerender-manifest.json +61 -0
  122. package/dist/runtime/web/.next/react-loadable-manifest.json +39 -0
  123. package/dist/runtime/web/.next/required-server-files.json +334 -0
  124. package/dist/runtime/web/.next/routes-manifest.json +62 -0
  125. package/dist/runtime/web/.next/server/app/_not-found/page.js +2 -0
  126. package/dist/runtime/web/.next/server/app/_not-found/page.js.nft.json +1 -0
  127. package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  128. package/dist/runtime/web/.next/server/app/_not-found.html +7 -0
  129. package/dist/runtime/web/.next/server/app/_not-found.meta +8 -0
  130. package/dist/runtime/web/.next/server/app/_not-found.rsc +22 -0
  131. package/dist/runtime/web/.next/server/app/api/health/route.js +1 -0
  132. package/dist/runtime/web/.next/server/app/api/health/route.js.nft.json +1 -0
  133. package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +1 -0
  134. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +1 -0
  135. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js.nft.json +1 -0
  136. package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +1 -0
  137. package/dist/runtime/web/.next/server/app/api/upload/route.js +1 -0
  138. package/dist/runtime/web/.next/server/app/api/upload/route.js.nft.json +1 -0
  139. package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +1 -0
  140. package/dist/runtime/web/.next/server/app/index.html +7 -0
  141. package/dist/runtime/web/.next/server/app/index.meta +7 -0
  142. package/dist/runtime/web/.next/server/app/index.rsc +27 -0
  143. package/dist/runtime/web/.next/server/app/page.js +147 -0
  144. package/dist/runtime/web/.next/server/app/page.js.nft.json +1 -0
  145. package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +1 -0
  146. package/dist/runtime/web/.next/server/app-paths-manifest.json +7 -0
  147. package/dist/runtime/web/.next/server/chunks/217.js +1 -0
  148. package/dist/runtime/web/.next/server/chunks/383.js +6 -0
  149. package/dist/runtime/web/.next/server/chunks/458.js +1 -0
  150. package/dist/runtime/web/.next/server/chunks/576.js +18 -0
  151. package/dist/runtime/web/.next/server/chunks/635.js +22 -0
  152. package/dist/runtime/web/.next/server/chunks/761.js +1 -0
  153. package/dist/runtime/web/.next/server/chunks/777.js +3 -0
  154. package/dist/runtime/web/.next/server/chunks/825.js +1 -0
  155. package/dist/runtime/web/.next/server/chunks/838.js +1 -0
  156. package/dist/runtime/web/.next/server/chunks/973.js +15 -0
  157. package/dist/runtime/web/.next/server/functions-config-manifest.json +4 -0
  158. package/dist/runtime/web/.next/server/middleware-build-manifest.js +1 -0
  159. package/dist/runtime/web/.next/server/middleware-manifest.json +6 -0
  160. package/dist/runtime/web/.next/server/middleware-react-loadable-manifest.js +1 -0
  161. package/dist/runtime/web/.next/server/next-font-manifest.js +1 -0
  162. package/dist/runtime/web/.next/server/next-font-manifest.json +1 -0
  163. package/dist/runtime/web/.next/server/pages/404.html +7 -0
  164. package/dist/runtime/web/.next/server/pages/500.html +1 -0
  165. package/dist/runtime/web/.next/server/pages/_app.js +1 -0
  166. package/dist/runtime/web/.next/server/pages/_app.js.nft.json +1 -0
  167. package/dist/runtime/web/.next/server/pages/_document.js +1 -0
  168. package/dist/runtime/web/.next/server/pages/_document.js.nft.json +1 -0
  169. package/dist/runtime/web/.next/server/pages/_error.js +19 -0
  170. package/dist/runtime/web/.next/server/pages/_error.js.nft.json +1 -0
  171. package/dist/runtime/web/.next/server/pages-manifest.json +6 -0
  172. package/dist/runtime/web/.next/server/server-reference-manifest.js +1 -0
  173. package/dist/runtime/web/.next/server/server-reference-manifest.json +1 -0
  174. package/dist/runtime/web/.next/server/webpack-runtime.js +1 -0
  175. package/dist/runtime/web/.next/static/1HR8N0rJkCvFRtbTPJMyH/_buildManifest.js +1 -0
  176. package/dist/runtime/web/.next/static/1HR8N0rJkCvFRtbTPJMyH/_ssgManifest.js +1 -0
  177. package/dist/runtime/web/.next/static/chunks/18-15c10d3288afef2e.js +1 -0
  178. package/dist/runtime/web/.next/static/chunks/1c0ca389.537bbe362e3ffbd9.js +3 -0
  179. package/dist/runtime/web/.next/static/chunks/22747d63-ad5da0c19f4cfe41.js +71 -0
  180. package/dist/runtime/web/.next/static/chunks/277-0142a939f08738c3.js +63 -0
  181. package/dist/runtime/web/.next/static/chunks/355.056c2645878a799a.js +1 -0
  182. package/dist/runtime/web/.next/static/chunks/420.a5ccf151c9e2b2f1.js +1 -0
  183. package/dist/runtime/web/.next/static/chunks/439.1be0c6242fd248d5.js +15 -0
  184. package/dist/runtime/web/.next/static/chunks/440.c52e7c0f797e22b2.js +1 -0
  185. package/dist/runtime/web/.next/static/chunks/575-e2478287c27da87b.js +1 -0
  186. package/dist/runtime/web/.next/static/chunks/691.920d88c115087314.js +1 -0
  187. package/dist/runtime/web/.next/static/chunks/765-e838910065b50c3d.js +1 -0
  188. package/dist/runtime/web/.next/static/chunks/87c73c54-09e1ba5c70e60a51.js +1 -0
  189. package/dist/runtime/web/.next/static/chunks/891cff7f.0f71fc028f87e683.js +1 -0
  190. package/dist/runtime/web/.next/static/chunks/8bb4d8db-3e2aa02b0a2384b9.js +1 -0
  191. package/dist/runtime/web/.next/static/chunks/9af238c7-271a911d4e99ab18.js +1 -0
  192. package/dist/runtime/web/.next/static/chunks/app/_not-found/page-1cb74d1cba27d0ab.js +1 -0
  193. package/dist/runtime/web/.next/static/chunks/app/api/health/route-105a61ae865ba536.js +1 -0
  194. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-105a61ae865ba536.js +1 -0
  195. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-105a61ae865ba536.js +1 -0
  196. package/dist/runtime/web/.next/static/chunks/app/layout-dc0cfd29075b2160.js +1 -0
  197. package/dist/runtime/web/.next/static/chunks/app/page-f34a8b196b18850b.js +1 -0
  198. package/dist/runtime/web/.next/static/chunks/cac567b0-5b77dd12911823cd.js +1 -0
  199. package/dist/runtime/web/.next/static/chunks/framework-2518f1345b5b2806.js +1 -0
  200. package/dist/runtime/web/.next/static/chunks/main-17665e5e39de9a8a.js +1 -0
  201. package/dist/runtime/web/.next/static/chunks/main-app-c0b0f5ba4f7f9d75.js +1 -0
  202. package/dist/runtime/web/.next/static/chunks/pages/_app-d6f6b3bbc3d81ee1.js +1 -0
  203. package/dist/runtime/web/.next/static/chunks/pages/_error-75a96cf1997cc3b9.js +1 -0
  204. package/dist/runtime/web/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  205. package/dist/runtime/web/.next/static/chunks/webpack-c8de37305b4635cf.js +1 -0
  206. package/dist/runtime/web/.next/static/css/08c950681f1a9a92.css +1 -0
  207. package/dist/runtime/web/.next/static/css/2728291c68f99cb1.css +3 -0
  208. package/dist/runtime/web/.next/static/css/521bd69cc298cd1a.css +1 -0
  209. package/dist/runtime/web/.next/static/css/537e22821e101b87.css +1 -0
  210. package/dist/runtime/web/.next/static/media/19cfc7226ec3afaa-s.woff2 +0 -0
  211. package/dist/runtime/web/.next/static/media/21350d82a1f187e9-s.woff2 +0 -0
  212. package/dist/runtime/web/.next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  213. package/dist/runtime/web/.next/static/media/ba9851c3c22cd980-s.woff2 +0 -0
  214. package/dist/runtime/web/.next/static/media/c5fe6dc8356a8c31-s.woff2 +0 -0
  215. package/dist/runtime/web/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  216. package/dist/runtime/web/.next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  217. package/dist/runtime/web/package.json +65 -0
  218. package/dist/runtime/web/server.js +44 -0
  219. package/dist/tsconfig.tsbuildinfo +1 -0
  220. package/package.json +80 -7
@@ -0,0 +1,125 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { Plugin, PluginKey } from '@tiptap/pm/state';
3
+ import { handleImageUpload } from './tiptap-utils.js';
4
+ export const ImagePasteDrop = Extension.create({
5
+ name: 'imagePasteDrop',
6
+ addOptions() {
7
+ return {
8
+ upload: handleImageUpload,
9
+ onError: undefined,
10
+ onSuccess: undefined,
11
+ maxSize: 5 * 1024 * 1024, // 5MB
12
+ allowedTypes: [
13
+ 'image/jpeg',
14
+ 'image/jpg',
15
+ 'image/png',
16
+ 'image/gif',
17
+ 'image/webp',
18
+ 'image/svg+xml',
19
+ ],
20
+ };
21
+ },
22
+ addProseMirrorPlugins() {
23
+ const uploadAndInsertImages = (files, view, position) => {
24
+ files.forEach(async (file) => {
25
+ try {
26
+ // Validate file size
27
+ if (this.options.maxSize && file.size > this.options.maxSize) {
28
+ const error = new Error(`File size exceeds maximum allowed (${this.options.maxSize / (1024 * 1024)}MB)`);
29
+ this.options.onError?.(error);
30
+ return;
31
+ }
32
+ // Insert placeholder first
33
+ const placeholderTransaction = view.state.tr.insert(position, view.state.schema.text('🔄 Uploading...'));
34
+ view.dispatch(placeholderTransaction);
35
+ // Upload the image
36
+ const uploadFunction = this.options.upload || handleImageUpload;
37
+ const imageUrl = await uploadFunction(file);
38
+ // Replace placeholder with actual image
39
+ const filename = file.name.replace(/\.[^/.]+$/, '') || 'image';
40
+ const imageNode = view.state.schema.nodes.image.create({
41
+ src: imageUrl,
42
+ alt: filename,
43
+ title: filename,
44
+ });
45
+ // Find the placeholder text and replace it
46
+ const currentState = view.state;
47
+ let found = false;
48
+ currentState.doc.descendants((node, pos) => {
49
+ if (!found && node.isText && node.text === '🔄 Uploading...') {
50
+ const replaceTransaction = currentState.tr.replaceRangeWith(pos, pos + node.nodeSize, imageNode);
51
+ view.dispatch(replaceTransaction);
52
+ found = true;
53
+ return false;
54
+ }
55
+ return true;
56
+ });
57
+ this.options.onSuccess?.(imageUrl);
58
+ }
59
+ catch (error) {
60
+ // Remove placeholder on error
61
+ const currentState = view.state;
62
+ currentState.doc.descendants((node, pos) => {
63
+ if (node.isText && node.text === '🔄 Uploading...') {
64
+ const deleteTransaction = currentState.tr.delete(pos, pos + node.nodeSize);
65
+ view.dispatch(deleteTransaction);
66
+ return false;
67
+ }
68
+ return true;
69
+ });
70
+ const errorMessage = error instanceof Error ? error : new Error('Upload failed');
71
+ this.options.onError?.(errorMessage);
72
+ }
73
+ });
74
+ };
75
+ return [
76
+ new Plugin({
77
+ key: new PluginKey('imagePasteDrop'),
78
+ props: {
79
+ handleDOMEvents: {
80
+ // Handle drag and drop
81
+ drop: (view, event) => {
82
+ event.preventDefault();
83
+ const { files } = event.dataTransfer;
84
+ const imageFiles = Array.from(files).filter((file) => this.options.allowedTypes?.includes(file.type));
85
+ if (imageFiles.length === 0) {
86
+ return false;
87
+ }
88
+ // Get drop position
89
+ const pos = view.posAtCoords({
90
+ left: event.clientX,
91
+ top: event.clientY,
92
+ });
93
+ if (!pos)
94
+ return false;
95
+ uploadAndInsertImages(imageFiles, view, pos.pos);
96
+ return true;
97
+ },
98
+ // Handle paste
99
+ paste: (view, event) => {
100
+ const { files } = event.clipboardData;
101
+ const imageFiles = Array.from(files).filter((file) => this.options.allowedTypes?.includes(file.type));
102
+ if (imageFiles.length === 0) {
103
+ return false;
104
+ }
105
+ event.preventDefault();
106
+ // Insert at current cursor position
107
+ const { selection } = view.state;
108
+ uploadAndInsertImages(imageFiles, view, selection.from);
109
+ return true;
110
+ },
111
+ // Prevent default drag behaviors
112
+ dragover: (view, event) => {
113
+ event.preventDefault();
114
+ return false;
115
+ },
116
+ dragenter: (view, event) => {
117
+ event.preventDefault();
118
+ return false;
119
+ },
120
+ },
121
+ },
122
+ }),
123
+ ];
124
+ },
125
+ });
@@ -0,0 +1,11 @@
1
+ import { Logger } from 'pino';
2
+ export declare const logger: Logger;
3
+ export declare function createContextLogger(context: string): Logger;
4
+ export declare const log: {
5
+ error: (message: string, error?: Error | unknown, context?: string) => void;
6
+ warn: (message: string, data?: unknown, context?: string) => void;
7
+ info: (message: string, data?: unknown, context?: string) => void;
8
+ debug: (message: string, data?: unknown, context?: string) => void;
9
+ trace: (message: string, data?: unknown, context?: string) => void;
10
+ };
11
+ export default logger;
@@ -0,0 +1,188 @@
1
+ import pino from 'pino';
2
+ // Check if we're running in browser context
3
+ const isBrowser = typeof globalThis !== 'undefined' && 'window' in globalThis;
4
+ // Simple environment detection to avoid import issues
5
+ function isDevelopment() {
6
+ return process.env.NODE_ENV === 'development';
7
+ }
8
+ // Environment detection - check both environment variable and process args for verbose mode
9
+ const isVerbose = process.env.VERBOSE === 'true' ||
10
+ (typeof process !== 'undefined' &&
11
+ process.argv &&
12
+ (process.argv.includes('--verbose') || process.argv.includes('-v')));
13
+ // Optional explicit log level/format override
14
+ const envLogLevel = (process.env.VIBEMAN_LOG_LEVEL || process.env.LOG_LEVEL || '').toLowerCase();
15
+ const envLogStyle = (process.env.VIBEMAN_LOG_STYLE || process.env.LOG_STYLE || '').toLowerCase();
16
+ const paramSplitter = process.env.VIBEMAN_LOG_SPLIT || process.env.LOG_SPLIT || ' | ';
17
+ // Determine log level based on environment and verbose flag
18
+ function getLogLevel() {
19
+ if (envLogLevel &&
20
+ ['silent', 'fatal', 'error', 'warn', 'info', 'debug', 'trace'].includes(envLogLevel)) {
21
+ return envLogLevel;
22
+ }
23
+ if (isVerbose)
24
+ return 'debug';
25
+ if (isDevelopment())
26
+ return 'info';
27
+ return 'error';
28
+ }
29
+ // Create logger configuration
30
+ const loggerConfig = {
31
+ level: getLogLevel(),
32
+ ...(isBrowser
33
+ ? {
34
+ // Browser configuration - use simple console
35
+ browser: { asObject: false },
36
+ }
37
+ : {
38
+ // Node.js configuration
39
+ formatters: {
40
+ level: (label) => ({ level: label }),
41
+ log: (object) => object,
42
+ },
43
+ transport: {
44
+ target: 'pino-pretty',
45
+ options: (() => {
46
+ const base = {
47
+ colorize: true,
48
+ translateTime: 'HH:MM:ss',
49
+ ignore: 'pid,hostname',
50
+ };
51
+ if (envLogStyle !== 'pretty') {
52
+ base.singleLine = false;
53
+ base.hideObject = false; // allow error objects to render stacks
54
+ return base;
55
+ }
56
+ // Pretty (multi-line) with inline context, print objects nicely
57
+ base.levelFirst = true;
58
+ base.messageFormat = (log, messageKey) => log?.context ? `[${log.context}] ${log[messageKey]}` : log[messageKey];
59
+ return base;
60
+ })(),
61
+ },
62
+ }),
63
+ };
64
+ // Create the logger instance
65
+ export const logger = pino(loggerConfig);
66
+ // Context-aware logger factory
67
+ export function createContextLogger(context) {
68
+ return logger.child({ context });
69
+ }
70
+ // Convenience methods for common logging patterns
71
+ export const log = {
72
+ error: (message, error, context) => {
73
+ const contextLogger = context ? createContextLogger(context) : logger;
74
+ const msg = context ? `[${context}] ${message}` : message;
75
+ if (error instanceof Error) {
76
+ // Keep error object so stack renders, even in compact
77
+ contextLogger.error({ err: error }, msg);
78
+ }
79
+ else if (error) {
80
+ contextLogger.error({ err: error }, msg);
81
+ }
82
+ else {
83
+ contextLogger.error(msg);
84
+ }
85
+ },
86
+ warn: (message, data, context) => {
87
+ const contextLogger = context ? createContextLogger(context) : logger;
88
+ const msg = context ? `[${context}] ${message}` : message;
89
+ if (data && envLogStyle !== 'pretty') {
90
+ const entries = Object.entries(data);
91
+ const messageEntry = entries.find(([k]) => k === 'message');
92
+ const other = entries.filter(([k]) => k !== 'message');
93
+ const pairs = other.map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(paramSplitter);
94
+ const body = (() => {
95
+ if (!messageEntry)
96
+ return '';
97
+ const val = messageEntry[1];
98
+ if (typeof val === 'string')
99
+ return `\n${val}`; // print as-is (newlines preserved)
100
+ return `\n${JSON.stringify(val, null, 2)}`;
101
+ })();
102
+ contextLogger.warn(pairs ? `${msg} ${pairs}${body}` : `${msg}${body}`);
103
+ }
104
+ else if (data) {
105
+ contextLogger.warn(data, msg);
106
+ }
107
+ else {
108
+ contextLogger.warn(msg);
109
+ }
110
+ },
111
+ info: (message, data, context) => {
112
+ const contextLogger = context ? createContextLogger(context) : logger;
113
+ const msg = context ? `[${context}] ${message}` : message;
114
+ if (data && envLogStyle !== 'pretty') {
115
+ const entries = Object.entries(data);
116
+ const messageEntry = entries.find(([k]) => k === 'message');
117
+ const other = entries.filter(([k]) => k !== 'message');
118
+ const pairs = other.map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(paramSplitter);
119
+ const body = (() => {
120
+ if (!messageEntry)
121
+ return '';
122
+ const val = messageEntry[1];
123
+ if (typeof val === 'string')
124
+ return `\n${val}`;
125
+ return `\n${JSON.stringify(val, null, 2)}`;
126
+ })();
127
+ contextLogger.info(pairs ? `${msg} ${pairs}${body}` : `${msg}${body}`);
128
+ }
129
+ else if (data) {
130
+ contextLogger.info(data, msg);
131
+ }
132
+ else {
133
+ contextLogger.info(msg);
134
+ }
135
+ },
136
+ debug: (message, data, context) => {
137
+ const contextLogger = context ? createContextLogger(context) : logger;
138
+ const msg = context ? `[${context}] ${message}` : message;
139
+ if (data && envLogStyle !== 'pretty') {
140
+ const entries = Object.entries(data);
141
+ const messageEntry = entries.find(([k]) => k === 'message');
142
+ const other = entries.filter(([k]) => k !== 'message');
143
+ const pairs = other.map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(paramSplitter);
144
+ const body = (() => {
145
+ if (!messageEntry)
146
+ return '';
147
+ const val = messageEntry[1];
148
+ if (typeof val === 'string')
149
+ return `\n${val}`;
150
+ return `\n${JSON.stringify(val, null, 2)}`;
151
+ })();
152
+ contextLogger.debug(pairs ? `${msg} ${pairs}${body}` : `${msg}${body}`);
153
+ }
154
+ else if (data) {
155
+ contextLogger.debug(data, msg);
156
+ }
157
+ else {
158
+ contextLogger.debug(msg);
159
+ }
160
+ },
161
+ trace: (message, data, context) => {
162
+ const contextLogger = context ? createContextLogger(context) : logger;
163
+ const msg = context ? `[${context}] ${message}` : message;
164
+ if (data && envLogStyle !== 'pretty') {
165
+ const entries = Object.entries(data);
166
+ const messageEntry = entries.find(([k]) => k === 'message');
167
+ const other = entries.filter(([k]) => k !== 'message');
168
+ const pairs = other.map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(paramSplitter);
169
+ const body = (() => {
170
+ if (!messageEntry)
171
+ return '';
172
+ const val = messageEntry[1];
173
+ if (typeof val === 'string')
174
+ return `\n${val}`;
175
+ return `\n${JSON.stringify(val, null, 2)}`;
176
+ })();
177
+ contextLogger.trace(pairs ? `${msg} ${pairs}${body}` : `${msg}${body}`);
178
+ }
179
+ else if (data) {
180
+ contextLogger.trace(data, msg);
181
+ }
182
+ else {
183
+ contextLogger.trace(msg);
184
+ }
185
+ },
186
+ };
187
+ // Export default logger for direct use
188
+ export default logger;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Convert markdown to HTML for Tiptap editor
3
+ */
4
+ export declare function markdownToHtml(markdown: string): string;
5
+ /**
6
+ * Convert HTML to markdown for storage
7
+ */
8
+ export declare function htmlToMarkdown(html: string): string;
@@ -0,0 +1,282 @@
1
+ import { marked } from 'marked';
2
+ import TurndownService from 'turndown';
3
+ import { gfm } from 'turndown-plugin-gfm';
4
+ marked.setOptions({
5
+ gfm: true,
6
+ breaks: false,
7
+ });
8
+ const turndownService = new TurndownService({
9
+ headingStyle: 'atx',
10
+ hr: '---',
11
+ bulletListMarker: '-',
12
+ codeBlockStyle: 'fenced',
13
+ fence: '```',
14
+ });
15
+ // Use GitHub Flavored Markdown plugin
16
+ turndownService.use(gfm);
17
+ // Custom rule for regular list items to use single space after dash
18
+ turndownService.addRule('listItem', {
19
+ filter: (node) => {
20
+ return (node.nodeName === 'LI' && !node.getAttribute('data-type') // Not a task item
21
+ );
22
+ },
23
+ replacement: (content, node, _options) => {
24
+ content = content
25
+ .replace(/^\n+/, '') // Remove leading newlines
26
+ .replace(/\n+$/, '\n') // Replace trailing newlines with just one
27
+ .replace(/\n/gm, '\n '); // Indent subsequent lines
28
+ let prefix = '- '; // Use single space after dash
29
+ const parent = node.parentNode;
30
+ if (parent && parent.nodeName === 'OL') {
31
+ const index = Array.prototype.indexOf.call(parent.children, node);
32
+ const start = parent.getAttribute('start');
33
+ const startIndex = start ? parseInt(start, 10) - 1 : 0;
34
+ prefix = startIndex + index + 1 + '. ';
35
+ }
36
+ return prefix + content + (node.nextSibling && !/\n$/.test(content) ? '\n' : '');
37
+ },
38
+ });
39
+ // Custom rule for TipTap TaskItems
40
+ turndownService.addRule('tiptapTaskItem', {
41
+ filter: (node, _options) => {
42
+ return (node.nodeName === 'LI' &&
43
+ node.getAttribute('data-type') === 'taskItem' &&
44
+ node.getAttribute('data-checked') !== null);
45
+ },
46
+ replacement: (content, node) => {
47
+ const element = node;
48
+ const isChecked = element.getAttribute('data-checked') === 'true';
49
+ const checkbox = isChecked ? '[x]' : '[ ]';
50
+ // Extract text content from the div > p structure
51
+ const contentDiv = element.querySelector('div');
52
+ const textContent = contentDiv ? contentDiv.textContent?.trim() || '' : content.trim();
53
+ return `- ${checkbox} ${textContent}`;
54
+ },
55
+ });
56
+ // Custom rule for TipTap TaskLists - handles nested structure properly
57
+ turndownService.addRule('tiptapTaskList', {
58
+ filter: (node) => {
59
+ return node.nodeName === 'UL' && node.getAttribute('data-type') === 'taskList';
60
+ },
61
+ replacement: (content, node) => {
62
+ // Process only direct child li elements to preserve nesting
63
+ const directItems = Array.from(node.children).filter((child) => child.nodeName === 'LI' && child.getAttribute('data-type') === 'taskItem');
64
+ if (directItems.length === 0)
65
+ return content;
66
+ const processTaskItem = (li, indent = '') => {
67
+ const isChecked = li.getAttribute('data-checked') === 'true';
68
+ const checkbox = isChecked ? '[x]' : '[ ]';
69
+ // Get text content from the div, excluding nested lists
70
+ const contentDiv = li.querySelector('div');
71
+ let textContent = '';
72
+ if (contentDiv) {
73
+ // Clone the div to avoid modifying the original
74
+ const tempDiv = contentDiv.cloneNode(true);
75
+ // Remove any nested ul elements from the clone to get just the text
76
+ const nestedLists = Array.from(tempDiv.querySelectorAll('ul'));
77
+ nestedLists.forEach((list) => {
78
+ if (list instanceof Element) {
79
+ list.remove();
80
+ }
81
+ });
82
+ textContent = tempDiv.textContent?.trim() || '';
83
+ }
84
+ let result = `${indent}- ${checkbox} ${textContent}`;
85
+ // Process nested task lists
86
+ const nestedList = li.querySelector('ul[data-type="taskList"]');
87
+ if (nestedList) {
88
+ const nestedItems = Array.from(nestedList.children).filter((child) => child.nodeName === 'LI' && child.getAttribute('data-type') === 'taskItem');
89
+ nestedItems.forEach((nestedLi) => {
90
+ if (nestedLi instanceof Element) {
91
+ result += '\n' + processTaskItem(nestedLi, indent + ' ');
92
+ }
93
+ });
94
+ }
95
+ return result;
96
+ };
97
+ return '\n' + directItems.map((li) => processTaskItem(li)).join('\n') + '\n';
98
+ },
99
+ });
100
+ // Override paragraph handling to preserve paragraph breaks
101
+ // Ensure there is a blank line between paragraphs in markdown
102
+ turndownService.addRule('paragraph', {
103
+ filter: 'p',
104
+ replacement: (content) => {
105
+ return '\n\n' + content.trim() + '\n\n';
106
+ },
107
+ });
108
+ /**
109
+ * Clean up HTML by removing <p> tags within <li> elements under <ul> or <ol> lists
110
+ */
111
+ function cleanupListParagraphs(html) {
112
+ if (!html?.trim())
113
+ return html;
114
+ // Use DOM parsing to handle nested structures properly
115
+ if (typeof window !== 'undefined') {
116
+ const parser = new DOMParser();
117
+ const doc = parser.parseFromString(html, 'text/html');
118
+ // Find all <li> elements within <ul> or <ol>
119
+ const listItems = doc.querySelectorAll('ul > li, ol > li');
120
+ listItems.forEach((li) => {
121
+ // Find all <p> tags directly within this <li>
122
+ const paragraphs = Array.from(li.querySelectorAll('p'));
123
+ paragraphs.forEach((p) => {
124
+ // Only remove <p> if it's a direct child or within the list item structure
125
+ if (p.parentElement === li ||
126
+ (p.parentElement && ['UL', 'OL', 'LI'].includes(p.parentElement.nodeName))) {
127
+ // Replace <p> with its content
128
+ const content = p.innerHTML;
129
+ const textNode = doc.createDocumentFragment();
130
+ textNode.appendChild(doc.createTextNode(content));
131
+ // For better HTML structure, we'll replace with the content directly
132
+ p.outerHTML = content;
133
+ }
134
+ });
135
+ });
136
+ return doc.body.innerHTML;
137
+ }
138
+ // Fallback for server-side: use regex approach (less robust but works)
139
+ // Remove <p> and </p> tags within <li> elements
140
+ return html
141
+ .replace(/<li([^>]*)><p>/g, '<li$1>')
142
+ .replace(/<\/p><\/li>/g, '</li>')
143
+ .replace(/<\/p><ul>/g, '<ul>')
144
+ .replace(/<\/p><ol>/g, '<ol>')
145
+ .replace(/<\/ul><p>/g, '</ul>')
146
+ .replace(/<\/ol><p>/g, '</ol>');
147
+ }
148
+ /**
149
+ * Convert GFM checkbox HTML to Tiptap TaskItem format
150
+ */
151
+ function convertToTiptapTaskItems(html) {
152
+ if (!html?.trim())
153
+ return html;
154
+ // Use DOM parsing for better accuracy
155
+ if (typeof window !== 'undefined') {
156
+ const parser = new DOMParser();
157
+ const doc = parser.parseFromString(html, 'text/html');
158
+ // Process all ul elements, starting from the deepest nested ones
159
+ const lists = Array.from(doc.querySelectorAll('ul')).reverse();
160
+ lists.forEach((ul) => {
161
+ let hasTaskItems = false;
162
+ // Only process direct children li elements to preserve nesting
163
+ const directListItems = Array.from(ul.children).filter((child) => child.nodeName === 'LI');
164
+ directListItems.forEach((li) => {
165
+ const checkbox = li.querySelector('input[type="checkbox"]');
166
+ if (checkbox) {
167
+ hasTaskItems = true;
168
+ // Get the checkbox state
169
+ const isChecked = checkbox.hasAttribute('checked');
170
+ // Set TaskItem attributes
171
+ li.setAttribute('data-type', 'taskItem');
172
+ li.setAttribute('data-checked', isChecked ? 'true' : 'false');
173
+ // Get the text content, preserving nested structure
174
+ const clonedLi = li.cloneNode(true);
175
+ // Remove the checkbox from the clone
176
+ const clonedCheckbox = clonedLi.querySelector('input[type="checkbox"]');
177
+ if (clonedCheckbox) {
178
+ clonedCheckbox.remove();
179
+ }
180
+ // Extract nested lists to preserve them
181
+ const nestedLists = Array.from(clonedLi.querySelectorAll('ul'));
182
+ const nestedListsHTML = nestedLists.map((list) => list.outerHTML);
183
+ // Remove nested lists temporarily to get just the text content
184
+ nestedLists.forEach((list) => {
185
+ if (list instanceof Element) {
186
+ list.remove();
187
+ }
188
+ });
189
+ // Get the text content
190
+ const textContent = clonedLi.textContent?.trim() || '';
191
+ // Create the proper TipTap structure
192
+ let innerHTML = `
193
+ <label contenteditable="false">
194
+ <input type="checkbox" ${isChecked ? 'checked' : ''}>
195
+ <span></span>
196
+ </label>
197
+ <div>
198
+ <p>${textContent}</p>`;
199
+ // Add back any nested lists, ensuring they have the correct data-type
200
+ if (nestedListsHTML.length > 0) {
201
+ nestedListsHTML.forEach((nestedHTML) => {
202
+ // Make sure nested task lists have the correct data-type attribute
203
+ let processedHTML = nestedHTML;
204
+ if (nestedHTML.includes('data-type="taskItem"') &&
205
+ !nestedHTML.includes('data-type="taskList"')) {
206
+ processedHTML = nestedHTML.replace('<ul>', '<ul data-type="taskList">');
207
+ }
208
+ innerHTML += processedHTML;
209
+ });
210
+ }
211
+ innerHTML += '</div>';
212
+ li.innerHTML = innerHTML.trim();
213
+ }
214
+ });
215
+ // If this ul contains task items, mark it as a taskList
216
+ if (hasTaskItems) {
217
+ ul.setAttribute('data-type', 'taskList');
218
+ }
219
+ });
220
+ return doc.body.innerHTML;
221
+ }
222
+ // Fallback for server-side: use regex approach (less robust)
223
+ return (html
224
+ // First pass: Convert list items with checkboxes
225
+ .replace(/<li>(\s*)<input\s+([^>]*?)type="checkbox"([^>]*?)>([^<]*)/gi, (match, leadingSpace, beforeType, afterType, textContent) => {
226
+ const isChecked = beforeType.includes('checked') || afterType.includes('checked');
227
+ const cleanText = textContent.trim();
228
+ return `<li data-type="taskItem" data-checked="${isChecked ? 'true' : 'false'}">
229
+ <label contenteditable="false">
230
+ <input type="checkbox" ${isChecked ? 'checked' : ''}>
231
+ <span></span>
232
+ </label>
233
+ <div>
234
+ <p>${cleanText}</p>
235
+ </div>`;
236
+ })
237
+ // Second pass: Mark parent ul as taskList if it contains taskItems
238
+ .replace(/<ul>(\s*(?:<li[^>]*data-type="taskItem"[^>]*>[\s\S]*?<\/li>\s*)+)<\/ul>/gi, '<ul data-type="taskList">$1</ul>'));
239
+ }
240
+ /**
241
+ * Pre-process markdown to ensure proper task list item boundaries
242
+ */
243
+ function preprocessMarkdownTaskItems(markdown) {
244
+ if (!markdown?.trim())
245
+ return markdown;
246
+ // Split markdown into lines
247
+ const lines = markdown.split('\n');
248
+ const processedLines = [];
249
+ for (let i = 0; i < lines.length; i++) {
250
+ const line = lines[i];
251
+ const nextLine = i + 1 < lines.length ? lines[i + 1] : '';
252
+ processedLines.push(line);
253
+ // If current line is a task item and next line is not empty and not indented
254
+ // and not another list item, add a blank line to separate them
255
+ if (line.trim().match(/^-\s+\[[ x]\]/) &&
256
+ nextLine.trim() &&
257
+ !nextLine.match(/^-\s+/) &&
258
+ !nextLine.match(/^\s{2,}/)) {
259
+ processedLines.push(''); // Add blank line
260
+ }
261
+ }
262
+ return processedLines.join('\n');
263
+ }
264
+ /**
265
+ * Convert markdown to HTML for Tiptap editor
266
+ */
267
+ export function markdownToHtml(markdown) {
268
+ if (!markdown?.trim())
269
+ return '';
270
+ const preprocessedMarkdown = preprocessMarkdownTaskItems(markdown);
271
+ const html = marked(preprocessedMarkdown);
272
+ return convertToTiptapTaskItems(html);
273
+ }
274
+ /**
275
+ * Convert HTML to markdown for storage
276
+ */
277
+ export function htmlToMarkdown(html) {
278
+ if (!html?.trim())
279
+ return '';
280
+ const cleanedHtml = cleanupListParagraphs(html);
281
+ return turndownService.turndown(cleanedHtml);
282
+ }
@@ -0,0 +1 @@
1
+ export {};