code-squad-cli 1.2.13 → 1.2.16
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/constants/filters.js +20 -0
- package/dist/flip/index.js +18 -16
- package/dist/flip/routes/static.js +1 -2
- package/dist/flip/routes/submit.js +3 -3
- package/dist/flip/server/Server.js +1 -1
- package/dist/flip/watcher/FileWatcher.js +8 -8
- package/dist/index.js +48 -28
- package/package.json +1 -1
|
@@ -24,6 +24,26 @@ export const FILTERED_PATTERNS = new Set([
|
|
|
24
24
|
'__pycache__',
|
|
25
25
|
'.pytest_cache',
|
|
26
26
|
'target',
|
|
27
|
+
// macOS system folders (prevent FD exhaustion when run from home dir)
|
|
28
|
+
'Library',
|
|
29
|
+
'Applications',
|
|
30
|
+
'Pictures',
|
|
31
|
+
'Movies',
|
|
32
|
+
'Music',
|
|
33
|
+
'Downloads',
|
|
34
|
+
'.Trash',
|
|
35
|
+
'.local',
|
|
36
|
+
'.npm',
|
|
37
|
+
'.nvm',
|
|
38
|
+
'.cargo',
|
|
39
|
+
'.rustup',
|
|
40
|
+
'.volta',
|
|
41
|
+
'.pyenv',
|
|
42
|
+
'.rbenv',
|
|
43
|
+
// Linux system folders
|
|
44
|
+
'.config',
|
|
45
|
+
'.mozilla',
|
|
46
|
+
'.thunderbird',
|
|
27
47
|
]);
|
|
28
48
|
export function isFiltered(name) {
|
|
29
49
|
return FILTERED_PATTERNS.has(name);
|
package/dist/flip/index.js
CHANGED
|
@@ -4,6 +4,8 @@ import path from 'path';
|
|
|
4
4
|
import { execSync } from 'child_process';
|
|
5
5
|
import { copyToClipboard } from './output/clipboard.js';
|
|
6
6
|
const DEFAULT_PORT = 51234;
|
|
7
|
+
// Use stderr for info messages (stdout goes to terminal input in coprocess mode)
|
|
8
|
+
const log = (...args) => console.error(...args);
|
|
7
9
|
function formatTime() {
|
|
8
10
|
const now = new Date();
|
|
9
11
|
const hours = String(now.getHours()).padStart(2, '0');
|
|
@@ -63,34 +65,34 @@ export async function runFlip(args) {
|
|
|
63
65
|
case 'serve': {
|
|
64
66
|
// Daemon mode: start server, keep running
|
|
65
67
|
const port = await findFreePort(DEFAULT_PORT);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
log(`Server running at http://localhost:${port}`);
|
|
69
|
+
log('Press Ctrl+C to stop');
|
|
70
|
+
log('');
|
|
71
|
+
log('To open browser, run: csq flip open');
|
|
72
|
+
log(`Or use hotkey to open: open http://localhost:${port}`);
|
|
71
73
|
// Run server in loop (restarts after each submit/cancel)
|
|
72
74
|
while (true) {
|
|
73
75
|
const server = new Server(cwd, port);
|
|
74
76
|
const result = await server.run();
|
|
75
77
|
if (result) {
|
|
76
|
-
|
|
78
|
+
log(`[${formatTime()}] Submitted ${result.length} characters`);
|
|
77
79
|
}
|
|
78
80
|
else {
|
|
79
|
-
|
|
81
|
+
log(`[${formatTime()}] Cancelled`);
|
|
80
82
|
}
|
|
81
|
-
|
|
83
|
+
log(`[${formatTime()}] Ready for next session...`);
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
case 'open': {
|
|
85
87
|
// Just open browser to existing server
|
|
86
88
|
const url = `http://localhost:${DEFAULT_PORT}`;
|
|
87
|
-
|
|
89
|
+
log(`Opening ${url} in browser...`);
|
|
88
90
|
try {
|
|
89
91
|
await open(url);
|
|
90
92
|
}
|
|
91
93
|
catch (e) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
log('Failed to open browser:', e);
|
|
95
|
+
log('Is the server running? Start with: csq flip serve');
|
|
94
96
|
}
|
|
95
97
|
break;
|
|
96
98
|
}
|
|
@@ -101,21 +103,21 @@ export async function runFlip(args) {
|
|
|
101
103
|
const url = sessionId
|
|
102
104
|
? `http://localhost:${port}?session=${sessionId}`
|
|
103
105
|
: `http://localhost:${port}`;
|
|
104
|
-
|
|
106
|
+
log(`Opening ${url} in browser...`);
|
|
105
107
|
try {
|
|
106
108
|
await open(url);
|
|
107
109
|
}
|
|
108
110
|
catch (e) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
log('Failed to open browser:', e);
|
|
112
|
+
log(`Please open ${url} manually`);
|
|
111
113
|
}
|
|
112
114
|
const server = new Server(cwd, port);
|
|
113
115
|
const result = await server.run();
|
|
114
116
|
if (result) {
|
|
115
|
-
|
|
117
|
+
log(`\nSubmitted ${result.length} characters`);
|
|
116
118
|
}
|
|
117
119
|
else {
|
|
118
|
-
|
|
120
|
+
log('\nCancelled');
|
|
119
121
|
}
|
|
120
122
|
break;
|
|
121
123
|
}
|
|
@@ -8,8 +8,7 @@ export function createStaticRouter() {
|
|
|
8
8
|
// Get __dirname equivalent in ESM
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
10
|
const __dirname = path.dirname(__filename);
|
|
11
|
-
//
|
|
12
|
-
// - Bundled: dist/flip-ui/dist
|
|
11
|
+
// Bundled: __dirname is dist/, flip-ui is at dist/flip-ui/dist
|
|
13
12
|
let distPath = path.resolve(__dirname, 'flip-ui/dist');
|
|
14
13
|
// If the bundled path doesn't exist, fall back to the unbundled (development) path.
|
|
15
14
|
// - Unbundled: packages/cli/flip-ui/dist
|
|
@@ -26,9 +26,9 @@ router.post('/', async (req, res) => {
|
|
|
26
26
|
}
|
|
27
27
|
catch (e) {
|
|
28
28
|
console.error('Failed to copy to clipboard:', e);
|
|
29
|
-
console.
|
|
30
|
-
console.
|
|
31
|
-
console.
|
|
29
|
+
console.error('\n--- Output (copy manually) ---');
|
|
30
|
+
console.error(formatted);
|
|
31
|
+
console.error('--- End of output ---\n');
|
|
32
32
|
}
|
|
33
33
|
// Schedule paste only if clipboard copy succeeded
|
|
34
34
|
if (clipboardSuccess) {
|
|
@@ -16,15 +16,15 @@ export class FileWatcher {
|
|
|
16
16
|
this.debounceMs = options.debounceMs ?? 300;
|
|
17
17
|
}
|
|
18
18
|
start() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return
|
|
25
|
-
}
|
|
19
|
+
// Use function-based ignore to prevent chokidar from even opening filtered directories
|
|
20
|
+
const shouldIgnore = (filePath) => {
|
|
21
|
+
const relativePath = path.relative(this.cwd, filePath);
|
|
22
|
+
const segments = relativePath.split(path.sep);
|
|
23
|
+
// Ignore if any path segment matches filtered patterns (except .git)
|
|
24
|
+
return segments.some(segment => segment !== '.git' && FILTERED_PATTERNS.has(segment));
|
|
25
|
+
};
|
|
26
26
|
this.watcher = chokidar.watch(this.cwd, {
|
|
27
|
-
ignored:
|
|
27
|
+
ignored: shouldIgnore,
|
|
28
28
|
persistent: true,
|
|
29
29
|
ignoreInitial: true,
|
|
30
30
|
awaitWriteFinish: {
|
package/dist/index.js
CHANGED
|
@@ -448,7 +448,27 @@ var FILTERED_PATTERNS = /* @__PURE__ */ new Set([
|
|
|
448
448
|
"coverage",
|
|
449
449
|
"__pycache__",
|
|
450
450
|
".pytest_cache",
|
|
451
|
-
"target"
|
|
451
|
+
"target",
|
|
452
|
+
// macOS system folders (prevent FD exhaustion when run from home dir)
|
|
453
|
+
"Library",
|
|
454
|
+
"Applications",
|
|
455
|
+
"Pictures",
|
|
456
|
+
"Movies",
|
|
457
|
+
"Music",
|
|
458
|
+
"Downloads",
|
|
459
|
+
".Trash",
|
|
460
|
+
".local",
|
|
461
|
+
".npm",
|
|
462
|
+
".nvm",
|
|
463
|
+
".cargo",
|
|
464
|
+
".rustup",
|
|
465
|
+
".volta",
|
|
466
|
+
".pyenv",
|
|
467
|
+
".rbenv",
|
|
468
|
+
// Linux system folders
|
|
469
|
+
".config",
|
|
470
|
+
".mozilla",
|
|
471
|
+
".thunderbird"
|
|
452
472
|
]);
|
|
453
473
|
function isFiltered(name) {
|
|
454
474
|
return FILTERED_PATTERNS.has(name);
|
|
@@ -1069,9 +1089,9 @@ router4.post("/", async (req, res) => {
|
|
|
1069
1089
|
clipboardSuccess = true;
|
|
1070
1090
|
} catch (e) {
|
|
1071
1091
|
console.error("Failed to copy to clipboard:", e);
|
|
1072
|
-
console.
|
|
1073
|
-
console.
|
|
1074
|
-
console.
|
|
1092
|
+
console.error("\n--- Output (copy manually) ---");
|
|
1093
|
+
console.error(formatted);
|
|
1094
|
+
console.error("--- End of output ---\n");
|
|
1075
1095
|
}
|
|
1076
1096
|
if (clipboardSuccess) {
|
|
1077
1097
|
try {
|
|
@@ -1169,14 +1189,13 @@ var FileWatcher = class {
|
|
|
1169
1189
|
this.debounceMs = options.debounceMs ?? 300;
|
|
1170
1190
|
}
|
|
1171
1191
|
start() {
|
|
1172
|
-
const
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
}).filter(Boolean);
|
|
1192
|
+
const shouldIgnore = (filePath) => {
|
|
1193
|
+
const relativePath = path8.relative(this.cwd, filePath);
|
|
1194
|
+
const segments = relativePath.split(path8.sep);
|
|
1195
|
+
return segments.some((segment) => segment !== ".git" && FILTERED_PATTERNS.has(segment));
|
|
1196
|
+
};
|
|
1178
1197
|
this.watcher = chokidar.watch(this.cwd, {
|
|
1179
|
-
ignored:
|
|
1198
|
+
ignored: shouldIgnore,
|
|
1180
1199
|
persistent: true,
|
|
1181
1200
|
ignoreInitial: true,
|
|
1182
1201
|
awaitWriteFinish: {
|
|
@@ -1352,7 +1371,7 @@ var Server = class {
|
|
|
1352
1371
|
resolve2(output);
|
|
1353
1372
|
};
|
|
1354
1373
|
server.listen(this.port, "127.0.0.1", () => {
|
|
1355
|
-
console.
|
|
1374
|
+
console.error(`Server running at http://localhost:${this.port}`);
|
|
1356
1375
|
});
|
|
1357
1376
|
});
|
|
1358
1377
|
}
|
|
@@ -1382,6 +1401,7 @@ import open from "open";
|
|
|
1382
1401
|
import path9 from "path";
|
|
1383
1402
|
import { execSync as execSync2 } from "child_process";
|
|
1384
1403
|
var DEFAULT_PORT = 51234;
|
|
1404
|
+
var log = (...args) => console.error(...args);
|
|
1385
1405
|
function formatTime() {
|
|
1386
1406
|
const now = /* @__PURE__ */ new Date();
|
|
1387
1407
|
const hours = String(now.getHours()).padStart(2, "0");
|
|
@@ -1436,30 +1456,30 @@ async function runFlip(args) {
|
|
|
1436
1456
|
}
|
|
1437
1457
|
case "serve": {
|
|
1438
1458
|
const port = await findFreePort(DEFAULT_PORT);
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1459
|
+
log(`Server running at http://localhost:${port}`);
|
|
1460
|
+
log("Press Ctrl+C to stop");
|
|
1461
|
+
log("");
|
|
1462
|
+
log("To open browser, run: csq flip open");
|
|
1463
|
+
log(`Or use hotkey to open: open http://localhost:${port}`);
|
|
1444
1464
|
while (true) {
|
|
1445
1465
|
const server = new Server(cwd, port);
|
|
1446
1466
|
const result = await server.run();
|
|
1447
1467
|
if (result) {
|
|
1448
|
-
|
|
1468
|
+
log(`[${formatTime()}] Submitted ${result.length} characters`);
|
|
1449
1469
|
} else {
|
|
1450
|
-
|
|
1470
|
+
log(`[${formatTime()}] Cancelled`);
|
|
1451
1471
|
}
|
|
1452
|
-
|
|
1472
|
+
log(`[${formatTime()}] Ready for next session...`);
|
|
1453
1473
|
}
|
|
1454
1474
|
}
|
|
1455
1475
|
case "open": {
|
|
1456
1476
|
const url = `http://localhost:${DEFAULT_PORT}`;
|
|
1457
|
-
|
|
1477
|
+
log(`Opening ${url} in browser...`);
|
|
1458
1478
|
try {
|
|
1459
1479
|
await open(url);
|
|
1460
1480
|
} catch (e) {
|
|
1461
|
-
|
|
1462
|
-
|
|
1481
|
+
log("Failed to open browser:", e);
|
|
1482
|
+
log("Is the server running? Start with: csq flip serve");
|
|
1463
1483
|
}
|
|
1464
1484
|
break;
|
|
1465
1485
|
}
|
|
@@ -1467,20 +1487,20 @@ async function runFlip(args) {
|
|
|
1467
1487
|
default: {
|
|
1468
1488
|
const port = await findFreePort(DEFAULT_PORT);
|
|
1469
1489
|
const url = sessionId ? `http://localhost:${port}?session=${sessionId}` : `http://localhost:${port}`;
|
|
1470
|
-
|
|
1490
|
+
log(`Opening ${url} in browser...`);
|
|
1471
1491
|
try {
|
|
1472
1492
|
await open(url);
|
|
1473
1493
|
} catch (e) {
|
|
1474
|
-
|
|
1475
|
-
|
|
1494
|
+
log("Failed to open browser:", e);
|
|
1495
|
+
log(`Please open ${url} manually`);
|
|
1476
1496
|
}
|
|
1477
1497
|
const server = new Server(cwd, port);
|
|
1478
1498
|
const result = await server.run();
|
|
1479
1499
|
if (result) {
|
|
1480
|
-
|
|
1500
|
+
log(`
|
|
1481
1501
|
Submitted ${result.length} characters`);
|
|
1482
1502
|
} else {
|
|
1483
|
-
|
|
1503
|
+
log("\nCancelled");
|
|
1484
1504
|
}
|
|
1485
1505
|
break;
|
|
1486
1506
|
}
|