dashcam 0.8.4 → 1.0.1-beta.11
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/.dashcam/cli-config.json +3 -0
- package/.dashcam/recording.log +135 -0
- package/.dashcam/web-config.json +11 -0
- package/.github/RELEASE.md +59 -0
- package/.github/workflows/publish.yml +43 -0
- package/BACKWARD_COMPATIBILITY.md +177 -0
- package/LOG_TRACKING_GUIDE.md +225 -0
- package/README.md +709 -155
- package/bin/dashcam-background.js +177 -0
- package/bin/dashcam.cjs +8 -0
- package/bin/dashcam.js +703 -0
- package/bin/index.js +63 -0
- package/examples/execute-script.js +152 -0
- package/examples/simple-test.js +37 -0
- package/lib/applicationTracker.js +311 -0
- package/lib/auth.js +222 -0
- package/lib/binaries.js +21 -0
- package/lib/config.js +34 -0
- package/lib/extension-logs/helpers.js +182 -0
- package/lib/extension-logs/index.js +347 -0
- package/lib/extension-logs/manager.js +344 -0
- package/lib/ffmpeg.js +155 -0
- package/lib/logTracker.js +23 -0
- package/lib/logger.js +118 -0
- package/lib/logs/index.js +488 -0
- package/lib/permissions.js +85 -0
- package/lib/processManager.js +317 -0
- package/lib/recorder.js +690 -0
- package/lib/store.js +58 -0
- package/lib/tracking/FileTracker.js +105 -0
- package/lib/tracking/FileTrackerManager.js +62 -0
- package/lib/tracking/LogsTracker.js +161 -0
- package/lib/tracking/active-win.js +212 -0
- package/lib/tracking/icons/darwin.js +39 -0
- package/lib/tracking/icons/index.js +167 -0
- package/lib/tracking/icons/windows.js +27 -0
- package/lib/tracking/idle.js +82 -0
- package/lib/tracking.js +23 -0
- package/lib/uploader.js +456 -0
- package/lib/utilities/jsonl.js +77 -0
- package/lib/webLogsDaemon.js +234 -0
- package/lib/websocket/server.js +223 -0
- package/package.json +53 -21
- package/recording.log +814 -0
- package/sea-bundle.mjs +34595 -0
- package/test-page.html +15 -0
- package/test.log +1 -0
- package/test_run.log +48 -0
- package/test_workflow.sh +154 -0
- package/examples/crash-test.js +0 -11
- package/examples/github-issue.sh +0 -1
- package/examples/protocol.html +0 -22
- package/index.js +0 -158
- package/lib.js +0 -199
- package/recorder.js +0 -85
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Background recording process for dashcam CLI
|
|
4
|
+
* This script runs detached from the parent process to handle long-running recordings
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { startRecording, stopRecording } from '../lib/recorder.js';
|
|
8
|
+
import { upload } from '../lib/uploader.js';
|
|
9
|
+
import { logger, setVerbose } from '../lib/logger.js';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import os from 'os';
|
|
13
|
+
|
|
14
|
+
// Get process directory for status files
|
|
15
|
+
const PROCESS_DIR = path.join(os.homedir(), '.dashcam-cli');
|
|
16
|
+
const STATUS_FILE = path.join(PROCESS_DIR, 'status.json');
|
|
17
|
+
const RESULT_FILE = path.join(PROCESS_DIR, 'upload-result.json');
|
|
18
|
+
|
|
19
|
+
// Parse options from command line argument
|
|
20
|
+
const optionsJson = process.argv[2];
|
|
21
|
+
if (!optionsJson) {
|
|
22
|
+
console.error('No options provided to background process');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const options = JSON.parse(optionsJson);
|
|
27
|
+
|
|
28
|
+
// Enable verbose logging in background
|
|
29
|
+
setVerbose(true);
|
|
30
|
+
|
|
31
|
+
logger.info('Background recording process started', {
|
|
32
|
+
pid: process.pid,
|
|
33
|
+
options
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Write status file
|
|
37
|
+
function writeStatus(status) {
|
|
38
|
+
try {
|
|
39
|
+
fs.writeFileSync(STATUS_FILE, JSON.stringify({
|
|
40
|
+
...status,
|
|
41
|
+
timestamp: Date.now(),
|
|
42
|
+
pid: process.pid
|
|
43
|
+
}, null, 2));
|
|
44
|
+
} catch (error) {
|
|
45
|
+
logger.error('Failed to write status file', { error });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Write upload result file
|
|
50
|
+
function writeUploadResult(result) {
|
|
51
|
+
try {
|
|
52
|
+
logger.info('Writing upload result to file', { path: RESULT_FILE, shareLink: result.shareLink });
|
|
53
|
+
fs.writeFileSync(RESULT_FILE, JSON.stringify({
|
|
54
|
+
...result,
|
|
55
|
+
timestamp: Date.now()
|
|
56
|
+
}, null, 2));
|
|
57
|
+
logger.info('Successfully wrote upload result to file');
|
|
58
|
+
} catch (error) {
|
|
59
|
+
logger.error('Failed to write upload result file', { error });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Main recording function
|
|
64
|
+
async function runBackgroundRecording() {
|
|
65
|
+
let recordingResult = null;
|
|
66
|
+
let isShuttingDown = false;
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
// Start the recording
|
|
70
|
+
const recordingOptions = {
|
|
71
|
+
fps: parseInt(options.fps) || 10,
|
|
72
|
+
includeAudio: options.audio || false,
|
|
73
|
+
customOutputPath: options.output || null
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
logger.info('Starting recording with options', { recordingOptions });
|
|
77
|
+
|
|
78
|
+
recordingResult = await startRecording(recordingOptions);
|
|
79
|
+
|
|
80
|
+
// Write status to track the recording
|
|
81
|
+
writeStatus({
|
|
82
|
+
isRecording: true,
|
|
83
|
+
startTime: recordingResult.startTime,
|
|
84
|
+
options,
|
|
85
|
+
pid: process.pid,
|
|
86
|
+
outputPath: recordingResult.outputPath
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
logger.info('Recording started successfully', {
|
|
90
|
+
outputPath: recordingResult.outputPath,
|
|
91
|
+
startTime: recordingResult.startTime
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Set up signal handlers for graceful shutdown
|
|
95
|
+
const handleShutdown = async (signal) => {
|
|
96
|
+
if (isShuttingDown) {
|
|
97
|
+
logger.info('Shutdown already in progress...');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
isShuttingDown = true;
|
|
101
|
+
|
|
102
|
+
logger.info(`Received ${signal}, stopping background recording...`);
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
// Stop the recording
|
|
106
|
+
const stopResult = await stopRecording();
|
|
107
|
+
|
|
108
|
+
if (stopResult) {
|
|
109
|
+
logger.info('Recording stopped successfully', {
|
|
110
|
+
outputPath: stopResult.outputPath,
|
|
111
|
+
duration: stopResult.duration
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Upload the recording
|
|
115
|
+
logger.info('Starting upload...');
|
|
116
|
+
const uploadResult = await upload(stopResult.outputPath, {
|
|
117
|
+
title: options.title || 'Dashcam Recording',
|
|
118
|
+
description: options.description || 'Recorded with Dashcam CLI',
|
|
119
|
+
project: options.project || options.k,
|
|
120
|
+
duration: stopResult.duration,
|
|
121
|
+
clientStartDate: stopResult.clientStartDate,
|
|
122
|
+
apps: stopResult.apps,
|
|
123
|
+
logs: stopResult.logs,
|
|
124
|
+
gifPath: stopResult.gifPath,
|
|
125
|
+
snapshotPath: stopResult.snapshotPath
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
logger.info('Upload complete', { shareLink: uploadResult.shareLink });
|
|
129
|
+
|
|
130
|
+
// Write upload result for stop command to read
|
|
131
|
+
writeUploadResult({
|
|
132
|
+
shareLink: uploadResult.shareLink,
|
|
133
|
+
replayId: uploadResult.replay?.id
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Update status to indicate recording stopped
|
|
138
|
+
writeStatus({
|
|
139
|
+
isRecording: false,
|
|
140
|
+
completedTime: Date.now(),
|
|
141
|
+
pid: process.pid
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
logger.info('Background process exiting successfully');
|
|
145
|
+
process.exit(0);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
logger.error('Error during shutdown:', error);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
process.on('SIGINT', () => handleShutdown('SIGINT'));
|
|
153
|
+
process.on('SIGTERM', () => handleShutdown('SIGTERM'));
|
|
154
|
+
|
|
155
|
+
// Keep the process alive
|
|
156
|
+
logger.info('Background recording is now running. Waiting for stop signal...');
|
|
157
|
+
await new Promise(() => {}); // Wait indefinitely for signals
|
|
158
|
+
|
|
159
|
+
} catch (error) {
|
|
160
|
+
logger.error('Background recording failed:', error);
|
|
161
|
+
|
|
162
|
+
// Update status to indicate failure
|
|
163
|
+
writeStatus({
|
|
164
|
+
isRecording: false,
|
|
165
|
+
error: error.message,
|
|
166
|
+
pid: process.pid
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Run the background recording
|
|
174
|
+
runBackgroundRecording().catch(error => {
|
|
175
|
+
logger.error('Fatal error in background process:', error);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
});
|