deckide 3.0.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 (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +192 -0
  3. package/apps/server/dist/config.js +77 -0
  4. package/apps/server/dist/index.js +5 -0
  5. package/apps/server/dist/middleware/auth.js +78 -0
  6. package/apps/server/dist/middleware/cors.js +26 -0
  7. package/apps/server/dist/middleware/security.js +16 -0
  8. package/apps/server/dist/pty-client.js +177 -0
  9. package/apps/server/dist/pty-daemon.js +246 -0
  10. package/apps/server/dist/routes/decks.js +95 -0
  11. package/apps/server/dist/routes/files.js +221 -0
  12. package/apps/server/dist/routes/git.js +775 -0
  13. package/apps/server/dist/routes/settings.js +95 -0
  14. package/apps/server/dist/routes/terminals.js +239 -0
  15. package/apps/server/dist/routes/workspaces.js +83 -0
  16. package/apps/server/dist/server.js +257 -0
  17. package/apps/server/dist/types.js +1 -0
  18. package/apps/server/dist/utils/database.js +136 -0
  19. package/apps/server/dist/utils/error.js +28 -0
  20. package/apps/server/dist/utils/path.js +98 -0
  21. package/apps/server/dist/utils/shell.js +4 -0
  22. package/apps/server/dist/websocket.js +207 -0
  23. package/apps/server/package.json +26 -0
  24. package/apps/web/dist/assets/index-C-usl0y0.css +32 -0
  25. package/apps/web/dist/assets/index-CibzlLP5.js +129 -0
  26. package/apps/web/dist/index.html +13 -0
  27. package/bin/deckide.js +79 -0
  28. package/package.json +77 -0
  29. package/packages/shared/dist/types.d.ts +124 -0
  30. package/packages/shared/dist/types.d.ts.map +1 -0
  31. package/packages/shared/dist/types.js +3 -0
  32. package/packages/shared/dist/types.js.map +1 -0
  33. package/packages/shared/dist/utils-node.d.ts +22 -0
  34. package/packages/shared/dist/utils-node.d.ts.map +1 -0
  35. package/packages/shared/dist/utils-node.js +35 -0
  36. package/packages/shared/dist/utils-node.js.map +1 -0
  37. package/packages/shared/dist/utils.d.ts +90 -0
  38. package/packages/shared/dist/utils.d.ts.map +1 -0
  39. package/packages/shared/dist/utils.js +186 -0
  40. package/packages/shared/dist/utils.js.map +1 -0
  41. package/packages/shared/package.json +16 -0
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <title>Deck IDE</title>
7
+ <script type="module" crossorigin src="/assets/index-CibzlLP5.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-C-usl0y0.css">
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ </body>
13
+ </html>
package/bin/deckide.js ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { fileURLToPath } from 'node:url';
4
+ import path from 'node:path';
5
+ import os from 'node:os';
6
+ import { execSync } from 'node:child_process';
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+
10
+ // Parse CLI arguments
11
+ const args = process.argv.slice(2);
12
+ const options = {
13
+ port: 8787,
14
+ host: '0.0.0.0',
15
+ open: true,
16
+ };
17
+
18
+ for (let i = 0; i < args.length; i++) {
19
+ const arg = args[i];
20
+ if ((arg === '--port' || arg === '-p') && args[i + 1]) {
21
+ options.port = parseInt(args[i + 1], 10);
22
+ i++;
23
+ } else if (arg === '--host' && args[i + 1]) {
24
+ options.host = args[i + 1];
25
+ i++;
26
+ } else if (arg === '--no-open') {
27
+ options.open = false;
28
+ } else if (arg === '--help' || arg === '-h') {
29
+ console.log(`
30
+ Deck IDE - Browser-based IDE
31
+
32
+ Usage:
33
+ deckide [options]
34
+
35
+ Options:
36
+ -p, --port <port> Port to listen on (default: 8787)
37
+ --host <host> Host to bind to (default: 0.0.0.0)
38
+ --no-open Don't open browser automatically
39
+ -h, --help Show this help message
40
+ -v, --version Show version
41
+ `);
42
+ process.exit(0);
43
+ } else if (arg === '--version' || arg === '-v') {
44
+ const pkg = await import(path.join(__dirname, '..', 'package.json'), { with: { type: 'json' } });
45
+ console.log(pkg.default.version);
46
+ process.exit(0);
47
+ }
48
+ }
49
+
50
+ // Set data directory to ~/.deckide/
51
+ const dataDir = path.join(os.homedir(), '.deckide');
52
+ process.env.DECKIDE_DATA_DIR = dataDir;
53
+ process.env.PORT = String(options.port);
54
+ process.env.HOST = options.host;
55
+
56
+ // Import and start the server
57
+ const serverPath = path.join(__dirname, '..', 'apps', 'server', 'dist', 'index.js');
58
+ const { createServer } = await import(path.join(__dirname, '..', 'apps', 'server', 'dist', 'server.js'));
59
+
60
+ const server = await createServer();
61
+
62
+ // Open browser after server starts
63
+ if (options.open) {
64
+ const url = `http://localhost:${options.port}`;
65
+ setTimeout(() => {
66
+ try {
67
+ const platform = process.platform;
68
+ if (platform === 'darwin') {
69
+ execSync(`open ${url}`);
70
+ } else if (platform === 'win32') {
71
+ execSync(`start ${url}`);
72
+ } else {
73
+ execSync(`xdg-open ${url}`);
74
+ }
75
+ } catch {
76
+ // Silently fail if browser can't be opened
77
+ }
78
+ }, 500);
79
+ }
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "deckide",
3
+ "version": "3.0.0",
4
+ "description": "Deck IDE - Browser-based IDE with terminal, file explorer, and git integration",
5
+ "type": "module",
6
+ "bin": {
7
+ "deckide": "bin/deckide.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "apps/server/dist/",
12
+ "apps/server/package.json",
13
+ "apps/web/dist/",
14
+ "packages/shared/dist/",
15
+ "packages/shared/package.json"
16
+ ],
17
+ "workspaces": [
18
+ "apps/server",
19
+ "apps/web",
20
+ "packages/*"
21
+ ],
22
+ "scripts": {
23
+ "dev:web": "npm --workspace apps/web run dev",
24
+ "dev:server": "npm --workspace apps/server run dev",
25
+ "build:shared": "npm --workspace @deck-ide/shared run build",
26
+ "build:server": "npm --workspace apps/server run build",
27
+ "build:web": "npm --workspace apps/web run build",
28
+ "build": "npm run build:shared && npm run build:web && npm run build:server",
29
+ "serve": "npm run build && npm --workspace apps/server run serve",
30
+ "prepublishOnly": "npm run build"
31
+ },
32
+ "dependencies": {
33
+ "@deck-ide/shared": "file:packages/shared",
34
+ "@hono/node-server": "^1.12.2",
35
+ "hono": "^4.5.10",
36
+ "node-pty": "^1.0.0",
37
+ "simple-git": "^3.27.0",
38
+ "ws": "^8.17.0",
39
+ "zod": "^4.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "@monaco-editor/react": "^4.6.0",
43
+ "@tailwindcss/vite": "^4.2.1",
44
+ "@types/node": "^24.10.9",
45
+ "@types/react": "^18.3.12",
46
+ "@types/react-dom": "^18.3.1",
47
+ "@vitejs/plugin-react": "^4.2.1",
48
+ "clsx": "^2.1.1",
49
+ "react": "^18.3.1",
50
+ "react-dom": "^18.3.1",
51
+ "tailwindcss": "^4.2.1",
52
+ "tsx": "^4.19.2",
53
+ "typescript": "^5.6.3",
54
+ "vite": "^5.2.0",
55
+ "xterm": "^5.3.0",
56
+ "xterm-addon-fit": "^0.8.0",
57
+ "xterm-addon-unicode11": "^0.6.0",
58
+ "xterm-addon-web-links": "^0.9.0",
59
+ "xterm-addon-webgl": "^0.16.0"
60
+ },
61
+ "engines": {
62
+ "node": ">=20"
63
+ },
64
+ "repository": {
65
+ "type": "git",
66
+ "url": "https://github.com/tako0614/ide.git"
67
+ },
68
+ "keywords": [
69
+ "ide",
70
+ "editor",
71
+ "terminal",
72
+ "web-ide",
73
+ "developer-tools"
74
+ ],
75
+ "author": "tako0614",
76
+ "license": "MIT"
77
+ }
@@ -0,0 +1,124 @@
1
+ export type FileEntryType = 'file' | 'dir';
2
+ export interface Workspace {
3
+ id: string;
4
+ name: string;
5
+ path: string;
6
+ createdAt: string;
7
+ }
8
+ export interface Deck {
9
+ id: string;
10
+ name: string;
11
+ root: string;
12
+ workspaceId: string;
13
+ createdAt: string;
14
+ }
15
+ export interface FileSystemEntry {
16
+ name: string;
17
+ path: string;
18
+ type: FileEntryType;
19
+ }
20
+ export interface FileTreeNode extends FileSystemEntry {
21
+ expanded: boolean;
22
+ loading: boolean;
23
+ children?: FileTreeNode[];
24
+ }
25
+ export interface EditorFile {
26
+ id: string;
27
+ name: string;
28
+ path: string;
29
+ language: string;
30
+ contents: string;
31
+ dirty: boolean;
32
+ }
33
+ export interface TerminalSession {
34
+ id: string;
35
+ title: string;
36
+ createdAt?: string;
37
+ }
38
+ export interface WorkspaceState {
39
+ files: EditorFile[];
40
+ activeFileId: string | null;
41
+ tree: FileTreeNode[];
42
+ treeLoading: boolean;
43
+ treeError: string | null;
44
+ }
45
+ export interface DeckState {
46
+ terminals: TerminalSession[];
47
+ }
48
+ export interface ApiError {
49
+ error: string;
50
+ }
51
+ export interface ApiConfig {
52
+ defaultRoot: string;
53
+ }
54
+ export interface ApiFileResponse {
55
+ path: string;
56
+ contents: string;
57
+ }
58
+ export interface ApiFileSaveResponse {
59
+ path: string;
60
+ saved: boolean;
61
+ }
62
+ export interface ApiTerminalCreateResponse {
63
+ id: string;
64
+ title: string;
65
+ }
66
+ export interface CreateWorkspaceRequest {
67
+ path: string;
68
+ name?: string;
69
+ }
70
+ export interface CreateDeckRequest {
71
+ name?: string;
72
+ workspaceId: string;
73
+ }
74
+ export interface CreateTerminalRequest {
75
+ deckId: string;
76
+ title?: string;
77
+ }
78
+ export interface SaveFileRequest {
79
+ workspaceId: string;
80
+ path: string;
81
+ contents: string;
82
+ }
83
+ export interface GetFileRequest {
84
+ workspaceId: string;
85
+ path: string;
86
+ }
87
+ export interface GetFilesRequest {
88
+ workspaceId: string;
89
+ path?: string;
90
+ }
91
+ export interface GetPreviewRequest {
92
+ path: string;
93
+ subpath?: string;
94
+ }
95
+ export type GitFileStatusCode = 'modified' | 'staged' | 'untracked' | 'deleted' | 'renamed' | 'conflicted';
96
+ export interface GitFileStatus {
97
+ path: string;
98
+ status: GitFileStatusCode;
99
+ staged: boolean;
100
+ }
101
+ export interface GitStatus {
102
+ isGitRepo: boolean;
103
+ branch: string;
104
+ files: GitFileStatus[];
105
+ }
106
+ export interface GitDiff {
107
+ original: string;
108
+ modified: string;
109
+ path: string;
110
+ }
111
+ export interface GitRepoInfo {
112
+ path: string;
113
+ name: string;
114
+ branch: string;
115
+ fileCount: number;
116
+ }
117
+ export interface GitFileStatusWithRepo extends GitFileStatus {
118
+ repoPath: string;
119
+ }
120
+ export interface MultiRepoGitStatus {
121
+ repos: GitRepoInfo[];
122
+ files: GitFileStatusWithRepo[];
123
+ }
124
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ // Core domain types shared across the entire application
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA,yDAAyD"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Normalize a workspace path to an absolute path (Node.js version)
3
+ * @param inputPath - Input path (can be relative or absolute)
4
+ * @param defaultPath - Default path to use if inputPath is empty
5
+ * @returns Normalized absolute path
6
+ */
7
+ export declare function normalizeWorkspacePath(inputPath: string, defaultPath: string): string;
8
+ /**
9
+ * Get a workspace key for indexing (handles case-insensitivity on Windows)
10
+ * @param workspacePath - Workspace path
11
+ * @returns Normalized key for indexing
12
+ */
13
+ export declare function getWorkspaceKey(workspacePath: string): string;
14
+ /**
15
+ * Extract a workspace name from its path
16
+ * @param workspacePath - Workspace path
17
+ * @param fallbackIndex - Index to use for fallback name
18
+ * @returns Workspace name
19
+ */
20
+ export declare function getWorkspaceName(workspacePath: string, fallbackIndex: number): string;
21
+ export { getFileExtension, getLanguageFromPath, normalizePathSeparators, isHidden, getErrorMessage, createHttpError, truncate, shortId, formatFileSize, sortFileEntries } from './utils.js';
22
+ //# sourceMappingURL=utils-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-node.d.ts","sourceRoot":"","sources":["../utils-node.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAErF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAIrF;AAGD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,QAAQ,EACR,eAAe,EACf,eAAe,EACf,QAAQ,EACR,OAAO,EACP,cAAc,EACd,eAAe,EAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,35 @@
1
+ // Node.js-specific utility functions
2
+ // This file should only be imported in Node.js environments (server)
3
+ import path from 'node:path';
4
+ /**
5
+ * Normalize a workspace path to an absolute path (Node.js version)
6
+ * @param inputPath - Input path (can be relative or absolute)
7
+ * @param defaultPath - Default path to use if inputPath is empty
8
+ * @returns Normalized absolute path
9
+ */
10
+ export function normalizeWorkspacePath(inputPath, defaultPath) {
11
+ return path.resolve(inputPath || defaultPath);
12
+ }
13
+ /**
14
+ * Get a workspace key for indexing (handles case-insensitivity on Windows)
15
+ * @param workspacePath - Workspace path
16
+ * @returns Normalized key for indexing
17
+ */
18
+ export function getWorkspaceKey(workspacePath) {
19
+ const normalized = workspacePath.replace(/[\\/]+$/, '');
20
+ return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
21
+ }
22
+ /**
23
+ * Extract a workspace name from its path
24
+ * @param workspacePath - Workspace path
25
+ * @param fallbackIndex - Index to use for fallback name
26
+ * @returns Workspace name
27
+ */
28
+ export function getWorkspaceName(workspacePath, fallbackIndex) {
29
+ const trimmed = workspacePath.replace(/[\\/]+$/, '');
30
+ const base = path.basename(trimmed);
31
+ return base || `Project ${fallbackIndex}`;
32
+ }
33
+ // Re-export browser-compatible utilities
34
+ export { getFileExtension, getLanguageFromPath, normalizePathSeparators, isHidden, getErrorMessage, createHttpError, truncate, shortId, formatFileSize, sortFileEntries } from './utils.js';
35
+ //# sourceMappingURL=utils-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-node.js","sourceRoot":"","sources":["../utils-node.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,qEAAqE;AAErE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE,WAAmB;IAC3E,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,WAAW,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,aAAqB;IACnD,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;AAC9E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,aAAqB,EAAE,aAAqB;IAC3E,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,IAAI,IAAI,WAAW,aAAa,EAAE,CAAC;AAC5C,CAAC;AAED,yCAAyC;AACzC,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,QAAQ,EACR,eAAe,EACf,eAAe,EACf,QAAQ,EACR,OAAO,EACP,cAAc,EACd,eAAe,EAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Get a workspace key for indexing (handles case-insensitivity on Windows)
3
+ * @param workspacePath - Workspace path
4
+ * @returns Normalized key for indexing
5
+ */
6
+ export declare function getWorkspaceKey(workspacePath: string): string;
7
+ /**
8
+ * Extract a workspace name from its path
9
+ * @param workspacePath - Workspace path
10
+ * @param fallbackIndex - Index to use for fallback name
11
+ * @returns Workspace name
12
+ */
13
+ export declare function getWorkspaceName(workspacePath: string, fallbackIndex: number): string;
14
+ /**
15
+ * Normalize a workspace path to an absolute path
16
+ * Note: This function requires Node.js path module
17
+ * For browser usage, import from utils-node.ts instead
18
+ * @param inputPath - Input path (can be relative or absolute)
19
+ * @param defaultPath - Default path to use if inputPath is empty
20
+ * @returns Normalized absolute path
21
+ */
22
+ export declare function normalizeWorkspacePath(inputPath: string, defaultPath: string): string;
23
+ /**
24
+ * Get file extension from a path
25
+ * @param filePath - File path
26
+ * @returns File extension (without dot) or empty string
27
+ */
28
+ export declare function getFileExtension(filePath: string): string;
29
+ /**
30
+ * Map file extension to Monaco editor language
31
+ * @param filePath - File path
32
+ * @returns Monaco language identifier
33
+ */
34
+ export declare function getLanguageFromPath(filePath: string): string;
35
+ /**
36
+ * Normalize path separators to forward slashes
37
+ * @param inputPath - Input path
38
+ * @returns Path with forward slashes
39
+ */
40
+ export declare function normalizePathSeparators(inputPath: string): string;
41
+ /**
42
+ * Check if a path is a hidden file or directory (starts with .)
43
+ * @param name - File or directory name
44
+ * @returns True if hidden
45
+ */
46
+ export declare function isHidden(name: string): boolean;
47
+ /**
48
+ * Get error message from unknown error type
49
+ * @param error - Error object
50
+ * @returns Error message string
51
+ */
52
+ export declare function getErrorMessage(error: unknown): string;
53
+ /**
54
+ * Create an HTTP error with status code
55
+ * @param message - Error message
56
+ * @param status - HTTP status code
57
+ * @returns Error object with status property
58
+ */
59
+ export declare function createHttpError(message: string, status: number): Error & {
60
+ status: number;
61
+ };
62
+ /**
63
+ * Truncate string to max length with ellipsis
64
+ * @param str - Input string
65
+ * @param maxLength - Maximum length
66
+ * @returns Truncated string
67
+ */
68
+ export declare function truncate(str: string, maxLength: number): string;
69
+ /**
70
+ * Generate a short ID from a UUID (first 8 characters)
71
+ * @param uuid - Full UUID
72
+ * @returns Short ID
73
+ */
74
+ export declare function shortId(uuid: string): string;
75
+ /**
76
+ * Format file size in human-readable format
77
+ * @param bytes - File size in bytes
78
+ * @returns Formatted file size string
79
+ */
80
+ export declare function formatFileSize(bytes: number): string;
81
+ /**
82
+ * Sort file system entries (directories first, then alphabetically)
83
+ * @param entries - Array of file system entries
84
+ * @returns Sorted array
85
+ */
86
+ export declare function sortFileEntries<T extends {
87
+ name: string;
88
+ type: 'file' | 'dir';
89
+ }>(entries: T[]): T[];
90
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../utils.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAK7D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAMrF;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAIrF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA+C5D;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKtD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAI3F;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMpD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAOnG"}
@@ -0,0 +1,186 @@
1
+ // Shared utility functions (browser-compatible)
2
+ /**
3
+ * Get a workspace key for indexing (handles case-insensitivity on Windows)
4
+ * @param workspacePath - Workspace path
5
+ * @returns Normalized key for indexing
6
+ */
7
+ export function getWorkspaceKey(workspacePath) {
8
+ const normalized = workspacePath.replace(/[\\/]+$/, '');
9
+ // In browser, we can't detect platform, so we normalize to lowercase
10
+ const platform = typeof process !== 'undefined' ? process.platform : 'unknown';
11
+ return platform === 'win32' ? normalized.toLowerCase() : normalized;
12
+ }
13
+ /**
14
+ * Extract a workspace name from its path
15
+ * @param workspacePath - Workspace path
16
+ * @param fallbackIndex - Index to use for fallback name
17
+ * @returns Workspace name
18
+ */
19
+ export function getWorkspaceName(workspacePath, fallbackIndex) {
20
+ const trimmed = workspacePath.replace(/[\\/]+$/, '');
21
+ // Browser-compatible basename
22
+ const parts = trimmed.split(/[\\/]/);
23
+ const base = parts[parts.length - 1] || '';
24
+ return base || `Project ${fallbackIndex}`;
25
+ }
26
+ /**
27
+ * Normalize a workspace path to an absolute path
28
+ * Note: This function requires Node.js path module
29
+ * For browser usage, import from utils-node.ts instead
30
+ * @param inputPath - Input path (can be relative or absolute)
31
+ * @param defaultPath - Default path to use if inputPath is empty
32
+ * @returns Normalized absolute path
33
+ */
34
+ export function normalizeWorkspacePath(inputPath, defaultPath) {
35
+ // This is a simplified version for browsers
36
+ // Server code should use the Node.js version from utils-node.ts
37
+ return inputPath || defaultPath;
38
+ }
39
+ /**
40
+ * Get file extension from a path
41
+ * @param filePath - File path
42
+ * @returns File extension (without dot) or empty string
43
+ */
44
+ export function getFileExtension(filePath) {
45
+ const lastDot = filePath.lastIndexOf('.');
46
+ if (lastDot === -1 || lastDot === 0)
47
+ return '';
48
+ const ext = filePath.slice(lastDot + 1);
49
+ return ext.toLowerCase();
50
+ }
51
+ /**
52
+ * Map file extension to Monaco editor language
53
+ * @param filePath - File path
54
+ * @returns Monaco language identifier
55
+ */
56
+ export function getLanguageFromPath(filePath) {
57
+ const ext = getFileExtension(filePath);
58
+ const languageMap = {
59
+ 'js': 'javascript',
60
+ 'jsx': 'javascript',
61
+ 'ts': 'typescript',
62
+ 'tsx': 'typescript',
63
+ 'json': 'json',
64
+ 'html': 'html',
65
+ 'css': 'css',
66
+ 'scss': 'scss',
67
+ 'sass': 'sass',
68
+ 'less': 'less',
69
+ 'md': 'markdown',
70
+ 'py': 'python',
71
+ 'rb': 'ruby',
72
+ 'go': 'go',
73
+ 'rs': 'rust',
74
+ 'java': 'java',
75
+ 'c': 'c',
76
+ 'cpp': 'cpp',
77
+ 'cc': 'cpp',
78
+ 'cxx': 'cpp',
79
+ 'h': 'c',
80
+ 'hpp': 'cpp',
81
+ 'sh': 'shell',
82
+ 'bash': 'shell',
83
+ 'zsh': 'shell',
84
+ 'fish': 'shell',
85
+ 'xml': 'xml',
86
+ 'yaml': 'yaml',
87
+ 'yml': 'yaml',
88
+ 'toml': 'toml',
89
+ 'sql': 'sql',
90
+ 'graphql': 'graphql',
91
+ 'vue': 'vue',
92
+ 'svelte': 'svelte',
93
+ 'php': 'php',
94
+ 'r': 'r',
95
+ 'swift': 'swift',
96
+ 'kt': 'kotlin',
97
+ 'dart': 'dart',
98
+ 'lua': 'lua',
99
+ 'dockerfile': 'dockerfile',
100
+ };
101
+ return languageMap[ext] || 'plaintext';
102
+ }
103
+ /**
104
+ * Normalize path separators to forward slashes
105
+ * @param inputPath - Input path
106
+ * @returns Path with forward slashes
107
+ */
108
+ export function normalizePathSeparators(inputPath) {
109
+ return inputPath.replace(/\\/g, '/');
110
+ }
111
+ /**
112
+ * Check if a path is a hidden file or directory (starts with .)
113
+ * @param name - File or directory name
114
+ * @returns True if hidden
115
+ */
116
+ export function isHidden(name) {
117
+ return name.startsWith('.');
118
+ }
119
+ /**
120
+ * Get error message from unknown error type
121
+ * @param error - Error object
122
+ * @returns Error message string
123
+ */
124
+ export function getErrorMessage(error) {
125
+ if (error instanceof Error) {
126
+ return error.message;
127
+ }
128
+ return String(error);
129
+ }
130
+ /**
131
+ * Create an HTTP error with status code
132
+ * @param message - Error message
133
+ * @param status - HTTP status code
134
+ * @returns Error object with status property
135
+ */
136
+ export function createHttpError(message, status) {
137
+ const error = new Error(message);
138
+ error.status = status;
139
+ return error;
140
+ }
141
+ /**
142
+ * Truncate string to max length with ellipsis
143
+ * @param str - Input string
144
+ * @param maxLength - Maximum length
145
+ * @returns Truncated string
146
+ */
147
+ export function truncate(str, maxLength) {
148
+ if (str.length <= maxLength)
149
+ return str;
150
+ return str.slice(0, maxLength - 3) + '...';
151
+ }
152
+ /**
153
+ * Generate a short ID from a UUID (first 8 characters)
154
+ * @param uuid - Full UUID
155
+ * @returns Short ID
156
+ */
157
+ export function shortId(uuid) {
158
+ return uuid.slice(0, 8);
159
+ }
160
+ /**
161
+ * Format file size in human-readable format
162
+ * @param bytes - File size in bytes
163
+ * @returns Formatted file size string
164
+ */
165
+ export function formatFileSize(bytes) {
166
+ if (bytes === 0)
167
+ return '0 B';
168
+ const k = 1024;
169
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
170
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
171
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
172
+ }
173
+ /**
174
+ * Sort file system entries (directories first, then alphabetically)
175
+ * @param entries - Array of file system entries
176
+ * @returns Sorted array
177
+ */
178
+ export function sortFileEntries(entries) {
179
+ return entries.sort((a, b) => {
180
+ if (a.type !== b.type) {
181
+ return a.type === 'dir' ? -1 : 1;
182
+ }
183
+ return a.name.localeCompare(b.name);
184
+ });
185
+ }
186
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../utils.ts"],"names":[],"mappings":"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"}