@mod-computer/cli 0.1.1 → 0.2.2
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 +98 -76
- package/dist/cli.bundle.js +23750 -12931
- package/dist/cli.bundle.js.map +4 -4
- package/dist/cli.js +23 -12
- package/dist/commands/add.js +245 -0
- package/dist/commands/auth.js +129 -21
- package/dist/commands/comment.js +568 -0
- package/dist/commands/diff.js +182 -0
- package/dist/commands/index.js +33 -3
- package/dist/commands/init.js +475 -221
- package/dist/commands/ls.js +135 -0
- package/dist/commands/members.js +687 -0
- package/dist/commands/mv.js +282 -0
- package/dist/commands/rm.js +257 -0
- package/dist/commands/status.js +273 -306
- package/dist/commands/sync.js +99 -75
- package/dist/commands/trace.js +1752 -0
- package/dist/commands/workspace.js +354 -330
- package/dist/config/features.js +18 -7
- package/dist/config/release-profiles/development.json +4 -1
- package/dist/config/release-profiles/mvp.json +4 -2
- package/dist/daemon/conflict-resolution.js +172 -0
- package/dist/daemon/content-hash.js +31 -0
- package/dist/daemon/file-sync.js +985 -0
- package/dist/daemon/index.js +203 -0
- package/dist/daemon/mime-types.js +166 -0
- package/dist/daemon/offline-queue.js +211 -0
- package/dist/daemon/path-utils.js +64 -0
- package/dist/daemon/share-policy.js +83 -0
- package/dist/daemon/wasm-errors.js +189 -0
- package/dist/daemon/worker.js +557 -0
- package/dist/daemon-worker.js +3 -2
- package/dist/errors/workspace-errors.js +48 -0
- package/dist/lib/auth-server.js +89 -26
- package/dist/lib/browser.js +1 -1
- package/dist/lib/diff.js +284 -0
- package/dist/lib/formatters.js +204 -0
- package/dist/lib/git.js +137 -0
- package/dist/lib/local-fs.js +201 -0
- package/dist/lib/prompts.js +23 -83
- package/dist/lib/storage.js +11 -1
- package/dist/lib/trace-formatters.js +314 -0
- package/dist/services/add-service.js +554 -0
- package/dist/services/add-validation.js +124 -0
- package/dist/services/mod-config.js +8 -2
- package/dist/services/modignore-service.js +2 -0
- package/dist/stores/use-workspaces-store.js +36 -14
- package/dist/types/add-types.js +99 -0
- package/dist/types/config.js +1 -1
- package/dist/types/workspace-connection.js +53 -2
- package/package.json +7 -5
- package/commands/execute.md +0 -156
- package/commands/overview.md +0 -233
- package/commands/review.md +0 -151
- package/commands/spec.md +0 -169
package/dist/commands/sync.js
CHANGED
|
@@ -1,95 +1,119 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
// glassware[type="implementation", id="cli-sync-command--4fa01713", requirements="requirement-cli-sync-ux-1a--55a635db,requirement-cli-sync-ux-1b--eedac360,requirement-cli-sync-ux-2--fe764dca,requirement-cli-sync-ux-3--fbb89737,requirement-cli-sync-ux-4a--f2e42b98,requirement-cli-sync-ux-4b--00ec3d9c,requirement-cli-sync-ux-5--480ee59f"]
|
|
2
|
+
import { startDaemon, stopDaemon, getDaemonStatus, } from '../daemon/index.js';
|
|
3
3
|
export async function syncCommand(args, repo) {
|
|
4
4
|
const command = args[0] || 'start';
|
|
5
|
-
const daemon = new SyncDaemon();
|
|
6
5
|
try {
|
|
7
6
|
switch (command) {
|
|
8
7
|
case 'start':
|
|
9
|
-
await
|
|
10
|
-
force: args.includes('--force'),
|
|
11
|
-
verbose: args.includes('--verbose')
|
|
12
|
-
});
|
|
8
|
+
await handleStart(args.includes('--verbose'));
|
|
13
9
|
break;
|
|
14
10
|
case 'stop':
|
|
15
|
-
await
|
|
16
|
-
force: args.includes('--force')
|
|
17
|
-
});
|
|
11
|
+
await handleStop(args.includes('--force'));
|
|
18
12
|
break;
|
|
19
13
|
case 'restart':
|
|
20
|
-
await
|
|
21
|
-
|
|
22
|
-
verbose: args.includes('--verbose')
|
|
23
|
-
});
|
|
14
|
+
await handleStop(args.includes('--force'));
|
|
15
|
+
await handleStart(args.includes('--verbose'));
|
|
24
16
|
break;
|
|
25
17
|
case 'status':
|
|
26
|
-
|
|
27
|
-
if (!status) {
|
|
28
|
-
console.log('❌ Daemon is not running');
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
console.log('📊 Sync Daemon Status:');
|
|
32
|
-
console.log(` Status: ${status.status}`);
|
|
33
|
-
console.log(` PID: ${status.pid}`);
|
|
34
|
-
console.log(` Started: ${new Date(status.startedAt).toLocaleString()}`);
|
|
35
|
-
console.log(` Last Activity: ${new Date(status.lastActivity).toLocaleString()}`);
|
|
36
|
-
console.log(` Workspace: ${status.workspaceId}${status.workspaceName ? ` (${status.workspaceName})` : ''}`);
|
|
37
|
-
if (status.activeBranchId) {
|
|
38
|
-
console.log(` Active Branch: ${status.activeBranchId}`);
|
|
39
|
-
}
|
|
40
|
-
console.log(` Watched Files: ${status.watchedFiles}`);
|
|
41
|
-
if (status.uptime) {
|
|
42
|
-
const uptimeSeconds = Math.floor(status.uptime / 1000);
|
|
43
|
-
const hours = Math.floor(uptimeSeconds / 3600);
|
|
44
|
-
const minutes = Math.floor((uptimeSeconds % 3600) / 60);
|
|
45
|
-
const seconds = uptimeSeconds % 60;
|
|
46
|
-
console.log(` Uptime: ${hours}h ${minutes}m ${seconds}s`);
|
|
47
|
-
}
|
|
48
|
-
if (status.crashCount > 0) {
|
|
49
|
-
console.log(` Crashes: ${status.crashCount}`);
|
|
50
|
-
}
|
|
51
|
-
if (status.lastError) {
|
|
52
|
-
console.log(` Last Error: ${status.lastError}`);
|
|
53
|
-
}
|
|
54
|
-
break;
|
|
55
|
-
case 'import':
|
|
56
|
-
const importService = new FileImportService(repo);
|
|
57
|
-
console.log('DEBUG: sync import args:', args);
|
|
58
|
-
const preview = args.includes('--preview');
|
|
59
|
-
console.log('DEBUG: preview flag:', preview);
|
|
60
|
-
const patterns = args.filter(arg => !arg.startsWith('--'));
|
|
61
|
-
if (preview) {
|
|
62
|
-
console.log('DEBUG: Running preview mode only');
|
|
63
|
-
await importService.previewImport({
|
|
64
|
-
patterns: patterns.length > 1 ? patterns.slice(1) : undefined,
|
|
65
|
-
verbose: args.includes('--verbose')
|
|
66
|
-
});
|
|
67
|
-
return; // Exit after preview
|
|
68
|
-
}
|
|
69
|
-
console.log('DEBUG: Running full import');
|
|
70
|
-
await importService.executeImport({
|
|
71
|
-
patterns: patterns.length > 1 ? patterns.slice(1) : undefined,
|
|
72
|
-
verbose: args.includes('--verbose')
|
|
73
|
-
});
|
|
18
|
+
handleStatus();
|
|
74
19
|
break;
|
|
75
20
|
default:
|
|
76
|
-
|
|
77
|
-
console.log('Commands:');
|
|
78
|
-
console.log(' start Start the sync daemon in the background');
|
|
79
|
-
console.log(' stop Stop the sync daemon gracefully');
|
|
80
|
-
console.log(' restart Restart the sync daemon');
|
|
81
|
-
console.log(' status Show daemon status and health information');
|
|
82
|
-
console.log(' import Import existing project files to workspace');
|
|
83
|
-
console.log('');
|
|
84
|
-
console.log('Options:');
|
|
85
|
-
console.log(' --force Force start/stop operations');
|
|
86
|
-
console.log(' --verbose Enable verbose output');
|
|
87
|
-
console.log(' --preview Preview files without importing (import only)');
|
|
21
|
+
showUsage();
|
|
88
22
|
break;
|
|
89
23
|
}
|
|
90
24
|
}
|
|
91
25
|
catch (error) {
|
|
92
|
-
console.error(
|
|
26
|
+
console.error(`Sync command failed: ${error.message}`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function handleStart(verbose) {
|
|
31
|
+
const result = await startDaemon({ verbose });
|
|
32
|
+
if (result.success) {
|
|
33
|
+
console.log(result.message);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.error(result.message);
|
|
93
37
|
process.exit(1);
|
|
94
38
|
}
|
|
95
39
|
}
|
|
40
|
+
async function handleStop(force) {
|
|
41
|
+
const result = await stopDaemon({ force });
|
|
42
|
+
if (result.success) {
|
|
43
|
+
console.log(result.message);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
console.error(result.message);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function handleStatus() {
|
|
51
|
+
const status = getDaemonStatus();
|
|
52
|
+
if (!status.running) {
|
|
53
|
+
console.log('Sync daemon: not running');
|
|
54
|
+
console.log('Run `mod sync start` to begin tracking changes');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.log(`Sync daemon: running (pid ${status.pid})`);
|
|
58
|
+
console.log('');
|
|
59
|
+
if (status.connections.length > 0) {
|
|
60
|
+
console.log('Connected directories:');
|
|
61
|
+
for (const conn of status.connections) {
|
|
62
|
+
const branchInfo = conn.gitBranch ? ` (${conn.gitBranch})` : ' (no git)';
|
|
63
|
+
console.log(` ${conn.path} → ${conn.workspaceName}${branchInfo}`);
|
|
64
|
+
}
|
|
65
|
+
console.log('');
|
|
66
|
+
}
|
|
67
|
+
switch (status.cloudSync) {
|
|
68
|
+
case 'connected':
|
|
69
|
+
console.log('Cloud sync: connected');
|
|
70
|
+
if (status.lastSync) {
|
|
71
|
+
const ago = formatTimeAgo(status.lastSync);
|
|
72
|
+
console.log(`Last sync: ${ago}`);
|
|
73
|
+
}
|
|
74
|
+
console.log(`Pending changes: ${status.pendingChanges}`);
|
|
75
|
+
break;
|
|
76
|
+
case 'not_signed_in':
|
|
77
|
+
console.log('Cloud sync: not signed in');
|
|
78
|
+
console.log('Tracking changes locally');
|
|
79
|
+
console.log('');
|
|
80
|
+
console.log('Sign in to sync with collaborators: mod auth login');
|
|
81
|
+
break;
|
|
82
|
+
case 'disconnected':
|
|
83
|
+
console.log('Cloud sync: disconnected');
|
|
84
|
+
console.log('Changes will sync when connection is restored');
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function showUsage() {
|
|
89
|
+
console.log('Usage: mod sync <command>');
|
|
90
|
+
console.log('');
|
|
91
|
+
console.log('Commands:');
|
|
92
|
+
console.log(' start Start the sync daemon in the background');
|
|
93
|
+
console.log(' stop Stop the sync daemon');
|
|
94
|
+
console.log(' restart Restart the sync daemon');
|
|
95
|
+
console.log(' status Show daemon status');
|
|
96
|
+
console.log('');
|
|
97
|
+
console.log('Options:');
|
|
98
|
+
console.log(' --force Force stop operations');
|
|
99
|
+
console.log(' --verbose Show daemon output in terminal');
|
|
100
|
+
}
|
|
101
|
+
function formatTimeAgo(isoString) {
|
|
102
|
+
const date = new Date(isoString);
|
|
103
|
+
const now = new Date();
|
|
104
|
+
const diffMs = now.getTime() - date.getTime();
|
|
105
|
+
const diffSeconds = Math.floor(diffMs / 1000);
|
|
106
|
+
if (diffSeconds < 60) {
|
|
107
|
+
return `${diffSeconds} seconds ago`;
|
|
108
|
+
}
|
|
109
|
+
const diffMinutes = Math.floor(diffSeconds / 60);
|
|
110
|
+
if (diffMinutes < 60) {
|
|
111
|
+
return `${diffMinutes} minute${diffMinutes === 1 ? '' : 's'} ago`;
|
|
112
|
+
}
|
|
113
|
+
const diffHours = Math.floor(diffMinutes / 60);
|
|
114
|
+
if (diffHours < 24) {
|
|
115
|
+
return `${diffHours} hour${diffHours === 1 ? '' : 's'} ago`;
|
|
116
|
+
}
|
|
117
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
118
|
+
return `${diffDays} day${diffDays === 1 ? '' : 's'} ago`;
|
|
119
|
+
}
|