recoder-code 2.5.2 → 2.5.3
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/index.js +0 -0
- package/dist/src/commands/context/index.js +2 -2
- package/dist/src/commands/mcp/marketplace.d.ts +6 -0
- package/dist/src/commands/mcp/marketplace.js +448 -0
- package/dist/src/commands/mcp.js +2 -0
- package/dist/src/commands/parallel.d.ts +20 -0
- package/dist/src/commands/parallel.js +133 -0
- package/dist/src/commands/recoderWeb.js +184 -5
- package/dist/src/commands/web/diff.d.ts +13 -0
- package/dist/src/commands/web/diff.js +235 -0
- package/dist/src/commands/web/link.d.ts +11 -0
- package/dist/src/commands/web/link.js +96 -0
- package/dist/src/commands/web/pull.d.ts +13 -0
- package/dist/src/commands/web/pull.js +203 -0
- package/dist/src/commands/web/status.d.ts +10 -0
- package/dist/src/commands/web/status.js +104 -0
- package/dist/src/commands/web/unlink.d.ts +10 -0
- package/dist/src/commands/web/unlink.js +45 -0
- package/dist/src/commands/web/watch.d.ts +14 -0
- package/dist/src/commands/web/watch.js +360 -0
- package/dist/src/commands/web.js +12 -0
- package/dist/src/config/config.js +6 -2
- package/dist/src/config/defaultMcpServers.d.ts +1 -0
- package/dist/src/config/defaultMcpServers.js +46 -0
- package/dist/src/gemini.js +10 -0
- package/dist/src/parallel/git-utils.d.ts +42 -0
- package/dist/src/parallel/git-utils.js +161 -0
- package/dist/src/parallel/index.d.ts +14 -0
- package/dist/src/parallel/index.js +14 -0
- package/dist/src/parallel/parallel-mode.d.ts +48 -0
- package/dist/src/parallel/parallel-mode.js +224 -0
- package/dist/src/services/AgentBridgeService.d.ts +61 -0
- package/dist/src/services/AgentBridgeService.js +253 -0
- package/dist/src/services/BuiltinCommandLoader.js +7 -0
- package/dist/src/services/PlatformSyncService.d.ts +154 -0
- package/dist/src/services/PlatformSyncService.js +588 -0
- package/dist/src/ui/commands/workflowCommands.d.ts +16 -0
- package/dist/src/ui/commands/workflowCommands.js +291 -0
- package/dist/src/ui/commands/workspaceCommand.d.ts +11 -0
- package/dist/src/ui/commands/workspaceCommand.js +329 -0
- package/dist/src/zed-integration/schema.d.ts +30 -30
- package/package.json +29 -10
- package/src/postinstall.cjs +3 -2
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 'recoder web pull' command
|
|
3
|
+
* Pull web project files to local directory
|
|
4
|
+
*/
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import { RecoderWebService } from '../../services/RecoderWebService.js';
|
|
8
|
+
import { RecoderAuthService } from '../../services/RecoderAuthService.js';
|
|
9
|
+
const DOCKER_BACKEND_URL = process.env['RECODER_DOCKER_URL'] || 'https://docker.recoder.xyz';
|
|
10
|
+
export const pullCommand = {
|
|
11
|
+
command: 'pull [urlId]',
|
|
12
|
+
describe: 'Pull web project files to local directory',
|
|
13
|
+
builder: (yargs) => yargs
|
|
14
|
+
.positional('urlId', {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Project URL ID (optional, will read from .recoder-web if present)',
|
|
17
|
+
})
|
|
18
|
+
.option('directory', {
|
|
19
|
+
type: 'string',
|
|
20
|
+
alias: 'd',
|
|
21
|
+
description: 'Directory to pull to (defaults to current directory)',
|
|
22
|
+
default: process.cwd(),
|
|
23
|
+
})
|
|
24
|
+
.option('dry-run', {
|
|
25
|
+
type: 'boolean',
|
|
26
|
+
description: 'Show what would be pulled without actually pulling',
|
|
27
|
+
default: false,
|
|
28
|
+
})
|
|
29
|
+
.option('force', {
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
alias: 'f',
|
|
32
|
+
description: 'Overwrite local files without prompting',
|
|
33
|
+
default: false,
|
|
34
|
+
}),
|
|
35
|
+
handler: async (argv) => {
|
|
36
|
+
const webService = new RecoderWebService();
|
|
37
|
+
const authService = new RecoderAuthService();
|
|
38
|
+
try {
|
|
39
|
+
// Check authentication
|
|
40
|
+
const isAuth = await authService.isAuthenticated();
|
|
41
|
+
if (!isAuth) {
|
|
42
|
+
console.error('Not authenticated');
|
|
43
|
+
console.log('Run: recoder auth login');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
const targetDir = path.resolve(argv.directory || process.cwd());
|
|
47
|
+
let urlId = argv.urlId;
|
|
48
|
+
// Try to read .recoder-web metadata if no urlId provided
|
|
49
|
+
if (!urlId) {
|
|
50
|
+
try {
|
|
51
|
+
const metadataPath = path.join(targetDir, '.recoder-web');
|
|
52
|
+
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
|
|
53
|
+
urlId = metadata.urlId || metadata.projectId;
|
|
54
|
+
console.log(`Found project ID from .recoder-web: ${urlId}`);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
console.error('No project ID provided and no .recoder-web file found');
|
|
58
|
+
console.log('Usage: recoder web pull <urlId>');
|
|
59
|
+
console.log(' Or run from a linked directory');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
console.log(`Pulling project: ${urlId}`);
|
|
64
|
+
console.log(`Local directory: ${targetDir}\n`);
|
|
65
|
+
// Get token for backend request
|
|
66
|
+
const token = await authService.getAccessToken();
|
|
67
|
+
if (!token) {
|
|
68
|
+
console.error('Failed to get access token');
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
// Try to pull from docker backend first (for running containers)
|
|
72
|
+
let remoteFiles = {};
|
|
73
|
+
let pullSource = 'web';
|
|
74
|
+
try {
|
|
75
|
+
console.log('Checking docker backend for running container...');
|
|
76
|
+
const response = await fetch(`${DOCKER_BACKEND_URL}/api/sync/${urlId}/pull`, {
|
|
77
|
+
headers: {
|
|
78
|
+
'Authorization': `Bearer ${token}`,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
if (response.ok) {
|
|
82
|
+
const data = await response.json();
|
|
83
|
+
if (data.success && data.files) {
|
|
84
|
+
remoteFiles = data.files;
|
|
85
|
+
pullSource = 'docker';
|
|
86
|
+
console.log(`Found running container with ${data.fileCount} files`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Docker backend not available, fall back to web API
|
|
92
|
+
}
|
|
93
|
+
// Fall back to web API if docker backend didn't work
|
|
94
|
+
if (Object.keys(remoteFiles).length === 0) {
|
|
95
|
+
console.log('Fetching from web API...');
|
|
96
|
+
try {
|
|
97
|
+
const project = await webService.getProject(urlId);
|
|
98
|
+
remoteFiles = project.fileSnapshot || {};
|
|
99
|
+
console.log(`Found ${Object.keys(remoteFiles).length} files in web snapshot`);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.error(`Failed to fetch project: ${error.message}`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (Object.keys(remoteFiles).length === 0) {
|
|
107
|
+
console.log('\nNo files found in project');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// Scan local files
|
|
111
|
+
console.log('\nScanning local directory...');
|
|
112
|
+
const localFiles = await webService.scanDirectory(targetDir);
|
|
113
|
+
// Detect changes (from remote perspective - what needs to come down)
|
|
114
|
+
const changes = await webService.detectChanges(localFiles, remoteFiles);
|
|
115
|
+
// Files to download: files in remote but not in local, or modified
|
|
116
|
+
const toDownload = [...changes.deleted, ...changes.modified];
|
|
117
|
+
// Files to add: files in local but not in remote - we don't touch these during pull
|
|
118
|
+
// Files to delete: none during pull unless --force
|
|
119
|
+
console.log('\nPull Analysis:');
|
|
120
|
+
console.log('-'.repeat(60));
|
|
121
|
+
if (changes.deleted.length > 0) {
|
|
122
|
+
console.log(`\nNew files to download (${changes.deleted.length}):`);
|
|
123
|
+
changes.deleted.slice(0, 15).forEach((file) => console.log(` + ${file}`));
|
|
124
|
+
if (changes.deleted.length > 15) {
|
|
125
|
+
console.log(` ... and ${changes.deleted.length - 15} more`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (changes.modified.length > 0) {
|
|
129
|
+
console.log(`\nFiles to update (${changes.modified.length}):`);
|
|
130
|
+
changes.modified.slice(0, 15).forEach((file) => console.log(` ~ ${file}`));
|
|
131
|
+
if (changes.modified.length > 15) {
|
|
132
|
+
console.log(` ... and ${changes.modified.length - 15} more`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (changes.added.length > 0) {
|
|
136
|
+
console.log(`\nLocal-only files (${changes.added.length}):`);
|
|
137
|
+
changes.added.slice(0, 10).forEach((file) => console.log(` * ${file} (kept)`));
|
|
138
|
+
if (changes.added.length > 10) {
|
|
139
|
+
console.log(` ... and ${changes.added.length - 10} more`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const hasChanges = toDownload.length > 0;
|
|
143
|
+
if (!hasChanges) {
|
|
144
|
+
console.log('\nLocal directory is up to date with remote!');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// Dry run mode
|
|
148
|
+
if (argv['dry-run']) {
|
|
149
|
+
console.log('\nDry run mode - no files were downloaded');
|
|
150
|
+
console.log('Remove --dry-run to actually pull');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
// Check for conflicts if not forcing
|
|
154
|
+
if (!argv.force && changes.modified.length > 0) {
|
|
155
|
+
console.log('\nModified files will be overwritten.');
|
|
156
|
+
console.log('Use --force to proceed or --dry-run to see what would change.');
|
|
157
|
+
// In a real CLI we'd prompt, but for simplicity we'll just warn
|
|
158
|
+
console.log('\nProceeding with pull...');
|
|
159
|
+
}
|
|
160
|
+
// Download files
|
|
161
|
+
console.log('\nDownloading files...');
|
|
162
|
+
let downloaded = 0;
|
|
163
|
+
for (const filePath of toDownload) {
|
|
164
|
+
const content = remoteFiles[filePath];
|
|
165
|
+
if (content === undefined)
|
|
166
|
+
continue;
|
|
167
|
+
const fullPath = path.join(targetDir, filePath);
|
|
168
|
+
const fileDir = path.dirname(fullPath);
|
|
169
|
+
try {
|
|
170
|
+
await fs.mkdir(fileDir, { recursive: true });
|
|
171
|
+
await fs.writeFile(fullPath, content, 'utf-8');
|
|
172
|
+
downloaded++;
|
|
173
|
+
console.log(` Downloaded: ${filePath}`);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
console.error(` Failed: ${filePath} - ${error.message}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Update metadata
|
|
180
|
+
const metadataFile = path.join(targetDir, '.recoder-web');
|
|
181
|
+
try {
|
|
182
|
+
let metadata = {};
|
|
183
|
+
try {
|
|
184
|
+
metadata = JSON.parse(await fs.readFile(metadataFile, 'utf-8'));
|
|
185
|
+
}
|
|
186
|
+
catch { /* file doesn't exist */ }
|
|
187
|
+
metadata.urlId = urlId;
|
|
188
|
+
metadata.lastPull = new Date().toISOString();
|
|
189
|
+
metadata.pullSource = pullSource;
|
|
190
|
+
metadata.webUrl = webService.getProjectUrl(urlId);
|
|
191
|
+
await fs.writeFile(metadataFile, JSON.stringify(metadata, null, 2), 'utf-8');
|
|
192
|
+
}
|
|
193
|
+
catch { /* ignore metadata errors */ }
|
|
194
|
+
console.log(`\nPull complete!`);
|
|
195
|
+
console.log(`Downloaded ${downloaded} files from ${pullSource}`);
|
|
196
|
+
console.log(`View at: ${webService.getProjectUrl(urlId)}`);
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
console.error(`${error.message}`);
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 'recoder web status' command
|
|
3
|
+
* Show current project link and sync status
|
|
4
|
+
*/
|
|
5
|
+
import type { CommandModule } from 'yargs';
|
|
6
|
+
interface StatusArgs {
|
|
7
|
+
directory?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const statusCommand: CommandModule<{}, StatusArgs>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 'recoder web status' command
|
|
3
|
+
* Show current project link and sync status
|
|
4
|
+
*/
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import { RecoderAuthService } from '../../services/RecoderAuthService.js';
|
|
8
|
+
import { RecoderWebService } from '../../services/RecoderWebService.js';
|
|
9
|
+
export const statusCommand = {
|
|
10
|
+
command: 'status',
|
|
11
|
+
describe: 'Show project link and sync status',
|
|
12
|
+
builder: (yargs) => yargs.option('directory', {
|
|
13
|
+
type: 'string',
|
|
14
|
+
alias: 'd',
|
|
15
|
+
description: 'Directory to check (defaults to current directory)',
|
|
16
|
+
default: process.cwd(),
|
|
17
|
+
}),
|
|
18
|
+
handler: async (argv) => {
|
|
19
|
+
const authService = new RecoderAuthService();
|
|
20
|
+
const webService = new RecoderWebService();
|
|
21
|
+
try {
|
|
22
|
+
const targetDir = path.resolve(argv.directory || process.cwd());
|
|
23
|
+
// Check authentication
|
|
24
|
+
const isAuth = await authService.isAuthenticated();
|
|
25
|
+
const user = isAuth ? await authService.getUser() : null;
|
|
26
|
+
// Check for project link
|
|
27
|
+
let metadata = null;
|
|
28
|
+
try {
|
|
29
|
+
const metadataPath = path.join(targetDir, '.recoder-web');
|
|
30
|
+
metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
console.log('\n┌────────────────────────────────────────────────┐');
|
|
34
|
+
console.log('│ 📊 Recoder Platform Status │');
|
|
35
|
+
console.log('├────────────────────────────────────────────────┤');
|
|
36
|
+
// Auth status
|
|
37
|
+
if (isAuth && user) {
|
|
38
|
+
console.log(`│ 👤 Account: ${user.email.slice(0, 32).padEnd(32)}│`);
|
|
39
|
+
console.log(`│ 📋 Plan: ${user.subscription_plan.toUpperCase().padEnd(35)}│`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
console.log('│ 👤 Account: Not logged in │');
|
|
43
|
+
console.log('│ 💡 Run: recoder auth login │');
|
|
44
|
+
}
|
|
45
|
+
console.log('├────────────────────────────────────────────────┤');
|
|
46
|
+
// Project link status
|
|
47
|
+
if (metadata?.urlId || metadata?.projectId) {
|
|
48
|
+
const projectId = metadata.urlId || metadata.projectId;
|
|
49
|
+
console.log(`│ 🔗 Linked: Yes │`);
|
|
50
|
+
console.log(`│ 📁 Project: ${projectId.slice(0, 32).padEnd(32)}│`);
|
|
51
|
+
if (metadata.linkedAt) {
|
|
52
|
+
const linkedDate = new Date(metadata.linkedAt).toLocaleDateString();
|
|
53
|
+
console.log(`│ 📅 Linked: ${linkedDate.padEnd(33)}│`);
|
|
54
|
+
}
|
|
55
|
+
if (metadata.lastSync) {
|
|
56
|
+
const syncDate = new Date(metadata.lastSync).toLocaleString();
|
|
57
|
+
console.log(`│ 🔄 Last sync: ${syncDate.slice(0, 30).padEnd(30)}│`);
|
|
58
|
+
}
|
|
59
|
+
console.log('├────────────────────────────────────────────────┤');
|
|
60
|
+
console.log(`│ 🌐 Web: ${(metadata.webUrl || '').slice(0, 36).padEnd(36)}│`);
|
|
61
|
+
console.log(`│ 👁️ Preview: ${(metadata.previewUrl || '').slice(0, 31).padEnd(31)}│`);
|
|
62
|
+
// Check for local changes
|
|
63
|
+
if (isAuth) {
|
|
64
|
+
try {
|
|
65
|
+
const project = await webService.getProject(projectId);
|
|
66
|
+
const localFiles = await webService.scanDirectory(targetDir);
|
|
67
|
+
const remoteFiles = project.fileSnapshot || {};
|
|
68
|
+
const changes = await webService.detectChanges(localFiles, remoteFiles);
|
|
69
|
+
const totalChanges = changes.added.length + changes.modified.length + changes.deleted.length;
|
|
70
|
+
console.log('├────────────────────────────────────────────────┤');
|
|
71
|
+
if (totalChanges === 0) {
|
|
72
|
+
console.log('│ ✅ Status: In sync │');
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.log(`│ ⚠️ Status: ${totalChanges} pending changes`.padEnd(47) + '│');
|
|
76
|
+
if (changes.added.length > 0) {
|
|
77
|
+
console.log(`│ + ${changes.added.length} new files`.padEnd(44) + '│');
|
|
78
|
+
}
|
|
79
|
+
if (changes.modified.length > 0) {
|
|
80
|
+
console.log(`│ ~ ${changes.modified.length} modified`.padEnd(44) + '│');
|
|
81
|
+
}
|
|
82
|
+
if (changes.deleted.length > 0) {
|
|
83
|
+
console.log(`│ - ${changes.deleted.length} deleted`.padEnd(44) + '│');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
console.log('├────────────────────────────────────────────────┤');
|
|
89
|
+
console.log('│ ⚠️ Could not fetch remote status │');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log('│ 🔗 Linked: No │');
|
|
95
|
+
console.log('│ 💡 Run: recoder web link <projectId> │');
|
|
96
|
+
}
|
|
97
|
+
console.log('└────────────────────────────────────────────────┘\n');
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error(`❌ ${error.message}`);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 'recoder web unlink' command
|
|
3
|
+
* Remove link between current directory and recoder.xyz project
|
|
4
|
+
*/
|
|
5
|
+
import type { CommandModule } from 'yargs';
|
|
6
|
+
interface UnlinkArgs {
|
|
7
|
+
directory?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const unlinkCommand: CommandModule<{}, UnlinkArgs>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 'recoder web unlink' command
|
|
3
|
+
* Remove link between current directory and recoder.xyz project
|
|
4
|
+
*/
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
export const unlinkCommand = {
|
|
8
|
+
command: 'unlink',
|
|
9
|
+
describe: 'Remove link to recoder.xyz project',
|
|
10
|
+
builder: (yargs) => yargs.option('directory', {
|
|
11
|
+
type: 'string',
|
|
12
|
+
alias: 'd',
|
|
13
|
+
description: 'Directory to unlink (defaults to current directory)',
|
|
14
|
+
default: process.cwd(),
|
|
15
|
+
}),
|
|
16
|
+
handler: async (argv) => {
|
|
17
|
+
try {
|
|
18
|
+
const targetDir = path.resolve(argv.directory || process.cwd());
|
|
19
|
+
const metadataFile = path.join(targetDir, '.recoder-web');
|
|
20
|
+
try {
|
|
21
|
+
await fs.access(metadataFile);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
console.log('📂 No project link found in this directory');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// Read metadata before deleting
|
|
28
|
+
let projectId = 'unknown';
|
|
29
|
+
try {
|
|
30
|
+
const metadata = JSON.parse(await fs.readFile(metadataFile, 'utf-8'));
|
|
31
|
+
projectId = metadata.urlId || metadata.projectId || 'unknown';
|
|
32
|
+
}
|
|
33
|
+
catch { }
|
|
34
|
+
await fs.unlink(metadataFile);
|
|
35
|
+
console.log('✅ Project unlinked successfully');
|
|
36
|
+
console.log(`📁 Directory: ${targetDir}`);
|
|
37
|
+
console.log(`🔗 Was linked to: ${projectId}`);
|
|
38
|
+
console.log('\n💡 Run "recoder web link <projectId>" to link again');
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error(`❌ ${error.message}`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 'recoder web watch' command
|
|
3
|
+
* Live sync - watch for local changes and sync to web in real-time
|
|
4
|
+
*/
|
|
5
|
+
import type { CommandModule } from 'yargs';
|
|
6
|
+
interface WatchArgs {
|
|
7
|
+
urlId?: string;
|
|
8
|
+
directory?: string;
|
|
9
|
+
'push-only'?: boolean;
|
|
10
|
+
'pull-only'?: boolean;
|
|
11
|
+
interval?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare const watchCommand: CommandModule<{}, WatchArgs>;
|
|
14
|
+
export {};
|