@mod-computer/cli 0.2.3 → 0.2.5

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.
Files changed (75) hide show
  1. package/dist/cli.bundle.js +216 -36371
  2. package/package.json +3 -3
  3. package/dist/app.js +0 -227
  4. package/dist/cli.bundle.js.map +0 -7
  5. package/dist/cli.js +0 -132
  6. package/dist/commands/add.js +0 -245
  7. package/dist/commands/agents-run.js +0 -71
  8. package/dist/commands/auth.js +0 -259
  9. package/dist/commands/branch.js +0 -1411
  10. package/dist/commands/claude-sync.js +0 -772
  11. package/dist/commands/comment.js +0 -568
  12. package/dist/commands/diff.js +0 -182
  13. package/dist/commands/index.js +0 -73
  14. package/dist/commands/init.js +0 -597
  15. package/dist/commands/ls.js +0 -135
  16. package/dist/commands/members.js +0 -687
  17. package/dist/commands/mv.js +0 -282
  18. package/dist/commands/recover.js +0 -207
  19. package/dist/commands/rm.js +0 -257
  20. package/dist/commands/spec.js +0 -386
  21. package/dist/commands/status.js +0 -296
  22. package/dist/commands/sync.js +0 -119
  23. package/dist/commands/trace.js +0 -1752
  24. package/dist/commands/workspace.js +0 -447
  25. package/dist/components/conflict-resolution-ui.js +0 -120
  26. package/dist/components/messages.js +0 -5
  27. package/dist/components/thread.js +0 -8
  28. package/dist/config/features.js +0 -83
  29. package/dist/containers/branches-container.js +0 -140
  30. package/dist/containers/directory-container.js +0 -92
  31. package/dist/containers/thread-container.js +0 -214
  32. package/dist/containers/threads-container.js +0 -27
  33. package/dist/containers/workspaces-container.js +0 -27
  34. package/dist/daemon/conflict-resolution.js +0 -172
  35. package/dist/daemon/content-hash.js +0 -31
  36. package/dist/daemon/file-sync.js +0 -985
  37. package/dist/daemon/index.js +0 -203
  38. package/dist/daemon/mime-types.js +0 -166
  39. package/dist/daemon/offline-queue.js +0 -211
  40. package/dist/daemon/path-utils.js +0 -64
  41. package/dist/daemon/share-policy.js +0 -83
  42. package/dist/daemon/wasm-errors.js +0 -189
  43. package/dist/daemon/worker.js +0 -557
  44. package/dist/daemon-worker.js +0 -258
  45. package/dist/errors/workspace-errors.js +0 -48
  46. package/dist/lib/auth-server.js +0 -216
  47. package/dist/lib/browser.js +0 -35
  48. package/dist/lib/diff.js +0 -284
  49. package/dist/lib/formatters.js +0 -204
  50. package/dist/lib/git.js +0 -137
  51. package/dist/lib/local-fs.js +0 -201
  52. package/dist/lib/prompts.js +0 -56
  53. package/dist/lib/storage.js +0 -213
  54. package/dist/lib/trace-formatters.js +0 -314
  55. package/dist/services/add-service.js +0 -554
  56. package/dist/services/add-validation.js +0 -124
  57. package/dist/services/automatic-file-tracker.js +0 -303
  58. package/dist/services/cli-orchestrator.js +0 -227
  59. package/dist/services/feature-flags.js +0 -187
  60. package/dist/services/file-import-service.js +0 -283
  61. package/dist/services/file-transformation-service.js +0 -218
  62. package/dist/services/logger.js +0 -44
  63. package/dist/services/mod-config.js +0 -67
  64. package/dist/services/modignore-service.js +0 -328
  65. package/dist/services/sync-daemon.js +0 -244
  66. package/dist/services/thread-notification-service.js +0 -50
  67. package/dist/services/thread-service.js +0 -147
  68. package/dist/stores/use-directory-store.js +0 -96
  69. package/dist/stores/use-threads-store.js +0 -46
  70. package/dist/stores/use-workspaces-store.js +0 -54
  71. package/dist/types/add-types.js +0 -99
  72. package/dist/types/config.js +0 -16
  73. package/dist/types/index.js +0 -2
  74. package/dist/types/workspace-connection.js +0 -53
  75. package/dist/types.js +0 -1
