claudeship 0.2.11 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/apps/server/dist/app.module.js +8 -0
  2. package/apps/server/dist/app.module.js.map +1 -1
  3. package/apps/server/dist/chat/prompts/fullstack-express-prompt.d.ts +1 -1
  4. package/apps/server/dist/chat/prompts/fullstack-express-prompt.js +110 -1
  5. package/apps/server/dist/chat/prompts/fullstack-express-prompt.js.map +1 -1
  6. package/apps/server/dist/chat/prompts/fullstack-fastapi-prompt.d.ts +1 -1
  7. package/apps/server/dist/chat/prompts/fullstack-fastapi-prompt.js +110 -1
  8. package/apps/server/dist/chat/prompts/fullstack-fastapi-prompt.js.map +1 -1
  9. package/apps/server/dist/chat/prompts/web-system-prompt.d.ts +1 -1
  10. package/apps/server/dist/chat/prompts/web-system-prompt.js +157 -0
  11. package/apps/server/dist/chat/prompts/web-system-prompt.js.map +1 -1
  12. package/apps/server/dist/checkpoint/checkpoint.controller.d.ts +19 -0
  13. package/apps/server/dist/checkpoint/checkpoint.controller.js +93 -0
  14. package/apps/server/dist/checkpoint/checkpoint.controller.js.map +1 -0
  15. package/apps/server/dist/checkpoint/checkpoint.module.d.ts +2 -0
  16. package/apps/server/dist/checkpoint/checkpoint.module.js +25 -0
  17. package/apps/server/dist/checkpoint/checkpoint.module.js.map +1 -0
  18. package/apps/server/dist/checkpoint/checkpoint.service.d.ts +41 -0
  19. package/apps/server/dist/checkpoint/checkpoint.service.js +261 -0
  20. package/apps/server/dist/checkpoint/checkpoint.service.js.map +1 -0
  21. package/apps/server/dist/database/database.controller.d.ts +23 -0
  22. package/apps/server/dist/database/database.controller.js +109 -0
  23. package/apps/server/dist/database/database.controller.js.map +1 -0
  24. package/apps/server/dist/database/database.module.d.ts +2 -0
  25. package/apps/server/dist/database/database.module.js +25 -0
  26. package/apps/server/dist/database/database.module.js.map +1 -0
  27. package/apps/server/dist/database/database.service.d.ts +32 -0
  28. package/apps/server/dist/database/database.service.js +238 -0
  29. package/apps/server/dist/database/database.service.js.map +1 -0
  30. package/apps/server/dist/preview/preview.controller.d.ts +5 -0
  31. package/apps/server/dist/preview/preview.controller.js +41 -0
  32. package/apps/server/dist/preview/preview.controller.js.map +1 -1
  33. package/apps/server/dist/preview/preview.service.d.ts +20 -0
  34. package/apps/server/dist/preview/preview.service.js +51 -2
  35. package/apps/server/dist/preview/preview.service.js.map +1 -1
  36. package/apps/server/dist/project/project.controller.d.ts +10 -1
  37. package/apps/server/dist/project/project.controller.js +57 -0
  38. package/apps/server/dist/project/project.controller.js.map +1 -1
  39. package/apps/server/dist/project/project.service.d.ts +15 -0
  40. package/apps/server/dist/project/project.service.js +111 -0
  41. package/apps/server/dist/project/project.service.js.map +1 -1
  42. package/apps/server/dist/project-context/project-context.controller.d.ts +42 -0
  43. package/apps/server/dist/project-context/project-context.controller.js +127 -0
  44. package/apps/server/dist/project-context/project-context.controller.js.map +1 -0
  45. package/apps/server/dist/project-context/project-context.module.d.ts +2 -0
  46. package/apps/server/dist/project-context/project-context.module.js +25 -0
  47. package/apps/server/dist/project-context/project-context.module.js.map +1 -0
  48. package/apps/server/dist/project-context/project-context.service.d.ts +36 -0
  49. package/apps/server/dist/project-context/project-context.service.js +260 -0
  50. package/apps/server/dist/project-context/project-context.service.js.map +1 -0
  51. package/apps/server/dist/testing/testing.controller.d.ts +24 -0
  52. package/apps/server/dist/testing/testing.controller.js +126 -0
  53. package/apps/server/dist/testing/testing.controller.js.map +1 -0
  54. package/apps/server/dist/testing/testing.module.d.ts +2 -0
  55. package/apps/server/dist/testing/testing.module.js +26 -0
  56. package/apps/server/dist/testing/testing.module.js.map +1 -0
  57. package/apps/server/dist/testing/testing.service.d.ts +62 -0
  58. package/apps/server/dist/testing/testing.service.js +269 -0
  59. package/apps/server/dist/testing/testing.service.js.map +1 -0
  60. package/apps/server/dist/tsconfig.tsbuildinfo +1 -1
  61. package/apps/server/package.json +1 -1
  62. package/apps/web/.next/BUILD_ID +1 -1
  63. package/apps/web/.next/app-build-manifest.json +7 -7
  64. package/apps/web/.next/app-path-routes-manifest.json +2 -2
  65. package/apps/web/.next/build-manifest.json +2 -2
  66. package/apps/web/.next/cache/.previewinfo +1 -1
  67. package/apps/web/.next/cache/.rscinfo +1 -1
  68. package/apps/web/.next/cache/.tsbuildinfo +1 -1
  69. package/apps/web/.next/cache/config.json +3 -3
  70. package/apps/web/.next/cache/eslint/.cache_j3uhuz +1 -1
  71. package/apps/web/.next/cache/webpack/client-production/0.pack +0 -0
  72. package/apps/web/.next/cache/webpack/client-production/index.pack +0 -0
  73. package/apps/web/.next/cache/webpack/edge-server-production/index.pack +0 -0
  74. package/apps/web/.next/cache/webpack/server-production/0.pack +0 -0
  75. package/apps/web/.next/cache/webpack/server-production/index.pack +0 -0
  76. package/apps/web/.next/prerender-manifest.json +13 -13
  77. package/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  78. package/apps/web/.next/server/app/_not-found.html +1 -1
  79. package/apps/web/.next/server/app/_not-found.rsc +2 -2
  80. package/apps/web/.next/server/app/index.html +1 -1
  81. package/apps/web/.next/server/app/index.rsc +3 -3
  82. package/apps/web/.next/server/app/page.js +2 -2
  83. package/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  84. package/apps/web/.next/server/app/project/[id]/page.js +2 -2
  85. package/apps/web/.next/server/app/project/[id]/page_client-reference-manifest.js +1 -1
  86. package/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  87. package/apps/web/.next/server/app/settings.html +1 -1
  88. package/apps/web/.next/server/app/settings.rsc +3 -3
  89. package/apps/web/.next/server/app-paths-manifest.json +2 -2
  90. package/apps/web/.next/server/chunks/392.js +1 -1
  91. package/apps/web/.next/server/pages/404.html +1 -1
  92. package/apps/web/.next/server/pages/500.html +1 -1
  93. package/apps/web/.next/server/server-reference-manifest.json +1 -1
  94. package/apps/web/.next/static/chunks/712-11fca77fb30a2a06.js +1 -0
  95. package/apps/web/.next/static/chunks/app/page-0db1c152fbd48359.js +1 -0
  96. package/apps/web/.next/static/chunks/app/project/[id]/page-7c44ae18c8984726.js +1 -0
  97. package/apps/web/.next/static/chunks/app/settings/page-d1318c2fd58729a5.js +1 -0
  98. package/apps/web/.next/static/css/d0f1b036f222bc16.css +3 -0
  99. package/apps/web/.next/trace +18 -17
  100. package/apps/web/node_modules/.bin/eslint +2 -2
  101. package/apps/web/package.json +2 -1
  102. package/apps/web/src/components/checkpoint/CheckpointPanel.tsx +384 -0
  103. package/apps/web/src/components/database/DatabasePanel.tsx +405 -0
  104. package/apps/web/src/components/env/EnvPanel.tsx +356 -0
  105. package/apps/web/src/components/preview/ConsoleViewer.tsx +270 -0
  106. package/apps/web/src/components/preview/ErrorOverlay.tsx +189 -0
  107. package/apps/web/src/components/preview/PreviewPanel.tsx +148 -6
  108. package/apps/web/src/components/testing/TestRunner.tsx +481 -0
  109. package/apps/web/src/components/ui/tabs.tsx +55 -0
  110. package/apps/web/src/components/visual-editor/VisualEditor.tsx +382 -0
  111. package/apps/web/src/lib/api.ts +5 -2
  112. package/package.json +1 -1
  113. package/apps/web/.next/static/chunks/298-6f3d6b321c288cd3.js +0 -1
  114. package/apps/web/.next/static/chunks/app/page-3d093f7f480a8599.js +0 -1
  115. package/apps/web/.next/static/chunks/app/project/[id]/page-e5cda6f9050b0a52.js +0 -1
  116. package/apps/web/.next/static/chunks/app/settings/page-92d28565c3d8c755.js +0 -1
  117. package/apps/web/.next/static/css/8f946046a2047594.css +0 -3
  118. /package/apps/web/.next/static/{zw4FcukMOho6_dzgpEdNW → tV_Qc76rupeogXvWEMw6p}/_buildManifest.js +0 -0
  119. /package/apps/web/.next/static/{zw4FcukMOho6_dzgpEdNW → tV_Qc76rupeogXvWEMw6p}/_ssgManifest.js +0 -0
