code-squad-cli 1.2.3 → 1.2.4
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.
- package/dist/flip/routes/file.js +122 -34
- package/dist/flip/routes/files.js +29 -2
- package/dist/flip-ui/dist/assets/index-DTf1sRAX.css +1 -0
- package/dist/flip-ui/dist/assets/index-DmJdj9bX.js +154 -0
- package/dist/flip-ui/dist/index.html +2 -2
- package/dist/index.js +145 -36
- package/package.json +1 -1
- package/dist/flip-ui/dist/assets/index-BqoCRrTA.css +0 -1
- package/dist/flip-ui/dist/assets/index-CgNq-jV5.js +0 -69
package/dist/flip/routes/file.js
CHANGED
|
@@ -2,42 +2,130 @@ import { Router } from 'express';
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
const router = Router();
|
|
5
|
+
// Extension to language mapping
|
|
6
|
+
const extensionMap = {
|
|
7
|
+
// JavaScript/TypeScript
|
|
8
|
+
js: 'javascript',
|
|
9
|
+
mjs: 'javascript',
|
|
10
|
+
cjs: 'javascript',
|
|
11
|
+
ts: 'typescript',
|
|
12
|
+
mts: 'typescript',
|
|
13
|
+
cts: 'typescript',
|
|
14
|
+
tsx: 'tsx',
|
|
15
|
+
jsx: 'jsx',
|
|
16
|
+
// Systems languages
|
|
17
|
+
rs: 'rust',
|
|
18
|
+
go: 'go',
|
|
19
|
+
c: 'c',
|
|
20
|
+
cpp: 'cpp',
|
|
21
|
+
cc: 'cpp',
|
|
22
|
+
cxx: 'cpp',
|
|
23
|
+
h: 'cpp',
|
|
24
|
+
hpp: 'cpp',
|
|
25
|
+
hxx: 'cpp',
|
|
26
|
+
// JVM languages
|
|
27
|
+
java: 'java',
|
|
28
|
+
kt: 'kotlin',
|
|
29
|
+
kts: 'kotlin',
|
|
30
|
+
scala: 'scala',
|
|
31
|
+
groovy: 'groovy',
|
|
32
|
+
// Scripting languages
|
|
33
|
+
py: 'python',
|
|
34
|
+
rb: 'ruby',
|
|
35
|
+
php: 'php',
|
|
36
|
+
pl: 'perl',
|
|
37
|
+
lua: 'lua',
|
|
38
|
+
// Mobile
|
|
39
|
+
swift: 'swift',
|
|
40
|
+
m: 'objective-c',
|
|
41
|
+
mm: 'objective-cpp',
|
|
42
|
+
dart: 'dart',
|
|
43
|
+
// Web
|
|
44
|
+
html: 'html',
|
|
45
|
+
htm: 'html',
|
|
46
|
+
css: 'css',
|
|
47
|
+
scss: 'scss',
|
|
48
|
+
sass: 'sass',
|
|
49
|
+
less: 'less',
|
|
50
|
+
vue: 'vue',
|
|
51
|
+
svelte: 'svelte',
|
|
52
|
+
astro: 'astro',
|
|
53
|
+
// Data formats
|
|
54
|
+
json: 'json',
|
|
55
|
+
jsonc: 'jsonc',
|
|
56
|
+
yaml: 'yaml',
|
|
57
|
+
yml: 'yaml',
|
|
58
|
+
toml: 'toml',
|
|
59
|
+
xml: 'xml',
|
|
60
|
+
csv: 'csv',
|
|
61
|
+
// Documentation
|
|
62
|
+
md: 'markdown',
|
|
63
|
+
mdx: 'mdx',
|
|
64
|
+
rst: 'rst',
|
|
65
|
+
tex: 'latex',
|
|
66
|
+
// Shell
|
|
67
|
+
sh: 'bash',
|
|
68
|
+
bash: 'bash',
|
|
69
|
+
zsh: 'bash',
|
|
70
|
+
fish: 'fish',
|
|
71
|
+
ps1: 'powershell',
|
|
72
|
+
bat: 'batch',
|
|
73
|
+
cmd: 'batch',
|
|
74
|
+
// Database
|
|
75
|
+
sql: 'sql',
|
|
76
|
+
prisma: 'prisma',
|
|
77
|
+
graphql: 'graphql',
|
|
78
|
+
gql: 'graphql',
|
|
79
|
+
// Config
|
|
80
|
+
ini: 'ini',
|
|
81
|
+
conf: 'ini',
|
|
82
|
+
cfg: 'ini',
|
|
83
|
+
env: 'dotenv',
|
|
84
|
+
// Other
|
|
85
|
+
dockerfile: 'dockerfile',
|
|
86
|
+
makefile: 'makefile',
|
|
87
|
+
cmake: 'cmake',
|
|
88
|
+
diff: 'diff',
|
|
89
|
+
patch: 'diff',
|
|
90
|
+
};
|
|
91
|
+
// Filename to language mapping (for files without extensions)
|
|
92
|
+
const filenameMap = {
|
|
93
|
+
'Makefile': 'makefile',
|
|
94
|
+
'makefile': 'makefile',
|
|
95
|
+
'GNUmakefile': 'makefile',
|
|
96
|
+
'Dockerfile': 'dockerfile',
|
|
97
|
+
'dockerfile': 'dockerfile',
|
|
98
|
+
'Containerfile': 'dockerfile',
|
|
99
|
+
'Jenkinsfile': 'groovy',
|
|
100
|
+
'Vagrantfile': 'ruby',
|
|
101
|
+
'Gemfile': 'ruby',
|
|
102
|
+
'Rakefile': 'ruby',
|
|
103
|
+
'Brewfile': 'ruby',
|
|
104
|
+
'Podfile': 'ruby',
|
|
105
|
+
'Fastfile': 'ruby',
|
|
106
|
+
'Guardfile': 'ruby',
|
|
107
|
+
'.gitignore': 'gitignore',
|
|
108
|
+
'.gitattributes': 'gitattributes',
|
|
109
|
+
'.editorconfig': 'editorconfig',
|
|
110
|
+
'.bashrc': 'bash',
|
|
111
|
+
'.zshrc': 'bash',
|
|
112
|
+
'.bash_profile': 'bash',
|
|
113
|
+
'.profile': 'bash',
|
|
114
|
+
'CMakeLists.txt': 'cmake',
|
|
115
|
+
'CODEOWNERS': 'gitignore',
|
|
116
|
+
};
|
|
5
117
|
function detectLanguage(filePath) {
|
|
118
|
+
const basename = path.basename(filePath);
|
|
119
|
+
// Check filename first (for files like Makefile, Dockerfile)
|
|
120
|
+
if (filenameMap[basename]) {
|
|
121
|
+
return filenameMap[basename];
|
|
122
|
+
}
|
|
123
|
+
// Then check extension
|
|
6
124
|
const ext = path.extname(filePath).slice(1).toLowerCase();
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
tsx: 'tsx',
|
|
12
|
-
jsx: 'jsx',
|
|
13
|
-
py: 'python',
|
|
14
|
-
go: 'go',
|
|
15
|
-
java: 'java',
|
|
16
|
-
c: 'c',
|
|
17
|
-
cpp: 'cpp',
|
|
18
|
-
cc: 'cpp',
|
|
19
|
-
cxx: 'cpp',
|
|
20
|
-
h: 'cpp',
|
|
21
|
-
hpp: 'cpp',
|
|
22
|
-
md: 'markdown',
|
|
23
|
-
json: 'json',
|
|
24
|
-
yaml: 'yaml',
|
|
25
|
-
yml: 'yaml',
|
|
26
|
-
toml: 'toml',
|
|
27
|
-
html: 'html',
|
|
28
|
-
css: 'css',
|
|
29
|
-
scss: 'scss',
|
|
30
|
-
sh: 'bash',
|
|
31
|
-
bash: 'bash',
|
|
32
|
-
sql: 'sql',
|
|
33
|
-
rb: 'ruby',
|
|
34
|
-
swift: 'swift',
|
|
35
|
-
kt: 'kotlin',
|
|
36
|
-
kts: 'kotlin',
|
|
37
|
-
xml: 'xml',
|
|
38
|
-
vue: 'vue',
|
|
39
|
-
};
|
|
40
|
-
return languageMap[ext] || 'plaintext';
|
|
125
|
+
if (extensionMap[ext]) {
|
|
126
|
+
return extensionMap[ext];
|
|
127
|
+
}
|
|
128
|
+
return 'text';
|
|
41
129
|
}
|
|
42
130
|
// GET /api/file?path=<path>
|
|
43
131
|
router.get('/', (req, res) => {
|
|
@@ -24,9 +24,36 @@ const DEFAULT_IGNORES = [
|
|
|
24
24
|
'yarn.lock',
|
|
25
25
|
'.DS_Store',
|
|
26
26
|
];
|
|
27
|
+
// Dotfiles that should be visible in the file tree
|
|
28
|
+
const VISIBLE_DOTFILES = new Set([
|
|
29
|
+
'.gitignore',
|
|
30
|
+
'.gitattributes',
|
|
31
|
+
'.env.example',
|
|
32
|
+
'.env.local.example',
|
|
33
|
+
'.eslintrc',
|
|
34
|
+
'.eslintrc.js',
|
|
35
|
+
'.eslintrc.cjs',
|
|
36
|
+
'.eslintrc.json',
|
|
37
|
+
'.eslintrc.yml',
|
|
38
|
+
'.prettierrc',
|
|
39
|
+
'.prettierrc.js',
|
|
40
|
+
'.prettierrc.cjs',
|
|
41
|
+
'.prettierrc.json',
|
|
42
|
+
'.prettierrc.yml',
|
|
43
|
+
'.editorconfig',
|
|
44
|
+
'.npmrc',
|
|
45
|
+
'.nvmrc',
|
|
46
|
+
'.node-version',
|
|
47
|
+
'.dockerignore',
|
|
48
|
+
'.browserslistrc',
|
|
49
|
+
'.babelrc',
|
|
50
|
+
'.babelrc.js',
|
|
51
|
+
'.babelrc.json',
|
|
52
|
+
]);
|
|
27
53
|
function shouldIgnore(name) {
|
|
28
|
-
if (name.startsWith('.')
|
|
29
|
-
|
|
54
|
+
if (name.startsWith('.')) {
|
|
55
|
+
// Allow specific dotfiles
|
|
56
|
+
return !VISIBLE_DOTFILES.has(name);
|
|
30
57
|
}
|
|
31
58
|
return DEFAULT_IGNORES.includes(name);
|
|
32
59
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*{box-sizing:border-box;margin:0;padding:0}:root{--bg-primary: #0d1117;--bg-secondary: #161b22;--bg-tertiary: #21262d;--bg-hover: #30363d;--bg-selected: #1f6feb26;--text-primary: #e6edf3;--text-secondary: #8b949e;--text-muted: #6e7681;--border-color: #30363d;--border-subtle: #21262d;--accent-primary: #238636;--accent-primary-hover: #2ea043;--accent-secondary: #1f6feb;--git-modified: #d29922;--git-untracked: #3fb950;--git-deleted: #f85149;--git-added: #3fb950;--line-number-color: #6e7681;--selection-bg: #264f78;--diff-add-bg: rgba(46, 160, 67, .15);--diff-add-text: #7ee787;--diff-add-border: rgba(46, 160, 67, .4);--diff-delete-bg: rgba(248, 81, 73, .15);--diff-delete-text: #ffa198;--diff-delete-border: rgba(248, 81, 73, .4);--diff-hunk-bg: rgba(56, 139, 253, .1);--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;--font-mono: "SF Mono", "Menlo", "Monaco", "Consolas", monospace;--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-5: 24px;--transition-fast: .15s ease;--transition-normal: .2s ease}body{font-family:var(--font-sans);font-size:14px;background-color:var(--bg-primary);color:var(--text-primary);height:100vh;overflow:hidden}#root{height:100%}.app{display:flex;flex-direction:column;height:100%}.main-content{display:flex;flex:1;overflow:hidden}.toolbar{display:flex;align-items:center;justify-content:space-between;height:40px;padding:0 var(--space-3);background-color:var(--bg-secondary);border-bottom:1px solid var(--border-subtle)}.toolbar-left,.toolbar-center,.toolbar-right{display:flex;align-items:center;gap:var(--space-2)}.toolbar-btn{display:flex;align-items:center;justify-content:center;gap:var(--space-1);height:28px;padding:0 var(--space-2);border:none;background:transparent;border-radius:6px;color:var(--text-secondary);cursor:pointer;transition:all var(--transition-fast)}.toolbar-btn:hover{background-color:var(--bg-hover);color:var(--text-primary)}.toolbar-btn.active{background-color:var(--bg-tertiary);color:var(--text-primary)}.toolbar-btn svg{flex-shrink:0}.diff-toggle{min-width:100px}.diff-mode-label{font-size:12px}.sidebar{width:280px;background-color:var(--bg-secondary);border-right:1px solid var(--border-subtle);overflow:hidden;display:flex;flex-direction:column;transition:width var(--transition-normal),opacity var(--transition-fast)}.sidebar.collapsed{width:0;opacity:0;border-right:none}.content{flex:1;overflow:hidden;display:flex;flex-direction:column;min-width:0}.staging-panel{width:320px;background-color:var(--bg-secondary);border-left:1px solid var(--border-subtle);overflow:hidden;display:flex;flex-direction:column;transition:width var(--transition-normal),opacity var(--transition-fast)}.staging-panel.collapsed{width:0;opacity:0;border-left:none}.footer{display:flex;align-items:center;justify-content:space-between;padding:var(--space-2) var(--space-4);background-color:var(--bg-secondary);border-top:1px solid var(--border-subtle);gap:var(--space-4)}.footer-actions{display:flex;gap:var(--space-2)}.file-tree{display:flex;flex-direction:column;height:100%}.file-tree-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-3) var(--space-4);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--text-secondary);border-bottom:1px solid var(--border-subtle)}.file-tree-header-actions{display:flex;gap:var(--space-1)}.filter-btn{display:flex;align-items:center;gap:var(--space-1);padding:2px 8px;border:none;background:transparent;border-radius:4px;color:var(--text-muted);font-size:10px;font-weight:600;cursor:pointer;transition:all var(--transition-fast)}.filter-btn:hover{background-color:var(--bg-hover);color:var(--text-secondary)}.filter-btn.active{background-color:var(--accent-secondary);color:#fff}.filter-btn .count{background-color:var(--bg-hover);padding:0 4px;border-radius:3px;font-size:9px}.filter-btn.active .count{background-color:#fff3}.file-tree-content{flex:1;overflow-y:auto;padding:var(--space-1) 0}.tree-item{display:flex;align-items:center;padding:var(--space-1) var(--space-2);cursor:pointer;-webkit-user-select:none;user-select:none;gap:6px}.tree-item:hover{background-color:var(--bg-hover)}.tree-icon{display:flex;align-items:center;justify-content:center;width:14px;color:var(--text-secondary);flex-shrink:0}.tree-folder-icon{display:flex;align-items:center;justify-content:center;width:14px;color:var(--git-modified);flex-shrink:0}.tree-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.git-badge{font-size:10px;font-weight:600;padding:1px 4px;border-radius:3px}.git-badge-modified{color:var(--git-modified);background-color:#d2992226}.git-badge-untracked{color:var(--git-untracked);background-color:#3fb95026}.git-badge-deleted{color:var(--git-deleted);background-color:#f8514926}.git-badge-added{color:var(--git-added);background-color:#3fb95026}.code-viewer{display:flex;flex-direction:column;height:100%;overflow:hidden}.code-viewer-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--text-secondary);gap:var(--space-3)}.code-viewer-empty .hint{display:flex;align-items:center;gap:var(--space-1);font-size:12px;color:var(--text-muted)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--space-5);gap:var(--space-3)}.empty-state-icon{color:var(--text-muted);opacity:.5}.code-viewer-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-2) var(--space-4);background-color:var(--bg-secondary);border-bottom:1px solid var(--border-subtle)}.file-path{font-size:13px;font-family:var(--font-mono)}.file-language{font-size:11px;color:var(--text-secondary);text-transform:uppercase}.code-viewer-content{flex:1;overflow:auto;font-family:var(--font-mono);font-size:13px;line-height:1.5}.code-line{display:flex;min-height:20px;cursor:pointer}.code-line:hover{background-color:var(--bg-hover)}.code-line-selected{background-color:var(--selection-bg)!important}.code-line-added{background-color:var(--diff-add-bg)!important}.code-line-added:hover{background-color:#2ea04340!important}.code-line-deleted{background-color:var(--diff-delete-bg)!important}.code-line-deleted:hover{background-color:#f8514940!important}.line-number{display:inline-block;min-width:50px;padding:0 var(--space-3);text-align:right;color:var(--line-number-color);-webkit-user-select:none;user-select:none;background-color:var(--bg-tertiary);border-right:1px solid var(--border-subtle)}.code-line code{flex:1;padding:0 var(--space-3);white-space:pre;background:transparent}.code-line code.hljs{background:transparent;padding:0 var(--space-3)}.code-content{flex:1;padding:0 var(--space-3);white-space:pre}.staging-list{display:flex;flex-direction:column;height:100%}.staging-list-empty{padding:var(--space-4)}.staging-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-3) var(--space-4);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--text-secondary);border-bottom:1px solid var(--border-subtle)}.staging-hint{font-size:12px;color:var(--text-muted);line-height:1.5}.staging-items{flex:1;overflow-y:auto;padding:var(--space-2)}.staging-item{background-color:var(--bg-tertiary);border-radius:6px;padding:var(--space-2) var(--space-3);margin-bottom:var(--space-2)}.staging-item-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-1)}.staging-location{font-family:var(--font-mono);font-size:12px;color:var(--text-secondary)}.staging-comment{font-size:13px;line-height:1.4}.comment-input{display:flex;align-items:center;gap:var(--space-3);flex:1}.comment-selection{font-family:var(--font-mono);font-size:12px;color:var(--accent-secondary);white-space:nowrap}.comment-field{flex:1;padding:var(--space-2) var(--space-3);background-color:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:6px;color:var(--text-primary);font-size:14px;transition:border-color var(--transition-fast)}.comment-field:focus{outline:none;border-color:var(--accent-secondary)}.comment-hint{color:var(--text-muted);font-size:13px}.fuzzy-finder-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#0009;display:flex;justify-content:center;padding-top:80px;z-index:100}.fuzzy-finder{background-color:var(--bg-secondary);border:1px solid var(--border-color);border-radius:12px;box-shadow:0 16px 48px #00000080;width:600px;max-height:400px;display:flex;flex-direction:column;overflow:hidden}.fuzzy-finder-input{padding:var(--space-4);background-color:var(--bg-tertiary);border:none;border-bottom:1px solid var(--border-subtle);color:var(--text-primary);font-size:16px}.fuzzy-finder-input:focus{outline:none}.fuzzy-finder-results{flex:1;overflow-y:auto}.fuzzy-finder-item{padding:var(--space-3) var(--space-4);cursor:pointer;font-family:var(--font-mono);font-size:13px}.fuzzy-finder-item:hover,.fuzzy-finder-item-selected{background-color:var(--bg-selected)}.fuzzy-finder-empty{padding:var(--space-4);color:var(--text-muted);text-align:center}.btn{padding:var(--space-2) var(--space-4);border:none;border-radius:6px;font-size:13px;font-weight:500;cursor:pointer;transition:background-color var(--transition-fast)}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-primary{background-color:var(--accent-primary);color:#fff}.btn-primary:hover:not(:disabled){background-color:var(--accent-primary-hover)}.btn-secondary{background-color:var(--bg-tertiary);color:var(--text-primary)}.btn-secondary:hover:not(:disabled){background-color:var(--bg-hover)}.btn-small{padding:var(--space-1) var(--space-3)}.btn-link{background:none;border:none;color:var(--accent-secondary);cursor:pointer;font-size:11px}.btn-link:hover{text-decoration:underline}.btn-icon{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:2px 6px}.btn-icon:hover{color:var(--text-primary)}.diff-side-by-side{display:flex;height:100%;overflow:hidden}.diff-pane{flex:1;overflow:auto;font-family:var(--font-mono);font-size:13px;line-height:1.5}.diff-pane-left{border-right:1px solid var(--border-color)}.diff-pane-header{padding:var(--space-2) var(--space-3);background-color:var(--bg-tertiary);border-bottom:1px solid var(--border-subtle);font-size:11px;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px}.code-viewer-loading{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted)}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--bg-hover);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#484f58}::-webkit-scrollbar-corner{background:transparent}
|