vibeman 0.0.1 → 0.0.3

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 (102) hide show
  1. package/dist/index.js +5 -7
  2. package/dist/runtime/api/.tsbuildinfo +1 -1
  3. package/dist/runtime/api/agent/agent-service.d.ts +18 -19
  4. package/dist/runtime/api/agent/agent-service.js +61 -58
  5. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.d.ts +2 -2
  6. package/dist/runtime/api/agent/ai-providers/claude-code-adapter.js +25 -36
  7. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.d.ts +2 -0
  8. package/dist/runtime/api/agent/ai-providers/codex-cli-provider.js +109 -43
  9. package/dist/runtime/api/agent/ai-providers/types.d.ts +2 -0
  10. package/dist/runtime/api/agent/codex-cli-provider.test.js +83 -1
  11. package/dist/runtime/api/agent/parsers.d.ts +1 -0
  12. package/dist/runtime/api/agent/parsers.js +75 -8
  13. package/dist/runtime/api/agent/prompt-service.d.ts +14 -1
  14. package/dist/runtime/api/agent/prompt-service.js +123 -14
  15. package/dist/runtime/api/agent/prompt-service.test.js +230 -0
  16. package/dist/runtime/api/agent/routing-policy.d.ts +25 -42
  17. package/dist/runtime/api/agent/routing-policy.js +82 -132
  18. package/dist/runtime/api/agent/routing-policy.test.js +63 -0
  19. package/dist/runtime/api/api/routers/ai.d.ts +19 -7
  20. package/dist/runtime/api/api/routers/ai.js +9 -23
  21. package/dist/runtime/api/api/routers/executions.d.ts +4 -4
  22. package/dist/runtime/api/api/routers/executions.js +12 -21
  23. package/dist/runtime/api/api/routers/provider-config.d.ts +165 -0
  24. package/dist/runtime/api/api/routers/provider-config.js +252 -0
  25. package/dist/runtime/api/api/routers/tasks.d.ts +9 -9
  26. package/dist/runtime/api/api/routers/workflows.d.ts +23 -16
  27. package/dist/runtime/api/api/routers/workflows.js +30 -27
  28. package/dist/runtime/api/api/routers/worktrees.d.ts +4 -5
  29. package/dist/runtime/api/api/routers/worktrees.js +11 -11
  30. package/dist/runtime/api/api/trpc.d.ts +16 -16
  31. package/dist/runtime/api/index.js +2 -10
  32. package/dist/runtime/api/lib/local-config.d.ts +245 -0
  33. package/dist/runtime/api/lib/local-config.js +288 -0
  34. package/dist/runtime/api/lib/provider-detection.d.ts +59 -0
  35. package/dist/runtime/api/lib/provider-detection.js +244 -0
  36. package/dist/runtime/api/lib/server/bootstrap.d.ts +38 -0
  37. package/dist/runtime/api/lib/server/bootstrap.js +197 -0
  38. package/dist/runtime/api/lib/server/project-root.js +24 -1
  39. package/dist/runtime/api/lib/trpc/server.d.ts +143 -30
  40. package/dist/runtime/api/lib/trpc/server.js +8 -8
  41. package/dist/runtime/api/lib/trpc/ws-server.js +2 -2
  42. package/dist/runtime/api/router.d.ts +144 -31
  43. package/dist/runtime/api/router.js +9 -31
  44. package/dist/runtime/api/settings-service.js +51 -1
  45. package/dist/runtime/api/types/index.d.ts +8 -1
  46. package/dist/runtime/api/types/settings.d.ts +15 -2
  47. package/dist/runtime/api/workflows/vibing-orchestrator.d.ts +8 -3
  48. package/dist/runtime/api/workflows/vibing-orchestrator.js +214 -184
  49. package/dist/runtime/web/.next/BUILD_ID +1 -1
  50. package/dist/runtime/web/.next/app-build-manifest.json +19 -12
  51. package/dist/runtime/web/.next/app-path-routes-manifest.json +2 -1
  52. package/dist/runtime/web/.next/build-manifest.json +2 -2
  53. package/dist/runtime/web/.next/prerender-manifest.json +10 -10
  54. package/dist/runtime/web/.next/routes-manifest.json +8 -0
  55. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js +1 -0
  56. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route.js.nft.json +1 -0
  57. package/dist/runtime/web/.next/server/app/.vibeman/assets/images/[...path]/route_client-reference-manifest.js +1 -0
  58. package/dist/runtime/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  59. package/dist/runtime/web/.next/server/app/_not-found.html +2 -2
  60. package/dist/runtime/web/.next/server/app/_not-found.rsc +5 -5
  61. package/dist/runtime/web/.next/server/app/api/health/route.js +1 -1
  62. package/dist/runtime/web/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  63. package/dist/runtime/web/.next/server/app/api/images/[...path]/route.js +1 -1
  64. package/dist/runtime/web/.next/server/app/api/images/[...path]/route_client-reference-manifest.js +1 -1
  65. package/dist/runtime/web/.next/server/app/api/upload/route.js +1 -1
  66. package/dist/runtime/web/.next/server/app/api/upload/route_client-reference-manifest.js +1 -1
  67. package/dist/runtime/web/.next/server/app/index.html +2 -2
  68. package/dist/runtime/web/.next/server/app/index.rsc +6 -6
  69. package/dist/runtime/web/.next/server/app/page.js +21 -21
  70. package/dist/runtime/web/.next/server/app/page_client-reference-manifest.js +1 -1
  71. package/dist/runtime/web/.next/server/app-paths-manifest.json +2 -1
  72. package/dist/runtime/web/.next/server/chunks/458.js +1 -1
  73. package/dist/runtime/web/.next/server/pages/404.html +2 -2
  74. package/dist/runtime/web/.next/server/pages/500.html +1 -1
  75. package/dist/runtime/web/.next/server/pages-manifest.json +1 -1
  76. package/dist/runtime/web/.next/server/server-reference-manifest.json +1 -1
  77. package/dist/runtime/web/.next/static/5_15u1WQCxN1_eHZpldCv/_buildManifest.js +1 -0
  78. package/dist/runtime/web/.next/static/chunks/{277-0142a939f08738c3.js → 823-6f371a6e829adbba.js} +1 -1
  79. package/dist/runtime/web/.next/static/chunks/app/.vibeman/assets/images/[...path]/route-751c9265a65409e5.js +1 -0
  80. package/dist/runtime/web/.next/static/chunks/app/api/health/route-751c9265a65409e5.js +1 -0
  81. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-751c9265a65409e5.js +1 -0
  82. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-751c9265a65409e5.js +1 -0
  83. package/dist/runtime/web/.next/static/chunks/app/{layout-dc0cfd29075b2160.js → layout-8435322f09fd0975.js} +1 -1
  84. package/dist/runtime/web/.next/static/chunks/app/page-9fe7d75095b4ccec.js +1 -0
  85. package/dist/tsconfig.tsbuildinfo +1 -1
  86. package/package.json +5 -1
  87. package/dist/runtime/api/lib/image-paste-drop-extension.d.ts +0 -26
  88. package/dist/runtime/api/lib/image-paste-drop-extension.js +0 -125
  89. package/dist/runtime/api/lib/markdown-utils.d.ts +0 -8
  90. package/dist/runtime/api/lib/markdown-utils.js +0 -282
  91. package/dist/runtime/api/lib/markdown-utils.test.js +0 -348
  92. package/dist/runtime/api/lib/tiptap-utils.clamp-selection.test.js +0 -27
  93. package/dist/runtime/api/lib/tiptap-utils.d.ts +0 -130
  94. package/dist/runtime/api/lib/tiptap-utils.js +0 -327
  95. package/dist/runtime/web/.next/static/1HR8N0rJkCvFRtbTPJMyH/_buildManifest.js +0 -1
  96. package/dist/runtime/web/.next/static/chunks/app/api/health/route-105a61ae865ba536.js +0 -1
  97. package/dist/runtime/web/.next/static/chunks/app/api/images/[...path]/route-105a61ae865ba536.js +0 -1
  98. package/dist/runtime/web/.next/static/chunks/app/api/upload/route-105a61ae865ba536.js +0 -1
  99. package/dist/runtime/web/.next/static/chunks/app/page-f34a8b196b18850b.js +0 -1
  100. /package/dist/runtime/api/{lib/markdown-utils.test.d.ts → agent/prompt-service.test.d.ts} +0 -0
  101. /package/dist/runtime/api/{lib/tiptap-utils.clamp-selection.test.d.ts → agent/routing-policy.test.d.ts} +0 -0
  102. /package/dist/runtime/web/.next/static/{1HR8N0rJkCvFRtbTPJMyH → 5_15u1WQCxN1_eHZpldCv}/_ssgManifest.js +0 -0