@@ -0,0 +1,382 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState, useRef, useCallback } from "react";
4
+ import {
5
+ MousePointer2,
6
+ Move,
7
+ Maximize2,
8
+ Type,
9
+ Palette,
10
+ Box,
11
+ X,
12
+ RefreshCw,
13
+ } from "lucide-react";
14
+ import { Button } from "@/components/ui/button";
15
+ import { Input } from "@/components/ui/input";
16
+
17
+ interface SelectedElement {
18
+ selector: string;
19
+ tagName: string;
20
+ className: string;
21
+ id: string;
22
+ styles: Record<string, string>;
23
+ rect: DOMRect;
24
+ }
25
+
26
+ interface VisualEditorProps {
27
+ projectId: string;
28
+ previewUrl: string;
29
+ }
30
+
31
+ const STYLE_CATEGORIES = {
32
+ layout: ["display", "position", "width", "height", "margin", "padding"],
33
+ typography: ["font-size", "font-weight", "color", "text-align", "line-height"],
34
+ background: ["background-color", "background-image", "opacity"],
35
+ border: ["border", "border-radius", "box-shadow"],
36
+ };
37
+
38
+ export function VisualEditor({ projectId, previewUrl }: VisualEditorProps) {
39
+ const iframeRef = useRef<HTMLIFrameElement>(null);
40
+ const [isEnabled, setIsEnabled] = useState(false);
41
+ const [selectedElement, setSelectedElement] = useState<SelectedElement | null>(null);
42
+ const [hoveredRect, setHoveredRect] = useState<DOMRect | null>(null);
43
+ const [editedStyles, setEditedStyles] = useState<Record<string, string>>({});
44
+
45
+ // Inject editor script into iframe
46
+ const injectEditorScript = useCallback(() => {
47
+ const iframe = iframeRef.current;
48
+ if (!iframe?.contentWindow) return;
49
+
50
+ const script = `
51
+ (function() {
52
+ if (window.__visualEditorInjected) return;
53
+ window.__visualEditorInjected = true;
54
+
55
+ let hoveredElement = null;
56
+ let selectedElement = null;
57
+ const overlay = document.createElement('div');
58
+ overlay.id = '__visual-editor-overlay';
59
+ overlay.style.cssText = 'position:fixed;pointer-events:none;z-index:99999;border:2px solid #3b82f6;background:rgba(59,130,246,0.1);transition:all 0.1s;display:none;';
60
+ document.body.appendChild(overlay);
61
+
62
+ const selectionOverlay = document.createElement('div');
63
+ selectionOverlay.id = '__visual-editor-selection';
64
+ selectionOverlay.style.cssText = 'position:fixed;pointer-events:none;z-index:99998;border:2px solid #10b981;background:rgba(16,185,129,0.1);display:none;';
65
+ document.body.appendChild(selectionOverlay);
66
+
67
+ function getSelector(el) {
68
+ if (el.id) return '#' + el.id;
69
+ if (el.className && typeof el.className === 'string') {
70
+ const classes = el.className.split(' ').filter(c => c && !c.startsWith('__'));
71
+ if (classes.length) return el.tagName.toLowerCase() + '.' + classes.join('.');
72
+ }
73
+ return el.tagName.toLowerCase();
74
+ }
75
+
76
+ function getStyles(el) {
77
+ const computed = window.getComputedStyle(el);
78
+ return {
79
+ 'display': computed.display,
80
+ 'position': computed.position,
81
+ 'width': computed.width,
82
+ 'height': computed.height,
83
+ 'margin': computed.margin,
84
+ 'padding': computed.padding,
85
+ 'font-size': computed.fontSize,
86
+ 'font-weight': computed.fontWeight,
87
+ 'color': computed.color,
88
+ 'text-align': computed.textAlign,
89
+ 'line-height': computed.lineHeight,
90
+ 'background-color': computed.backgroundColor,
91
+ 'border': computed.border,
92
+ 'border-radius': computed.borderRadius,
93
+ 'box-shadow': computed.boxShadow,
94
+ 'opacity': computed.opacity,
95
+ };
96
+ }
97
+
98
+ document.addEventListener('mousemove', function(e) {
99
+ if (!window.__visualEditorEnabled) return;
100
+
101
+ const el = document.elementFromPoint(e.clientX, e.clientY);
102
+ if (!el || el === overlay || el === selectionOverlay) return;
103
+ if (el === hoveredElement) return;
104
+
105
+ hoveredElement = el;
106
+ const rect = el.getBoundingClientRect();
107
+ overlay.style.display = 'block';
108
+ overlay.style.left = rect.left + 'px';
109
+ overlay.style.top = rect.top + 'px';
110
+ overlay.style.width = rect.width + 'px';
111
+ overlay.style.height = rect.height + 'px';
112
+
113
+ window.parent.postMessage({
114
+ type: 'visualEditor:hover',
115
+ rect: { left: rect.left, top: rect.top, width: rect.width, height: rect.height }
116
+ }, '*');
117
+ });
118
+
119
+ document.addEventListener('click', function(e) {
120
+ if (!window.__visualEditorEnabled) return;
121
+ e.preventDefault();
122
+ e.stopPropagation();
123
+
124
+ const el = document.elementFromPoint(e.clientX, e.clientY);
125
+ if (!el || el === overlay || el === selectionOverlay) return;
126
+
127
+ selectedElement = el;
128
+ const rect = el.getBoundingClientRect();
129
+ selectionOverlay.style.display = 'block';
130
+ selectionOverlay.style.left = rect.left + 'px';
131
+ selectionOverlay.style.top = rect.top + 'px';
132
+ selectionOverlay.style.width = rect.width + 'px';
133
+ selectionOverlay.style.height = rect.height + 'px';
134
+
135
+ window.parent.postMessage({
136
+ type: 'visualEditor:select',
137
+ element: {
138
+ selector: getSelector(el),
139
+ tagName: el.tagName.toLowerCase(),
140
+ className: el.className || '',
141
+ id: el.id || '',
142
+ styles: getStyles(el),
143
+ rect: { left: rect.left, top: rect.top, width: rect.width, height: rect.height }
144
+ }
145
+ }, '*');
146
+ }, true);
147
+
148
+ window.addEventListener('message', function(e) {
149
+ if (e.data.type === 'visualEditor:enable') {
150
+ window.__visualEditorEnabled = true;
151
+ document.body.style.cursor = 'crosshair';
152
+ } else if (e.data.type === 'visualEditor:disable') {
153
+ window.__visualEditorEnabled = false;
154
+ document.body.style.cursor = '';
155
+ overlay.style.display = 'none';
156
+ selectionOverlay.style.display = 'none';
157
+ } else if (e.data.type === 'visualEditor:updateStyle' && selectedElement) {
158
+ selectedElement.style[e.data.property] = e.data.value;
159
+ }
160
+ });
161
+ })();
162
+ `;
163
+
164
+ try {
165
+ const doc = iframe.contentDocument;
166
+ if (doc) {
167
+ // Remove existing script if any
168
+ const existing = doc.getElementById("__visual-editor-script");
169
+ if (existing) existing.remove();
170
+
171
+ const scriptEl = doc.createElement("script");
172
+ scriptEl.id = "__visual-editor-script";
173
+ scriptEl.textContent = script;
174
+ doc.body.appendChild(scriptEl);
175
+ }
176
+ } catch {
177
+ // Cross-origin - can't inject script
178
+ console.warn("Visual editor: Cannot inject script (cross-origin)");
179
+ }
180
+ }, []);
181
+
182
+ // Handle messages from iframe
183
+ useEffect(() => {
184
+ const handleMessage = (e: MessageEvent) => {
185
+ if (e.data.type === "visualEditor:hover") {
186
+ setHoveredRect(e.data.rect);
187
+ } else if (e.data.type === "visualEditor:select") {
188
+ setSelectedElement(e.data.element);
189
+ setEditedStyles(e.data.element.styles);
190
+ }
191
+ };
192
+
193
+ window.addEventListener("message", handleMessage);
194
+ return () => window.removeEventListener("message", handleMessage);
195
+ }, []);
196
+
197
+ // Toggle editor mode
198
+ const toggleEditor = useCallback(() => {
199
+ const iframe = iframeRef.current;
200
+ if (!iframe?.contentWindow) return;
201
+
202
+ if (!isEnabled) {
203
+ injectEditorScript();
204
+ iframe.contentWindow.postMessage({ type: "visualEditor:enable" }, "*");
205
+ } else {
206
+ iframe.contentWindow.postMessage({ type: "visualEditor:disable" }, "*");
207
+ setSelectedElement(null);
208
+ setHoveredRect(null);
209
+ }
210
+ setIsEnabled(!isEnabled);
211
+ }, [isEnabled, injectEditorScript]);
212
+
213
+ // Update style
214
+ const updateStyle = (property: string, value: string) => {
215
+ const iframe = iframeRef.current;
216
+ if (!iframe?.contentWindow || !selectedElement) return;
217
+
218
+ setEditedStyles((prev) => ({ ...prev, [property]: value }));
219
+ iframe.contentWindow.postMessage(
220
+ { type: "visualEditor:updateStyle", property, value },
221
+ "*"
222
+ );
223
+ };
224
+
225
+ // Generate Tailwind classes (simplified)
226
+ const generateTailwindClass = (property: string, value: string): string => {
227
+ // This is a simplified version - full implementation would need more mappings
228
+ const mappings: Record<string, Record<string, string>> = {
229
+ display: { flex: "flex", grid: "grid", block: "block", none: "hidden" },
230
+ "text-align": { center: "text-center", left: "text-left", right: "text-right" },
231
+ "font-weight": { "700": "font-bold", "600": "font-semibold", "400": "font-normal" },
232
+ };
233
+
234
+ return mappings[property]?.[value] || "";
235
+ };
236
+
237
+ return (
238
+ <div className="flex h-full flex-col">
239
+ {/* Header */}
240
+ <div className="flex items-center justify-between border-b px-4 py-3">
241
+ <h3 className="font-medium flex items-center gap-2">
242
+ <MousePointer2 className="h-4 w-4" />
243
+ Visual Editor
244
+ </h3>
245
+ <Button
246
+ variant={isEnabled ? "secondary" : "outline"}
247
+ size="sm"
248
+ onClick={toggleEditor}
249
+ >
250
+ {isEnabled ? "Disable" : "Enable"} Inspector
251
+ </Button>
252
+ </div>
253
+
254
+ <div className="flex flex-1 overflow-hidden">
255
+ {/* Preview */}
256
+ <div className="flex-1 bg-muted/30 relative">
257
+ <iframe
258
+ ref={iframeRef}
259
+ src={previewUrl}
260
+ className="w-full h-full border-0"
261
+ onLoad={injectEditorScript}
262
+ />
263
+ {isEnabled && (
264
+ <div className="absolute top-2 left-2 px-2 py-1 bg-blue-500 text-white text-xs rounded">
265
+ Inspector Mode
266
+ </div>
267
+ )}
268
+ </div>
269
+
270
+ {/* Style Panel */}
271
+ {selectedElement && (
272
+ <div className="w-72 border-l overflow-auto">
273
+ <div className="p-4 space-y-4">
274
+ {/* Element Info */}
275
+ <div className="space-y-2">
276
+ <div className="flex items-center justify-between">
277
+ <span className="text-sm font-medium">Selected Element</span>
278
+ <Button
279
+ variant="ghost"
280
+ size="sm"
281
+ onClick={() => setSelectedElement(null)}
282
+ className="h-6 w-6 p-0"
283
+ >
284
+ <X className="h-4 w-4" />
285
+ </Button>
286
+ </div>
287
+ <code className="block text-xs bg-muted p-2 rounded">
288
+ {selectedElement.selector}
289
+ </code>
290
+ </div>
291
+
292
+ {/* Layout */}
293
+ <div className="space-y-2">
294
+ <div className="flex items-center gap-2 text-sm font-medium">
295
+ <Box className="h-4 w-4" />
296
+ Layout
297
+ </div>
298
+ {STYLE_CATEGORIES.layout.map((prop) => (
299
+ <div key={prop} className="flex items-center gap-2">
300
+ <label className="text-xs text-muted-foreground w-20 shrink-0">
301
+ {prop}
302
+ </label>
303
+ <Input
304
+ value={editedStyles[prop] || ""}
305
+ onChange={(e) => updateStyle(prop, e.target.value)}
306
+ className="h-7 text-xs font-mono"
307
+ />
308
+ </div>
309
+ ))}
310
+ </div>
311
+
312
+ {/* Typography */}
313
+ <div className="space-y-2">
314
+ <div className="flex items-center gap-2 text-sm font-medium">
315
+ <Type className="h-4 w-4" />
316
+ Typography
317
+ </div>
318
+ {STYLE_CATEGORIES.typography.map((prop) => (
319
+ <div key={prop} className="flex items-center gap-2">
320
+ <label className="text-xs text-muted-foreground w-20 shrink-0">
321
+ {prop}
322
+ </label>
323
+ <Input
324
+ value={editedStyles[prop] || ""}
325
+ onChange={(e) => updateStyle(prop, e.target.value)}
326
+ className="h-7 text-xs font-mono"
327
+ />
328
+ </div>
329
+ ))}
330
+ </div>
331
+
332
+ {/* Background */}
333
+ <div className="space-y-2">
334
+ <div className="flex items-center gap-2 text-sm font-medium">
335
+ <Palette className="h-4 w-4" />
336
+ Background
337
+ </div>
338
+ {STYLE_CATEGORIES.background.map((prop) => (
339
+ <div key={prop} className="flex items-center gap-2">
340
+ <label className="text-xs text-muted-foreground w-20 shrink-0">
341
+ {prop}
342
+ </label>
343
+ <Input
344
+ value={editedStyles[prop] || ""}
345
+ onChange={(e) => updateStyle(prop, e.target.value)}
346
+ className="h-7 text-xs font-mono"
347
+ />
348
+ </div>
349
+ ))}
350
+ </div>
351
+
352
+ {/* Border */}
353
+ <div className="space-y-2">
354
+ <div className="flex items-center gap-2 text-sm font-medium">
355
+ <Maximize2 className="h-4 w-4" />
356
+ Border
357
+ </div>
358
+ {STYLE_CATEGORIES.border.map((prop) => (
359
+ <div key={prop} className="flex items-center gap-2">
360
+ <label className="text-xs text-muted-foreground w-20 shrink-0">
361
+ {prop}
362
+ </label>
363
+ <Input
364
+ value={editedStyles[prop] || ""}
365
+ onChange={(e) => updateStyle(prop, e.target.value)}
366
+ className="h-7 text-xs font-mono"
367
+ />
368
+ </div>
369
+ ))}
370
+ </div>
371
+
372
+ {/* Note */}
373
+ <p className="text-xs text-muted-foreground mt-4">
374
+ Changes are preview only. Use the AI to update source code.
375
+ </p>
376
+ </div>
377
+ </div>
378
+ )}
379
+ </div>
380
+ </div>
381
+ );
382
+ }
@@ -46,8 +46,11 @@ export const api = {
46
46
  method: "PUT",
47
47
  body: data ? JSON.stringify(data) : undefined,
48
48
  }),
49
- delete: <T>(endpoint: string) =>
50
- request<T>(endpoint, { method: "DELETE" }),
49
+ delete: <T>(endpoint: string, data?: unknown) =>
50
+ request<T>(endpoint, {
51
+ method: "DELETE",
52
+ body: data ? JSON.stringify(data) : undefined,
53
+ }),
51
54
 
52
55
  uploadFiles: async (
53
56
  projectId: string,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudeship",
3
- "version": "0.2.11",
3
+ "version": "0.2.14",
4
4
  "description": "AI-Powered App Builder using Claude Code CLI",
5
5
  "bin": {
6
6
  "claudeship": "./bin/claudeship.js"