glad-web 1.0.46 → 2.0.1
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/README.md +4 -192
- package/THIRD_PARTY_NOTICES.md +27 -0
- package/bin/glad.cjs +56 -0
- package/package.json +19 -61
- package/README.zh-CN.md +0 -198
- package/assets/logo.svg +0 -43
- package/bin/cli.js +0 -65
- package/lib/ai-tools/demo/enhanced-demo.js +0 -625
- package/lib/ai-tools/demo/index.js +0 -24
- package/lib/ai-tools/demo/responses.js +0 -88
- package/lib/ai-tools/detector.js +0 -76
- package/lib/ai-tools/registry.js +0 -300
- package/lib/claude/cli-usage.js +0 -95
- package/lib/claude/config.js +0 -82
- package/lib/claude/structured-session.js +0 -884
- package/lib/claude/transcript-repository.js +0 -216
- package/lib/codex/image-store.js +0 -174
- package/lib/codex/structured-session.js +0 -1590
- package/lib/commands/config.js +0 -78
- package/lib/commands/tools.js +0 -128
- package/lib/commands/web.js +0 -605
- package/lib/config/constants.js +0 -17
- package/lib/config/manager.js +0 -108
- package/lib/git/service.js +0 -83
- package/lib/notifications/message-formatter.js +0 -94
- package/lib/notifications/notification-service.js +0 -143
- package/lib/notifications/serverchan-client.js +0 -58
- package/lib/notifications/serverchan-settings-store.js +0 -115
- package/lib/schedule/job-runner.js +0 -162
- package/lib/schedule/job-store.js +0 -167
- package/lib/schedule/key-sequences.js +0 -49
- package/lib/schedule/scheduler-service.js +0 -39
- package/lib/server/routes/notifications.js +0 -52
- package/lib/server/routes/providers.js +0 -114
- package/lib/server/routes/schedules.js +0 -54
- package/lib/server/routes/skillhub.js +0 -104
- package/lib/server/routes/usage.js +0 -23
- package/lib/server/routes/workspace.js +0 -77
- package/lib/session/buffer.js +0 -102
- package/lib/session/file-attachment-store.js +0 -168
- package/lib/session/pty-manager.js +0 -255
- package/lib/session/rendered-history.js +0 -225
- package/lib/session/session-manager.js +0 -1032
- package/lib/session/text-history.js +0 -274
- package/lib/skillhub/client.js +0 -121
- package/lib/skillhub/settings-store.js +0 -168
- package/lib/skillhub/skill-installer.js +0 -320
- package/lib/usage/ccusage-runner.js +0 -128
- package/lib/usage/source-catalog.js +0 -26
- package/lib/usage/usage-service.js +0 -226
- package/lib/utils/logger.js +0 -74
- package/lib/utils/pid.js +0 -67
- package/lib/utils/validation.js +0 -53
- package/lib/web/bootstrap.js +0 -34
- package/lib/web/claude.js +0 -1150
- package/lib/web/codex.js +0 -1045
- package/lib/web/composer.js +0 -493
- package/lib/web/core.js +0 -385
- package/lib/web/git.js +0 -535
- package/lib/web/gitgraph.js +0 -293
- package/lib/web/index.html +0 -547
- package/lib/web/layout.js +0 -69
- package/lib/web/notifications.js +0 -164
- package/lib/web/schedules.js +0 -245
- package/lib/web/session.js +0 -361
- package/lib/web/shell.js +0 -74
- package/lib/web/skillhub.js +0 -197
- package/lib/web/styles.css +0 -932
- package/lib/web/terminal-scroll.js +0 -81
- package/lib/web/theme.js +0 -60
- package/lib/web/timed-inputs.js +0 -216
- package/lib/web/usage.js +0 -323
- package/lib/workspace/service.js +0 -77
- package/scripts/check-syntax.js +0 -26
package/lib/utils/logger.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const os = require('os');
|
|
4
|
-
const chalk = require('chalk');
|
|
5
|
-
|
|
6
|
-
const LOG_DIR = path.join(os.homedir(), '.glad', 'logs');
|
|
7
|
-
const LOG_FILE = path.join(LOG_DIR, 'cli.log');
|
|
8
|
-
|
|
9
|
-
// Ensure log directory exists
|
|
10
|
-
function ensureLogDir() {
|
|
11
|
-
if (!fs.existsSync(LOG_DIR)) {
|
|
12
|
-
fs.mkdirSync(LOG_DIR, { recursive: true });
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Format timestamp
|
|
17
|
-
function timestamp() {
|
|
18
|
-
return new Date().toISOString().replace('T', ' ').substring(0, 19);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Write to log file
|
|
22
|
-
function writeToFile(level, message) {
|
|
23
|
-
try {
|
|
24
|
-
ensureLogDir();
|
|
25
|
-
const entry = `[${timestamp()}] ${level}: ${message}\n`;
|
|
26
|
-
fs.appendFileSync(LOG_FILE, entry);
|
|
27
|
-
} catch (err) {
|
|
28
|
-
// Silently fail if can't write to log
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const logger = {
|
|
33
|
-
debug: (message) => {
|
|
34
|
-
// Only log to console and file when DEBUG mode is enabled
|
|
35
|
-
if (process.env.DEBUG === '1' || process.argv.includes('--debug')) {
|
|
36
|
-
console.log(chalk.gray(`[DEBUG] ${message}`));
|
|
37
|
-
writeToFile('DEBUG', message);
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
// Always write to file, but only show on console in DEBUG mode
|
|
42
|
-
debugInfo: (message) => {
|
|
43
|
-
writeToFile('INFO', message);
|
|
44
|
-
if (process.env.DEBUG === '1' || process.argv.includes('--debug')) {
|
|
45
|
-
console.log(chalk.gray(`[DEBUG] ${message}`));
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
info: (message) => {
|
|
50
|
-
console.log(chalk.blue(`ℹ ${message}`));
|
|
51
|
-
writeToFile('INFO', message);
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
success: (message) => {
|
|
55
|
-
console.log(chalk.green(`✓ ${message}`));
|
|
56
|
-
writeToFile('INFO', message);
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
warn: (message) => {
|
|
60
|
-
console.log(chalk.yellow(`⚠️ ${message}`));
|
|
61
|
-
writeToFile('WARN', message);
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
error: (message) => {
|
|
65
|
-
console.error(chalk.red(`❌ ${message}`));
|
|
66
|
-
writeToFile('ERROR', message);
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
log: (message) => {
|
|
70
|
-
console.log(message);
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
module.exports = logger;
|
package/lib/utils/pid.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
// Check if process with PID exists
|
|
2
|
-
function isPidAlive(pid) {
|
|
3
|
-
if (!pid || typeof pid !== 'number') {
|
|
4
|
-
return false;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
// Signal 0 checks if process exists without sending actual signal
|
|
9
|
-
process.kill(pid, 0);
|
|
10
|
-
return true;
|
|
11
|
-
} catch (err) {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Kill process by PID
|
|
17
|
-
function killProcess(pid, signal = 'SIGTERM') {
|
|
18
|
-
if (!pid || typeof pid !== 'number') {
|
|
19
|
-
throw new Error('Invalid PID');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
process.kill(pid, signal);
|
|
24
|
-
return true;
|
|
25
|
-
} catch (err) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Kill process gracefully with timeout
|
|
31
|
-
async function killProcessGracefully(pid, timeout = 5000) {
|
|
32
|
-
if (!isPidAlive(pid)) {
|
|
33
|
-
return { success: true, method: 'already_dead' };
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Send SIGTERM
|
|
37
|
-
killProcess(pid, 'SIGTERM');
|
|
38
|
-
|
|
39
|
-
// Wait for process to exit
|
|
40
|
-
const startTime = Date.now();
|
|
41
|
-
while (Date.now() - startTime < timeout) {
|
|
42
|
-
if (!isPidAlive(pid)) {
|
|
43
|
-
return { success: true, method: 'SIGTERM' };
|
|
44
|
-
}
|
|
45
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Force kill if still alive
|
|
49
|
-
if (isPidAlive(pid)) {
|
|
50
|
-
killProcess(pid, 'SIGKILL');
|
|
51
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
52
|
-
|
|
53
|
-
if (!isPidAlive(pid)) {
|
|
54
|
-
return { success: true, method: 'SIGKILL' };
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return { success: false, method: 'failed' };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return { success: true, method: 'SIGTERM' };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
module.exports = {
|
|
64
|
-
isPidAlive,
|
|
65
|
-
killProcess,
|
|
66
|
-
killProcessGracefully
|
|
67
|
-
};
|
package/lib/utils/validation.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
// Validate directory exists
|
|
5
|
-
function validateDirectory(dirPath) {
|
|
6
|
-
if (!dirPath) {
|
|
7
|
-
return { valid: false, error: 'Directory path is required' };
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const resolvedPath = path.resolve(dirPath);
|
|
11
|
-
|
|
12
|
-
if (!fs.existsSync(resolvedPath)) {
|
|
13
|
-
return {
|
|
14
|
-
valid: false,
|
|
15
|
-
error: `Directory does not exist: ${resolvedPath}`
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const stats = fs.statSync(resolvedPath);
|
|
20
|
-
if (!stats.isDirectory()) {
|
|
21
|
-
return {
|
|
22
|
-
valid: false,
|
|
23
|
-
error: `Path is not a directory: ${resolvedPath}`
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return { valid: true, path: resolvedPath };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Validate URL
|
|
31
|
-
function validateUrl(url) {
|
|
32
|
-
try {
|
|
33
|
-
new URL(url);
|
|
34
|
-
return true;
|
|
35
|
-
} catch {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Validate session ID format
|
|
41
|
-
function validateSessionId(sessionId) {
|
|
42
|
-
if (!sessionId || typeof sessionId !== 'string') {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
// UUID format
|
|
46
|
-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(sessionId);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
module.exports = {
|
|
50
|
-
validateDirectory,
|
|
51
|
-
validateUrl,
|
|
52
|
-
validateSessionId
|
|
53
|
-
};
|
package/lib/web/bootstrap.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
(() => {
|
|
2
|
-
const splitQuery = '(min-width: 920px)';
|
|
3
|
-
const sidebarStorageKey = 'glad-sidebar-width';
|
|
4
|
-
|
|
5
|
-
function clampSidebarWidth(value) {
|
|
6
|
-
const max = Math.max(300, Math.min(480, window.innerWidth - 484));
|
|
7
|
-
return Math.min(max, Math.max(300, Number(value) || 348));
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function applySidebarWidth(value) {
|
|
11
|
-
const width = clampSidebarWidth(value);
|
|
12
|
-
document.documentElement.style.setProperty('--sidebar-w', `${width}px`);
|
|
13
|
-
return width;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
window.gladLayout = Object.freeze({
|
|
17
|
-
splitQuery,
|
|
18
|
-
sidebarStorageKey,
|
|
19
|
-
clampSidebarWidth,
|
|
20
|
-
applySidebarWidth
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const storedTheme = localStorage.getItem('glad-theme');
|
|
24
|
-
const theme = storedTheme === 'light' || storedTheme === 'dark'
|
|
25
|
-
? storedTheme
|
|
26
|
-
: (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
|
27
|
-
document.documentElement.dataset.theme = theme;
|
|
28
|
-
document.documentElement.style.backgroundColor = theme === 'dark' ? '#000000' : '#f5f6f8';
|
|
29
|
-
|
|
30
|
-
const storedSidebarWidth = Number(localStorage.getItem(sidebarStorageKey));
|
|
31
|
-
if (Number.isFinite(storedSidebarWidth) && storedSidebarWidth > 0) {
|
|
32
|
-
applySidebarWidth(storedSidebarWidth);
|
|
33
|
-
}
|
|
34
|
-
})();
|