dashcam 1.0.1-beta.5 → 1.0.1-beta.7
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/BACKWARD_COMPATIBILITY.md +177 -0
- package/bin/dashcam-background.js +177 -0
- package/bin/dashcam.js +265 -139
- package/lib/logs/index.js +67 -11
- package/lib/processManager.js +61 -33
- package/lib/recorder.js +20 -5
- package/lib/tracking/FileTracker.js +7 -0
- package/lib/tracking/LogsTracker.js +21 -7
- package/lib/uploader.js +7 -4
- package/package.json +4 -1
- package/test_workflow.sh +99 -25
- package/.github/workflows/build.yml +0 -103
- package/.github/workflows/release.yml +0 -107
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Backward Compatibility Summary
|
|
2
|
+
|
|
3
|
+
This document confirms that `dashcam-cli-minimal` now supports all commands and arguments documented in the README.md.
|
|
4
|
+
|
|
5
|
+
## ✅ Implemented Commands
|
|
6
|
+
|
|
7
|
+
### `auth <api-key>`
|
|
8
|
+
Authenticate the dashcam desktop using a team's apiKey.
|
|
9
|
+
```bash
|
|
10
|
+
dashcam auth <api-key>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### `create [options]`
|
|
14
|
+
Create a clip from current recording and output the resulting url or markdown. This stops the current recording and uploads it.
|
|
15
|
+
```bash
|
|
16
|
+
# Start instant replay in background
|
|
17
|
+
dashcam start
|
|
18
|
+
|
|
19
|
+
# Later, create a clip from the recording
|
|
20
|
+
dashcam create
|
|
21
|
+
dashcam create -t "My New Title"
|
|
22
|
+
dashcam create --md
|
|
23
|
+
dashcam create -k wef8we72h23012j
|
|
24
|
+
dashcam create -d "Description text"
|
|
25
|
+
cat README.md | dashcam create
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Options:
|
|
29
|
+
- `-t, --title <string>` - Title of the replay
|
|
30
|
+
- `-d, --description [text]` - Replay markdown body (supports piped input)
|
|
31
|
+
- `--md` - Returns rich markdown image link
|
|
32
|
+
- `-k, --project <project>` - Project ID to publish to
|
|
33
|
+
|
|
34
|
+
**Note:** `create` stops the current recording and creates a clip. It's similar to `stop` but focused on outputting URLs/markdown for integration with other tools.
|
|
35
|
+
|
|
36
|
+
### `record [options]`
|
|
37
|
+
Start a recording terminal to be included in your dashcam video recording.
|
|
38
|
+
```bash
|
|
39
|
+
dashcam record
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Options:
|
|
43
|
+
- `-t, --title <title>` - Title for the recording
|
|
44
|
+
- `-d, --description <description>` - Description for the recording
|
|
45
|
+
- `-p, --project <project>` - Project ID to upload to
|
|
46
|
+
- `-a, --audio` - Include audio
|
|
47
|
+
- `-f, --fps <fps>` - Frames per second
|
|
48
|
+
|
|
49
|
+
### `pipe`
|
|
50
|
+
Pipe command output to dashcam to be included in recorded video.
|
|
51
|
+
```bash
|
|
52
|
+
ping 1.1.1.1 | dashcam pipe
|
|
53
|
+
cat /var/log/system.log | dashcam pipe
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### `track [options]`
|
|
57
|
+
Add a logs config to Dashcam.
|
|
58
|
+
|
|
59
|
+
**New Syntax (matches README):**
|
|
60
|
+
```bash
|
|
61
|
+
dashcam track --name=social --type=web --pattern="*facebook.com*" --pattern="*twitter.com*"
|
|
62
|
+
dashcam track --name=app-logs --type=application --pattern="/var/log/*.log"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Old Syntax (still supported):**
|
|
66
|
+
```bash
|
|
67
|
+
dashcam track --web "*facebook.com*"
|
|
68
|
+
dashcam track --app "/var/log/app.log"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Options:
|
|
72
|
+
- `--name <name>` - Name for the tracking configuration (required with new syntax)
|
|
73
|
+
- `--type <type>` - Type: "application" or "web" (required with new syntax)
|
|
74
|
+
- `--pattern <pattern>` - Pattern to track (can use multiple times)
|
|
75
|
+
- `--web <pattern>` - Web URL pattern (deprecated, use --type=web --pattern)
|
|
76
|
+
- `--app <pattern>` - Application file pattern (deprecated, use --type=application --pattern)
|
|
77
|
+
|
|
78
|
+
### `start`
|
|
79
|
+
Start instant replay recording on dashcam.
|
|
80
|
+
```bash
|
|
81
|
+
dashcam start
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `stop`
|
|
85
|
+
Stop the current recording and upload.
|
|
86
|
+
```bash
|
|
87
|
+
dashcam stop
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### `status`
|
|
91
|
+
Show current recording status.
|
|
92
|
+
```bash
|
|
93
|
+
dashcam status
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Examples from README
|
|
97
|
+
|
|
98
|
+
All examples from the README should now work:
|
|
99
|
+
|
|
100
|
+
### Basic usage
|
|
101
|
+
```bash
|
|
102
|
+
# Create a replay
|
|
103
|
+
dashcam create
|
|
104
|
+
# Returns: https://dashcam.io/replay/123?share=xyz
|
|
105
|
+
|
|
106
|
+
# With markdown output
|
|
107
|
+
dashcam create --md
|
|
108
|
+
|
|
109
|
+
# With title
|
|
110
|
+
dashcam create -t "My New Title"
|
|
111
|
+
|
|
112
|
+
# With project
|
|
113
|
+
dashcam create -k wef8we72h23012j
|
|
114
|
+
|
|
115
|
+
# Attach last 20 CLI commands
|
|
116
|
+
history -20 | dashcam create
|
|
117
|
+
|
|
118
|
+
# Attach a logfile
|
|
119
|
+
cat /var/log/system.log | dashcam create
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Tracking logs
|
|
123
|
+
```bash
|
|
124
|
+
# Track web URLs
|
|
125
|
+
dashcam track --name=social --type=web --pattern="*facebook.com*" --pattern="*twitter.com*"
|
|
126
|
+
|
|
127
|
+
# Track application files
|
|
128
|
+
dashcam track --name=app-logs --type=application --pattern="/var/log/*.log"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Recording
|
|
132
|
+
```bash
|
|
133
|
+
# Start recording
|
|
134
|
+
dashcam record
|
|
135
|
+
|
|
136
|
+
# Pipe output into recording
|
|
137
|
+
ping 1.1.1.1 | dashcam pipe
|
|
138
|
+
|
|
139
|
+
# Stop recording
|
|
140
|
+
dashcam stop
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### GitHub CLI integration
|
|
144
|
+
```bash
|
|
145
|
+
# Create GitHub issue with replay
|
|
146
|
+
gh issue create -w -t "Title" -b "`dashcam create --md`"
|
|
147
|
+
|
|
148
|
+
# With system logs
|
|
149
|
+
gh issue create -w -t "Title" -b "`cat /var/log/system.log | dashcam create --md`"
|
|
150
|
+
|
|
151
|
+
# Create PR with replay
|
|
152
|
+
gh pr create -w -t "Title" -b "`dashcam create --md`"
|
|
153
|
+
|
|
154
|
+
# Append to commit
|
|
155
|
+
git commit -am "`dashcam create`"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Key Changes for Backward Compatibility
|
|
159
|
+
|
|
160
|
+
1. **Added `create` command** - Stops current recording and creates a clip with URL/markdown output
|
|
161
|
+
2. **Added `pipe` command** - Allows piping command output into recordings
|
|
162
|
+
3. **Added `start` command** - Simple way to start instant replay recording in background
|
|
163
|
+
4. **Updated `track` command** - Now supports both old syntax (--web, --app) and new syntax (--name, --type, --pattern)
|
|
164
|
+
5. **Updated descriptions** - Match README text exactly
|
|
165
|
+
6. **Updated `auth` parameter** - Changed from `<apiKey>` to `<api-key>` to match README
|
|
166
|
+
7. **Added `-k` alias** - For `--project` option in `create` command
|
|
167
|
+
8. **Shared implementation** - `create`, `record`, and `start` share common code to avoid duplication
|
|
168
|
+
|
|
169
|
+
## Migration Notes
|
|
170
|
+
|
|
171
|
+
- **`start`** - Starts instant replay recording in background (like desktop app's always-on recording)
|
|
172
|
+
- **`create`** - Stops the current recording and outputs URL/markdown (perfect for CI/CD, git hooks, GitHub CLI)
|
|
173
|
+
- **`record`** - Full-featured recording command with all options (terminal recording mode)
|
|
174
|
+
- **`stop`** - Similar to `create` but focused on stopping and uploading vs URL output
|
|
175
|
+
- Old `track` syntax still works for backward compatibility but new syntax is preferred
|
|
176
|
+
- All piped input examples from README are supported
|
|
177
|
+
- Can run just `dashcam` with options (defaults to `create` command)
|
|
@@ -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
|
+
});
|