package/dist/cli.js DELETED
@@ -1,132 +0,0 @@
1
- #!/usr/bin/env -S node --disable-warning=ExperimentalWarning
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import dotenv from 'dotenv';
4
- import path from 'path';
5
- import { fileURLToPath } from 'url';
6
- import { render } from 'ink';
7
- import App from './app.js';
8
- import { repo as getRepo } from '@mod/mod-core/repos/repo.node';
9
- import { buildCommandRegistry } from './commands/index.js';
10
- import meow from 'meow';
11
- // Background watch functionality removed - using automatic-file-tracker instead
12
- import { getFeatureFlags } from './services/feature-flags.js';
13
- import { FEATURES, isFeatureEnabled } from './config/features.js';
14
- // Load environment variables from multiple candidate locations
15
- // 1) CWD (project dir where user runs `mod`)
16
- dotenv.config({ override: false, debug: false, quiet: true });
17
- // 2) Package-local .env (e.g., packages/mod-cli/.env) for monorepo development
18
- try {
19
- const __filename = fileURLToPath(import.meta.url);
20
- const __dirname = path.dirname(__filename);
21
- // dist/cli.js -> ../.env
22
- const pkgEnv = path.join(__dirname, '../.env');
23
- dotenv.config({ path: pkgEnv, override: true, debug: false, quiet: true });
24
- // monorepo root .env (two levels up from packages/mod-cli/dist)
25
- const rootEnv = path.join(__dirname, '../../../.env');
26
- dotenv.config({ path: rootEnv, override: true, debug: false, quiet: true });
27
- }
28
- catch { }
29
- // Note: AI features are lazily imported in thread-service to keep bootstrap light.
30
- // Note: Startup logging removed to reduce noise in alpha mode
31
- // Suppress extremely chatty Automerge sync noise that breaks TTY input rendering
32
- try {
33
- const noisy = [
34
- 'error receiving message',
35
- 'Attempting to change an outdated document',
36
- ];
37
- const shouldDrop = (args) => {
38
- try {
39
- const s = args.map(a => (typeof a === 'string' ? a : (a && a.stack) || JSON.stringify(a))).join(' ');
40
- return noisy.some(k => s.includes(k));
41
- }
42
- catch {
43
- return false;
44
- }
45
- };
46
- const origLog = console.log.bind(console);
47
- const origErr = console.error.bind(console);
48
- const origWarn = console.warn.bind(console);
49
- console.log = (...args) => { if (shouldDrop(args))
50
- return; origLog(...args); };
51
- console.error = (...args) => { if (shouldDrop(args))
52
- return; origErr(...args); };
53
- console.warn = (...args) => { if (shouldDrop(args))
54
- return; origWarn(...args); };
55
- }
56
- catch { }
57
- const cli = meow(`
58
- Usage
59
- $ mod <command> [options]
60
- Commands
61
- create-task <desc>
62
- set-task-status <id> <status>
63
- ...
64
- `, {
65
- importMeta: import.meta,
66
- flags: {
67
- preview: {
68
- type: 'boolean',
69
- default: false
70
- },
71
- verbose: {
72
- type: 'boolean',
73
- default: false
74
- },
75
- force: {
76
- type: 'boolean',
77
- default: false
78
- },
79
- dev: {
80
- type: 'boolean',
81
- default: false
82
- },
83
- json: {
84
- type: 'boolean',
85
- default: false
86
- }
87
- },
88
- allowUnknownFlags: true
89
- });
90
- async function main() {
91
- const repo = await getRepo();
92
- // Load user document into share policy if logged in
93
- const { readConfig } = await import('./lib/storage.js');
94
- const { addUserToSharePolicy } = await import('./daemon/share-policy.js');
95
- const config = readConfig();
96
- if (config.auth?.userDocId) {
97
- addUserToSharePolicy(config.auth.userDocId);
98
- }
99
- const availableCommands = buildCommandRegistry();
100
- const [cmd, ...args] = cli.input;
101
- // No user-facing banners or notifications about feature flags
102
- // Background watch now handled by automatic-file-tracker service
103
- // Handle command execution
104
- if (cmd && typeof availableCommands[cmd] === 'function') {
105
- // Pass raw args after the command name from process.argv
106
- // This preserves all flags (--type, --file, --json, etc.) as-is
107
- const cmdIndex = process.argv.findIndex(arg => arg === cmd);
108
- const rawArgs = cmdIndex >= 0 ? process.argv.slice(cmdIndex + 1) : args;
109
- await availableCommands[cmd](rawArgs, repo);
110
- // Exit after command completes - WebSocket keeps event loop alive otherwise
111
- process.exit(0);
112
- }
113
- if (!cmd) {
114
- console.log('Mod CLI\n');
115
- console.log('Available commands:');
116
- for (const command of Object.keys(availableCommands).sort()) {
117
- console.log(` mod ${command}`);
118
- }
119
- return;
120
- }
121
- if (cmd && !availableCommands[cmd]) {
122
- console.error(`Unknown command: ${cmd}`);
123
- console.error('Run "mod" to see available commands.');
124
- process.exit(1);
125
- }
126
- // Ink UI rendering controlled by features, not exposed to users
127
- if (isFeatureEnabled(FEATURES.STATUS) || Object.keys(availableCommands).length > 1) {
128
- const featureFlags = getFeatureFlags(); // Keep for backward compatibility with App component
129
- render(_jsx(App, { repo: repo, featureFlags: featureFlags }));
130
- }
131
- }
132
- main();
@@ -1,245 +0,0 @@
1
- #!/usr/bin/env node
2
- // glassware[type="implementation", id="impl-cli-add-command--777b18e2", requirements="requirement-cli-add-cmd--aff0d740,requirement-cli-add-cmd-help--e0709244,requirement-cli-add-progress-small--5474ba10,requirement-cli-add-progress-medium--0f22e3e8,requirement-cli-add-progress-large--477f1e9a,requirement-cli-add-summary--3d0fb9b5,requirement-cli-add-dry-run--91bb0ff6,requirement-cli-add-verbose--3a958508"]
3
- // spec: packages/mod-cli/specs/add.md
4
- import ora from 'ora';
5
- import { AddService } from '../services/add-service.js';
6
- import { validateAddOptions, validateWorkspaceState } from '../services/add-validation.js';
7
- import { ADD_CONSTANTS, } from '../types/add-types.js';
8
- /**
9
- * Parse command line arguments
10
- */
11
- function parseArgs(args) {
12
- const paths = [];
13
- let dryRun = false;
14
- let includeLargeBinary = false;
15
- let verbose = false;
16
- let quiet = false;
17
- for (const arg of args) {
18
- if (arg === '--dry-run') {
19
- dryRun = true;
20
- }
21
- else if (arg === '--include-large-binary') {
22
- includeLargeBinary = true;
23
- }
24
- else if (arg === '-v' || arg === '--verbose') {
25
- verbose = true;
26
- }
27
- else if (arg === '-q' || arg === '--quiet') {
28
- quiet = true;
29
- }
30
- else if (!arg.startsWith('-')) {
31
- paths.push(arg);
32
- }
33
- }
34
- // Default to current directory if no paths
35
- if (paths.length === 0) {
36
- paths.push('.');
37
- }
38
- return { paths, dryRun, includeLargeBinary, verbose, quiet };
39
- }
40
- /**
41
- * Add command entry point
42
- */
43
- export async function addCommand(args, repo) {
44
- // Parse arguments
45
- const { paths, dryRun, includeLargeBinary, verbose, quiet } = parseArgs(args);
46
- const options = {
47
- paths,
48
- dryRun,
49
- includeLargeBinary,
50
- verbose,
51
- quiet
52
- };
53
- // Validate options
54
- const optionsValidation = validateAddOptions(options);
55
- if (!optionsValidation.valid) {
56
- for (const error of optionsValidation.errors) {
57
- console.error(`Error: ${error.message}`);
58
- }
59
- process.exit(1);
60
- }
61
- // Validate workspace
62
- const workspaceValidation = await validateWorkspaceState(process.cwd());
63
- if (!workspaceValidation.valid) {
64
- for (const error of workspaceValidation.errors) {
65
- console.error(`Error: ${error.message}`);
66
- }
67
- process.exit(1);
68
- }
69
- // Create add service
70
- const addService = new AddService(repo);
71
- // Set up cancellation handler
72
- process.on('SIGINT', () => {
73
- addService.cancel();
74
- console.log('\nCancelling...');
75
- });
76
- // Progress tracking
77
- let spinner = null;
78
- let lastProgressUpdate = 0;
79
- const progressBarWidth = 30;
80
- const onProgress = (progress) => {
81
- if (quiet)
82
- return;
83
- // Throttle progress updates (cli-add-progress-throttle)
84
- const now = Date.now();
85
- if (now - lastProgressUpdate < ADD_CONSTANTS.PROGRESS_THROTTLE_MS)
86
- return;
87
- lastProgressUpdate = now;
88
- if (progress.phase === 'scanning') {
89
- if (!spinner) {
90
- spinner = ora('Scanning...').start();
91
- }
92
- spinner.text = `Scanning... ${progress.total} files found`;
93
- }
94
- else if (progress.phase === 'comparing') {
95
- if (spinner) {
96
- spinner.text = `Comparing... ${progress.current}/${progress.total} directories`;
97
- }
98
- }
99
- else if (progress.phase === 'adding') {
100
- const total = progress.total;
101
- if (total < ADD_CONSTANTS.SMALL_ADD_THRESHOLD) {
102
- // Small: no progress bar
103
- if (spinner) {
104
- spinner.text = `Adding... ${progress.current}/${total}`;
105
- }
106
- }
107
- else if (total < ADD_CONSTANTS.MEDIUM_ADD_THRESHOLD) {
108
- // Medium: spinner with count
109
- if (spinner) {
110
- spinner.text = `Adding... ${progress.current}/${total} files`;
111
- }
112
- }
113
- else {
114
- // Large: progress bar
115
- const percent = Math.round((progress.current / total) * 100);
116
- const filled = Math.round((progress.current / total) * progressBarWidth);
117
- const bar = '█'.repeat(filled) + '░'.repeat(progressBarWidth - filled);
118
- const eta = progress.eta ? ` | ETA: ${formatEta(progress.eta)}` : '';
119
- if (spinner) {
120
- spinner.text = `Adding files...\n[${bar}] ${percent}% | ${progress.current.toLocaleString()}/${total.toLocaleString()}${eta}`;
121
- }
122
- }
123
- if (verbose && progress.currentFile) {
124
- console.log(`+ ${progress.currentFile}`);
125
- }
126
- }
127
- };
128
- // Execute
129
- try {
130
- const result = await addService.execute(options, onProgress);
131
- // Stop spinner
132
- if (spinner) {
133
- spinner.stop();
134
- }
135
- // Print result
136
- printResult(result, options);
137
- if (!result.success) {
138
- process.exit(1);
139
- }
140
- }
141
- catch (error) {
142
- if (spinner) {
143
- spinner.stop();
144
- }
145
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
146
- process.exit(1);
147
- }
148
- }
149
- /**
150
- * Print the result of the add operation
151
- */
152
- function printResult(result, options) {
153
- const { summary, directories, duration } = result;
154
- if (options.dryRun) {
155
- // Dry run output
156
- console.log(`Would add ${summary.totalFiles.toLocaleString()} files across ${directories.length} directories:`);
157
- for (const dir of directories.slice(0, 10)) {
158
- console.log(` ${dir.path}/ (${dir.created} files)`);
159
- }
160
- if (directories.length > 10) {
161
- console.log(` ... (${directories.length - 10} more directories)`);
162
- }
163
- if (summary.skipped > 0) {
164
- console.log(`\nWould skip ${summary.skipped} files`);
165
- }
166
- const estimatedMinutes = Math.ceil(summary.totalFiles * 50 / 1000 / 60);
167
- console.log(`\nEstimated time: ~${estimatedMinutes} minutes`);
168
- return;
169
- }
170
- // Normal output
171
- if (options.quiet) {
172
- // Quiet: only show summary line
173
- if (summary.errors > 0) {
174
- console.log(`Added ${summary.created} files (${summary.errors} errors)`);
175
- }
176
- else {
177
- console.log(`Added ${summary.created} files`);
178
- }
179
- return;
180
- }
181
- // Standard output
182
- const parts = [];
183
- if (summary.created > 0) {
184
- parts.push(`${summary.created} created`);
185
- }
186
- if (summary.updated > 0) {
187
- parts.push(`${summary.updated} updated`);
188
- }
189
- if (summary.unchanged > 0) {
190
- parts.push(`${summary.unchanged} unchanged`);
191
- }
192
- if (parts.length > 0) {
193
- console.log(`\nAdded ${summary.totalFiles.toLocaleString()} files (${parts.join(', ')})`);
194
- }
195
- else {
196
- console.log(`\nNo files to add`);
197
- }
198
- // Show skipped files
199
- if (summary.skipped > 0) {
200
- console.log(`\nSkipped: ${summary.skipped} files`);
201
- }
202
- // Show errors
203
- if (summary.errors > 0) {
204
- console.log(`\nErrors: ${summary.errors} files`);
205
- // Show first few errors
206
- const allErrors = directories.flatMap(d => d.errors);
207
- for (const error of allErrors.slice(0, 5)) {
208
- console.log(` ${error.relativePath}: ${error.error?.message}`);
209
- }
210
- if (allErrors.length > 5) {
211
- console.log(` ... (${allErrors.length - 5} more errors)`);
212
- }
213
- }
214
- // Show duration
215
- console.log(`\nCompleted in ${formatDuration(duration)}`);
216
- }
217
- /**
218
- * Format duration in human readable format
219
- */
220
- function formatDuration(ms) {
221
- if (ms < 1000) {
222
- return `${ms}ms`;
223
- }
224
- if (ms < 60000) {
225
- return `${(ms / 1000).toFixed(1)}s`;
226
- }
227
- const minutes = Math.floor(ms / 60000);
228
- const seconds = Math.round((ms % 60000) / 1000);
229
- return `${minutes}m ${seconds}s`;
230
- }
231
- /**
232
- * Format ETA in human readable format
233
- */
234
- function formatEta(ms) {
235
- if (ms < 60000) {
236
- return `${Math.round(ms / 1000)}s`;
237
- }
238
- const minutes = Math.floor(ms / 60000);
239
- const seconds = Math.round((ms % 60000) / 1000);
240
- if (seconds === 0) {
241
- return `${minutes}m`;
242
- }
243
- return `${minutes}m ${seconds}s`;
244
- }
245
- export default addCommand;
@@ -1,71 +0,0 @@
1
- import { readModConfig } from '../services/mod-config.js';
2
- import { ThreadService } from '@mod/mod-core/services/thread-service';
3
- export async function agentsRunCommand(args, repo) {
4
- // Usage: mod agents-run --prompt "..." [--agent dev|planner]
5
- const promptIndex = args.findIndex(a => a === '--prompt');
6
- const agentIndex = args.findIndex(a => a === '--agent');
7
- const prompt = promptIndex !== -1 ? args[promptIndex + 1] : undefined;
8
- const agentName = agentIndex !== -1 ? (args[agentIndex + 1] || 'dev') : 'dev';
9
- if (!prompt) {
10
- console.error('Usage: mod agents-run --prompt "..." [--agent dev|planner]');
11
- process.exit(1);
12
- }
13
- const config = readModConfig();
14
- if (!config?.workspaceId) {
15
- console.error('No active workspace found in .mod/config.json');
16
- process.exit(1);
17
- }
18
- const wsHandle = await repo.find(config.workspaceId);
19
- const workspace = await wsHandle.doc();
20
- if (!workspace) {
21
- console.error('Workspace not found');
22
- process.exit(1);
23
- }
24
- const threadService = new ThreadService(repo);
25
- const threadId = workspace.activeThreadId || (await (async () => {
26
- const t = await threadService.createThreadWithBranch(workspace.id, workspace.branchesDocId, workspace.activeBranchId, 'CLI Thread');
27
- return t.id;
28
- })());
29
- // Lazy import agents (shimmed types)
30
- // Agent packages not yet available - placeholder implementation
31
- console.error('Agent packages (@mod/mod-agents) are not yet implemented');
32
- console.log(`Requested agent: ${agentName}`);
33
- process.exit(1);
34
- /*
35
- let agent: any;
36
- if (agentName === 'planner' || agentName === 'plan') {
37
- const mod = await import('@mod/mod-agents/planner');
38
- agent = (mod as any).plannerAgent || (mod as any).default;
39
- } else {
40
- const mod = await import('@mod/mod-agents/dev-agent');
41
- agent = (mod as any).devAgent || (mod as any).default;
42
- }
43
- */
44
- /*
45
- const tools: Record<string, any> = {};
46
- const apiKey = process.env.OPENAI_API_KEY || process.env.OPENAI || process.env.ANTHROPIC_API_KEY || '';
47
- try {
48
- for await (const chunk of chatWithAgentCli({
49
- repo: repo as any,
50
- threadId: threadId as any,
51
- userMessage: prompt,
52
- workspace,
53
- agent,
54
- tools,
55
- apiKey,
56
- })) {
57
- if (chunk.type === 'content') {
58
- process.stdout.write(chunk.content);
59
- } else if (chunk.type === 'tool-call') {
60
- log('[tool-call]', (chunk as any).toolName || '');
61
- } else if (chunk.type === 'tool-result') {
62
- log('[tool-result]', (chunk as any).output?.toolName || '');
63
- }
64
- }
65
- } catch (e: any) {
66
- console.error('Agent run failed:', e?.message || e);
67
- } finally {
68
- setTimeout(() => process.exit(0), 500);
69
- }
70
- */
71
- }