@@ -1,130 +0,0 @@
1
- import type { Node as TiptapNode } from '@tiptap/pm/model';
2
- import type { Editor } from '@tiptap/react';
3
- export declare const MAX_FILE_SIZE: number;
4
- export declare const MAC_SYMBOLS: Record<string, string>;
5
- export declare function cn(...classes: (string | boolean | undefined | null)[]): string;
6
- /**
7
- * Determines if the current platform is macOS
8
- * @returns boolean indicating if the current platform is Mac
9
- */
10
- export declare function isMac(): boolean;
11
- /**
12
- * Formats a shortcut key based on the platform (Mac or non-Mac)
13
- * @param key - The key to format (e.g., "ctrl", "alt", "shift")
14
- * @param isMac - Boolean indicating if the platform is Mac
15
- * @param capitalize - Whether to capitalize the key (default: true)
16
- * @returns Formatted shortcut key symbol
17
- */
18
- export declare const formatShortcutKey: (key: string, isMac: boolean, capitalize?: boolean) => string;
19
- /**
20
- * Parses a shortcut key string into an array of formatted key symbols
21
- * @param shortcutKeys - The string of shortcut keys (e.g., "ctrl-alt-shift")
22
- * @param delimiter - The delimiter used to split the keys (default: "-")
23
- * @param capitalize - Whether to capitalize the keys (default: true)
24
- * @returns Array of formatted shortcut key symbols
25
- */
26
- export declare const parseShortcutKeys: (props: {
27
- shortcutKeys: string | undefined;
28
- delimiter?: string;
29
- capitalize?: boolean;
30
- }) => string[];
31
- /**
32
- * Checks if a mark exists in the editor schema
33
- * @param markName - The name of the mark to check
34
- * @param editor - The editor instance
35
- * @returns boolean indicating if the mark exists in the schema
36
- */
37
- export declare const isMarkInSchema: (markName: string, editor: Editor | null) => boolean;
38
- /**
39
- * Checks if a node exists in the editor schema
40
- * @param nodeName - The name of the node to check
41
- * @param editor - The editor instance
42
- * @returns boolean indicating if the node exists in the schema
43
- */
44
- export declare const isNodeInSchema: (nodeName: string, editor: Editor | null) => boolean;
45
- /**
46
- * Moves the focus to the next node in the editor
47
- * @param editor - The editor instance
48
- * @returns boolean indicating if the focus was moved
49
- */
50
- export declare function focusNextNode(editor: Editor): boolean;
51
- /**
52
- * Checks if a value is a valid number (not null, undefined, or NaN)
53
- * @param value - The value to check
54
- * @returns boolean indicating if the value is a valid number
55
- */
56
- export declare function isValidPosition(pos: number | null | undefined): pos is number;
57
- /**
58
- * Checks if one or more extensions are registered in the Tiptap editor.
59
- * @param editor - The Tiptap editor instance
60
- * @param extensionNames - A single extension name or an array of names to check
61
- * @returns True if at least one of the extensions is available, false otherwise
62
- */
63
- export declare function isExtensionAvailable(editor: Editor | null, extensionNames: string | string[]): boolean;
64
- /**
65
- * Finds a node at the specified position with error handling
66
- * @param editor The Tiptap editor instance
67
- * @param position The position in the document to find the node
68
- * @returns The node at the specified position, or null if not found
69
- */
70
- export declare function findNodeAtPosition(editor: Editor, position: number): TiptapNode | null;
71
- /**
72
- * Finds the position and instance of a node in the document
73
- * @param props Object containing editor, node (optional), and nodePos (optional)
74
- * @param props.editor The Tiptap editor instance
75
- * @param props.node The node to find (optional if nodePos is provided)
76
- * @param props.nodePos The position of the node to find (optional if node is provided)
77
- * @returns An object with the position and node, or null if not found
78
- */
79
- export declare function findNodePosition(props: {
80
- editor: Editor | null;
81
- node?: TiptapNode | null;
82
- nodePos?: number | null;
83
- }): {
84
- pos: number;
85
- node: TiptapNode;
86
- } | null;
87
- /**
88
- * Checks if the current selection in the editor is a node selection of specified types
89
- * @param editor The Tiptap editor instance
90
- * @param types An array of node type names to check against
91
- * @returns boolean indicating if the selected node matches any of the specified types
92
- */
93
- export declare function isNodeTypeSelected(editor: Editor | null, types?: string[]): boolean;
94
- /**
95
- * Handles image upload with progress tracking and abort capability
96
- * @param file The file to upload
97
- * @param onProgress Optional callback for tracking upload progress
98
- * @param abortSignal Optional AbortSignal for cancelling the upload
99
- * @returns Promise resolving to the URL of the uploaded image
100
- */
101
- export declare const handleImageUpload: (file: File, onProgress?: (_event: {
102
- progress: number;
103
- }) => void, abortSignal?: AbortSignal) => Promise<string>;
104
- type ProtocolOptions = {
105
- /**
106
- * The protocol scheme to be registered.
107
- * @default '''
108
- * @example 'ftp'
109
- * @example 'git'
110
- */
111
- scheme: string;
112
- /**
113
- * If enabled, it allows optional slashes after the protocol.
114
- * @default false
115
- * @example true
116
- */
117
- optionalSlashes?: boolean;
118
- };
119
- type ProtocolConfig = Array<ProtocolOptions | string>;
120
- export declare function isAllowedUri(uri: string | undefined, protocols?: ProtocolConfig): true | RegExpMatchArray | null;
121
- export declare function sanitizeUrl(inputUrl: string, baseUrl: string, protocols?: ProtocolConfig): string;
122
- /**
123
- * Clamps selection anchor/head to valid [1, doc.nodeSize-2] range.
124
- * Returns an object compatible with TipTap's setTextSelection input.
125
- */
126
- export declare function clampSelectionPos(anchor: number, head: number, docNodeSize: number): {
127
- from: number;
128
- to: number;
129
- };
130
- export {};
@@ -1,327 +0,0 @@
1
- import { NodeSelection, Selection, TextSelection } from '@tiptap/pm/state';
2
- export const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
3
- export const MAC_SYMBOLS = {
4
- mod: '⌘',
5
- command: '⌘',
6
- meta: '⌘',
7
- ctrl: '⌃',
8
- control: '⌃',
9
- alt: '⌥',
10
- option: '⌥',
11
- shift: '⇧',
12
- backspace: 'Del',
13
- delete: '⌦',
14
- enter: '⏎',
15
- escape: '⎋',
16
- capslock: '⇪',
17
- };
18
- export function cn(...classes) {
19
- return classes.filter(Boolean).join(' ');
20
- }
21
- /**
22
- * Determines if the current platform is macOS
23
- * @returns boolean indicating if the current platform is Mac
24
- */
25
- export function isMac() {
26
- return typeof navigator !== 'undefined' && navigator.platform.toLowerCase().includes('mac');
27
- }
28
- /**
29
- * Formats a shortcut key based on the platform (Mac or non-Mac)
30
- * @param key - The key to format (e.g., "ctrl", "alt", "shift")
31
- * @param isMac - Boolean indicating if the platform is Mac
32
- * @param capitalize - Whether to capitalize the key (default: true)
33
- * @returns Formatted shortcut key symbol
34
- */
35
- export const formatShortcutKey = (key, isMac, capitalize = true) => {
36
- if (isMac) {
37
- const lowerKey = key.toLowerCase();
38
- return MAC_SYMBOLS[lowerKey] || (capitalize ? key.toUpperCase() : key);
39
- }
40
- return capitalize ? key.charAt(0).toUpperCase() + key.slice(1) : key;
41
- };
42
- /**
43
- * Parses a shortcut key string into an array of formatted key symbols
44
- * @param shortcutKeys - The string of shortcut keys (e.g., "ctrl-alt-shift")
45
- * @param delimiter - The delimiter used to split the keys (default: "-")
46
- * @param capitalize - Whether to capitalize the keys (default: true)
47
- * @returns Array of formatted shortcut key symbols
48
- */
49
- export const parseShortcutKeys = (props) => {
50
- const { shortcutKeys, delimiter = '+', capitalize = true } = props;
51
- if (!shortcutKeys)
52
- return [];
53
- return shortcutKeys
54
- .split(delimiter)
55
- .map((key) => key.trim())
56
- .map((key) => formatShortcutKey(key, isMac(), capitalize));
57
- };
58
- /**
59
- * Checks if a mark exists in the editor schema
60
- * @param markName - The name of the mark to check
61
- * @param editor - The editor instance
62
- * @returns boolean indicating if the mark exists in the schema
63
- */
64
- export const isMarkInSchema = (markName, editor) => {
65
- if (!editor?.schema)
66
- return false;
67
- return editor.schema.spec.marks.get(markName) !== undefined;
68
- };
69
- /**
70
- * Checks if a node exists in the editor schema
71
- * @param nodeName - The name of the node to check
72
- * @param editor - The editor instance
73
- * @returns boolean indicating if the node exists in the schema
74
- */
75
- export const isNodeInSchema = (nodeName, editor) => {
76
- if (!editor?.schema)
77
- return false;
78
- return editor.schema.spec.nodes.get(nodeName) !== undefined;
79
- };
80
- /**
81
- * Moves the focus to the next node in the editor
82
- * @param editor - The editor instance
83
- * @returns boolean indicating if the focus was moved
84
- */
85
- export function focusNextNode(editor) {
86
- const { state, view } = editor;
87
- const { doc, selection } = state;
88
- const nextSel = Selection.findFrom(selection.$to, 1, true);
89
- if (nextSel) {
90
- view.dispatch(state.tr.setSelection(nextSel).scrollIntoView());
91
- return true;
92
- }
93
- const paragraphType = state.schema.nodes.paragraph;
94
- if (!paragraphType) {
95
- console.warn('No paragraph node type found in schema.');
96
- return false;
97
- }
98
- const end = doc.content.size;
99
- const para = paragraphType.create();
100
- let tr = state.tr.insert(end, para);
101
- // Place the selection inside the new paragraph
102
- const $inside = tr.doc.resolve(end + 1);
103
- tr = tr.setSelection(TextSelection.near($inside)).scrollIntoView();
104
- view.dispatch(tr);
105
- return true;
106
- }
107
- /**
108
- * Checks if a value is a valid number (not null, undefined, or NaN)
109
- * @param value - The value to check
110
- * @returns boolean indicating if the value is a valid number
111
- */
112
- export function isValidPosition(pos) {
113
- return typeof pos === 'number' && pos >= 0;
114
- }
115
- /**
116
- * Checks if one or more extensions are registered in the Tiptap editor.
117
- * @param editor - The Tiptap editor instance
118
- * @param extensionNames - A single extension name or an array of names to check
119
- * @returns True if at least one of the extensions is available, false otherwise
120
- */
121
- export function isExtensionAvailable(editor, extensionNames) {
122
- if (!editor)
123
- return false;
124
- const names = Array.isArray(extensionNames) ? extensionNames : [extensionNames];
125
- const found = names.some((name) => editor.extensionManager.extensions.some((ext) => ext.name === name));
126
- if (!found) {
127
- console.warn(`None of the extensions [${names.join(', ')}] were found in the editor schema. Ensure they are included in the editor configuration.`);
128
- }
129
- return found;
130
- }
131
- /**
132
- * Finds a node at the specified position with error handling
133
- * @param editor The Tiptap editor instance
134
- * @param position The position in the document to find the node
135
- * @returns The node at the specified position, or null if not found
136
- */
137
- export function findNodeAtPosition(editor, position) {
138
- try {
139
- const node = editor.state.doc.nodeAt(position);
140
- if (!node) {
141
- console.warn(`No node found at position ${position}`);
142
- return null;
143
- }
144
- return node;
145
- }
146
- catch (error) {
147
- console.error(`Error getting node at position ${position}:`, error);
148
- return null;
149
- }
150
- }
151
- /**
152
- * Finds the position and instance of a node in the document
153
- * @param props Object containing editor, node (optional), and nodePos (optional)
154
- * @param props.editor The Tiptap editor instance
155
- * @param props.node The node to find (optional if nodePos is provided)
156
- * @param props.nodePos The position of the node to find (optional if node is provided)
157
- * @returns An object with the position and node, or null if not found
158
- */
159
- export function findNodePosition(props) {
160
- const { editor, node, nodePos } = props;
161
- if (!editor || !editor.state?.doc)
162
- return null;
163
- // Zero is valid position
164
- const hasValidNode = node !== undefined && node !== null;
165
- const hasValidPos = isValidPosition(nodePos);
166
- if (!hasValidNode && !hasValidPos) {
167
- return null;
168
- }
169
- // First search for the node in the document if we have a node
170
- if (hasValidNode) {
171
- let foundPos = -1;
172
- let foundNode = null;
173
- editor.state.doc.descendants((currentNode, pos) => {
174
- // TODO: Needed?
175
- // if (currentNode.type && currentNode.type.name === node!.type.name) {
176
- if (currentNode === node) {
177
- foundPos = pos;
178
- foundNode = currentNode;
179
- return false;
180
- }
181
- return true;
182
- });
183
- if (foundPos !== -1 && foundNode !== null) {
184
- return { pos: foundPos, node: foundNode };
185
- }
186
- }
187
- // If we have a valid position, use findNodeAtPosition
188
- if (hasValidPos) {
189
- const nodeAtPos = findNodeAtPosition(editor, nodePos);
190
- if (nodeAtPos) {
191
- return { pos: nodePos, node: nodeAtPos };
192
- }
193
- }
194
- return null;
195
- }
196
- /**
197
- * Checks if the current selection in the editor is a node selection of specified types
198
- * @param editor The Tiptap editor instance
199
- * @param types An array of node type names to check against
200
- * @returns boolean indicating if the selected node matches any of the specified types
201
- */
202
- export function isNodeTypeSelected(editor, types = []) {
203
- if (!editor || !editor.state.selection)
204
- return false;
205
- const { state } = editor;
206
- const { selection } = state;
207
- if (selection.empty)
208
- return false;
209
- if (selection instanceof NodeSelection) {
210
- const node = selection.node;
211
- return node ? types.includes(node.type.name) : false;
212
- }
213
- return false;
214
- }
215
- /**
216
- * Handles image upload with progress tracking and abort capability
217
- * @param file The file to upload
218
- * @param onProgress Optional callback for tracking upload progress
219
- * @param abortSignal Optional AbortSignal for cancelling the upload
220
- * @returns Promise resolving to the URL of the uploaded image
221
- */
222
- export const handleImageUpload = async (file, onProgress, abortSignal) => {
223
- // Validate file
224
- if (!file) {
225
- throw new Error('No file provided');
226
- }
227
- if (file.size > MAX_FILE_SIZE) {
228
- throw new Error(`File size exceeds maximum allowed (${MAX_FILE_SIZE / (1024 * 1024)}MB)`);
229
- }
230
- // Create FormData
231
- const formData = new FormData();
232
- formData.append('file', file);
233
- // Create XMLHttpRequest for progress tracking
234
- return new Promise((resolve, reject) => {
235
- const xhr = new XMLHttpRequest();
236
- // Handle progress
237
- xhr.upload.addEventListener('progress', (event) => {
238
- if (event.lengthComputable) {
239
- const progress = Math.round((event.loaded / event.total) * 100);
240
- onProgress?.({ progress });
241
- }
242
- });
243
- // Handle completion
244
- xhr.addEventListener('load', () => {
245
- if (xhr.status >= 200 && xhr.status < 300) {
246
- try {
247
- const response = JSON.parse(xhr.responseText);
248
- resolve(response.url);
249
- }
250
- catch {
251
- reject(new Error('Failed to parse upload response'));
252
- }
253
- }
254
- else {
255
- reject(new Error(`Upload failed with status ${xhr.status}`));
256
- }
257
- });
258
- // Handle errors
259
- xhr.addEventListener('error', () => {
260
- reject(new Error('Upload failed'));
261
- });
262
- // Handle abort
263
- if (abortSignal) {
264
- abortSignal.addEventListener('abort', () => {
265
- xhr.abort();
266
- reject(new Error('Upload cancelled'));
267
- });
268
- }
269
- // Send request
270
- xhr.open('POST', '/api/upload');
271
- xhr.send(formData);
272
- });
273
- };
274
- const ATTR_WHITESPACE =
275
- // eslint-disable-next-line no-control-regex
276
- /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
277
- export function isAllowedUri(uri, protocols) {
278
- const allowedProtocols = [
279
- 'http',
280
- 'https',
281
- 'ftp',
282
- 'ftps',
283
- 'mailto',
284
- 'tel',
285
- 'callto',
286
- 'sms',
287
- 'cid',
288
- 'xmpp',
289
- ];
290
- if (protocols) {
291
- protocols.forEach((protocol) => {
292
- const nextProtocol = typeof protocol === 'string' ? protocol : protocol.scheme;
293
- if (nextProtocol) {
294
- allowedProtocols.push(nextProtocol);
295
- }
296
- });
297
- }
298
- return (!uri ||
299
- uri.replace(ATTR_WHITESPACE, '').match(new RegExp(
300
- // eslint-disable-next-line no-useless-escape
301
- `^(?:(?:${allowedProtocols.join('|')}):|[^a-z]|[a-z0-9+.\-]+(?:[^a-z+.\-:]|$))`, 'i')));
302
- }
303
- export function sanitizeUrl(inputUrl, baseUrl, protocols) {
304
- try {
305
- const url = new URL(inputUrl, baseUrl);
306
- if (isAllowedUri(url.href, protocols)) {
307
- return url.href;
308
- }
309
- }
310
- catch {
311
- // If URL creation fails, it's considered invalid
312
- }
313
- return '#';
314
- }
315
- /**
316
- * Clamps selection anchor/head to valid [1, doc.nodeSize-2] range.
317
- * Returns an object compatible with TipTap's setTextSelection input.
318
- */
319
- export function clampSelectionPos(anchor, head, docNodeSize) {
320
- const maxPos = Math.max(1, docNodeSize - 2);
321
- const clamp = (pos) => Math.max(1, Math.min(pos, maxPos));
322
- const a = clamp(anchor);
323
- const h = clamp(head);
324
- const from = Math.min(a, h);
325
- const to = Math.max(a, h);
326
- return { from, to };
327
- }
@@ -1 +0,0 @@
1
- self.__BUILD_MANIFEST=function(e,r,t,_){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:4,errorRate:1e-4,numBits:77,numHashes:14,bitArray:[1,0,0,r,1,e,e,r,e,r,r,e,r,e,r,e,e,e,e,r,e,r,e,r,e,e,e,r,r,r,e,r,e,e,e,r,r,e,e,e,r,e,r,r,e,r,r,r,r,e,e,r,e,r,r,r,r,e,e,r,r,r,e,r,r,r,e,e,e,e,e,r,r,r,r,r,e]},__routerFilterDynamic:{numItems:e,errorRate:1e-4,numBits:20,numHashes:14,bitArray:[r,e,r,e,e,e,r,e,e,r,e,e,e,r,r,e,r,r,e,r]},"/_error":["static/chunks/pages/_error-75a96cf1997cc3b9.js"],sortedPages:["/_app","/_error"]}}(1,0,1e-4,14),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[298,413,772],{51680:()=>{}},_=>{_.O(0,[587,18,358],()=>_(_.s=51680)),_N_E=_.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[298,413,772],{51680:()=>{}},_=>{_.O(0,[587,18,358],()=>_(_.s=51680)),_N_E=_.O()}]);
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[298,413,772],{51680:()=>{}},_=>{_.O(0,[587,18,358],()=>_(_.s=51680)),_N_E=_.O()}]);