@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
@@ -1,314 +0,0 @@
1
- /**
2
- * Trace Formatters
3
- * Formatting utilities for trace CLI output
4
- *
5
- * spec: packages/mod-cli/specs/traces-cli.md
6
- */
7
- // =============================================================================
8
- // List Formatters
9
- // =============================================================================
10
- // glassware[type="implementation", id="impl-trace-list-table--58311354", specifications="specification-spec-traces-cli-list-output--46cf3c8e"]
11
- /**
12
- * Format traces as a table
13
- */
14
- export function formatTracesTable(traces) {
15
- if (traces.length === 0) {
16
- return 'No traces found.';
17
- }
18
- const lines = [];
19
- lines.push('Traces');
20
- lines.push('═'.repeat(70));
21
- lines.push('');
22
- // Group by node type
23
- const byType = new Map();
24
- for (const trace of traces) {
25
- const list = byType.get(trace.nodeType) || [];
26
- list.push(trace);
27
- byType.set(trace.nodeType, list);
28
- }
29
- for (const [nodeType, typeTraces] of byType) {
30
- lines.push(`${nodeType} (${typeTraces.length})`);
31
- lines.push('─'.repeat(40));
32
- for (const trace of typeTraces) {
33
- const location = trace.location.type === 'inline'
34
- ? `${trace.location.file}:${trace.location.line}`
35
- : `mod:${trace.location.docId}`;
36
- const status = trace.status === 'orphaned' ? ' [orphaned]' : '';
37
- const linkCount = trace.links.length > 0 ? ` (${trace.links.length} links)` : '';
38
- lines.push(` ${trace.id}${status}${linkCount}`);
39
- lines.push(` └─ ${location}`);
40
- if (trace.text && trace.text !== trace.id) {
41
- const truncatedText = trace.text.length > 50
42
- ? trace.text.slice(0, 47) + '...'
43
- : trace.text;
44
- lines.push(` "${truncatedText}"`);
45
- }
46
- }
47
- lines.push('');
48
- }
49
- lines.push(`Total: ${traces.length} traces`);
50
- return lines.join('\n');
51
- }
52
- // glassware[type="implementation", id="impl-trace-list-json--fc16c20a", specifications="specification-spec-traces-cli-json--abf2b82f"]
53
- /**
54
- * Format traces as JSON
55
- */
56
- export function formatTracesJson(traces) {
57
- return JSON.stringify({
58
- traces: traces.map(t => ({
59
- id: t.id,
60
- nodeType: t.nodeType,
61
- storage: t.storage,
62
- location: t.location,
63
- text: t.text,
64
- status: t.status,
65
- links: t.links,
66
- })),
67
- total: traces.length,
68
- }, null, 2);
69
- }
70
- // =============================================================================
71
- // Report Formatters
72
- // =============================================================================
73
- // glassware[type="implementation", id="impl-trace-report-text--5ba186be", specifications="specification-spec-traces-cli-report--2af325ed,specification-spec-traces-cli-report-content--8971542e"]
74
- /**
75
- * Format trace report as text
76
- * @param allTests - Optional array of all tests in workspace for test coverage checking
77
- */
78
- export function formatTraceReport(report, allTests = []) {
79
- const lines = [];
80
- const fileName = report.file.split('/').pop() || report.file;
81
- lines.push(`${fileName} - Trace Report`);
82
- lines.push('═'.repeat(55));
83
- lines.push('');
84
- if (report.traces.length === 0) {
85
- lines.push('No traces found in this file.');
86
- return lines.join('\n');
87
- }
88
- for (const item of report.traces) {
89
- const trace = item.trace;
90
- const statusIcon = getStatusIcon(item.status);
91
- const implStatus = getImplStatus(item);
92
- const testStatus = getTestStatus(item, allTests);
93
- // Main trace line
94
- const shortId = trace.id.split('--')[0];
95
- const title = trace.text && trace.text !== trace.id
96
- ? trace.text.slice(0, 40)
97
- : shortId;
98
- lines.push(`${statusIcon} ${shortId}: ${title}`);
99
- lines.push(` ${implStatus} ${testStatus}`);
100
- // Show implementations (implementations point TO specs, so check incoming)
101
- const implementations = item.incoming['implements'] || [];
102
- for (const impl of implementations) {
103
- const implLoc = impl.location.type === 'inline'
104
- ? `${impl.location.file}:${impl.location.line}`
105
- : `mod:${impl.location.docId}`;
106
- lines.push(` └─ impl: ${implLoc}`);
107
- // Show tests for this implementation
108
- const tests = getTestsForImpl(impl, allTests);
109
- for (const test of tests) {
110
- const testLoc = test.location.type === 'inline'
111
- ? `${test.location.file}:${test.location.line}`
112
- : `mod:${test.location.docId}`;
113
- lines.push(` └─ test: ${testLoc}`);
114
- }
115
- }
116
- lines.push('');
117
- }
118
- // Recalculate summary based on incoming edges (since implementations point TO specs)
119
- let fullyLinked = 0;
120
- let partiallyLinked = 0;
121
- let unlinked = 0;
122
- for (const item of report.traces) {
123
- const impls = item.incoming['implements'] || [];
124
- const hasImpl = impls.length > 0;
125
- const hasTests = impls.some(impl => allTests.some(test => test.links.some(l => stripTypePrefix(l.targetId) === impl.id)));
126
- if (hasImpl && hasTests) {
127
- fullyLinked++;
128
- }
129
- else if (hasImpl) {
130
- partiallyLinked++;
131
- }
132
- else {
133
- unlinked++;
134
- }
135
- }
136
- lines.push('─'.repeat(55));
137
- lines.push(`Summary: ${fullyLinked}/${report.traces.length} fully linked, ` +
138
- `${partiallyLinked} partial, ${unlinked} unlinked`);
139
- return lines.join('\n');
140
- }
141
- function getStatusIcon(status) {
142
- switch (status) {
143
- case 'fully-linked': return '✓';
144
- case 'partially-linked': return '⚠';
145
- case 'unlinked': return '✗';
146
- }
147
- }
148
- function getImplStatus(item) {
149
- // Implementations point TO specs, so check incoming edges
150
- const hasImpl = (item.incoming['implements'] || []).length > 0;
151
- return hasImpl ? '✓ Implemented' : '✗ Not implemented';
152
- }
153
- // Strip type prefix from link target IDs (e.g., "implementation-impl-foo--abc" -> "impl-foo--abc")
154
- function stripTypePrefix(targetId) {
155
- const prefixes = ['implementation-', 'specification-', 'requirement-', 'test-'];
156
- for (const prefix of prefixes) {
157
- if (targetId.startsWith(prefix)) {
158
- return targetId.slice(prefix.length);
159
- }
160
- }
161
- return targetId;
162
- }
163
- function getTestStatus(item, allTests) {
164
- // Check if any incoming implementations have tests pointing TO them
165
- const impls = item.incoming['implements'] || [];
166
- for (const impl of impls) {
167
- // Find tests that link to this implementation (strip type prefix from targetId)
168
- const hasTest = allTests.some(test => test.links.some(l => stripTypePrefix(l.targetId) === impl.id));
169
- if (hasTest) {
170
- return '✓ Tested';
171
- }
172
- }
173
- return impls.length > 0 ? '✗ No tests' : '';
174
- }
175
- function getTestsForImpl(impl, allTests) {
176
- // Find tests that link to this implementation (strip type prefix from targetId)
177
- return allTests.filter(test => test.links.some(l => stripTypePrefix(l.targetId) === impl.id));
178
- }
179
- // glassware[type="implementation", id="impl-trace-report-json--10381dca", specifications="specification-spec-traces-cli-report-json--0a0ddd0d"]
180
- /**
181
- * Format trace report as JSON
182
- * @param allTests - Optional array of all tests in workspace for test coverage checking
183
- */
184
- export function formatTraceReportJson(report, allTests = []) {
185
- // TODO: Could enhance JSON output with test coverage info from allTests
186
- return JSON.stringify(report, null, 2);
187
- }
188
- // =============================================================================
189
- // Coverage Formatters
190
- // =============================================================================
191
- // glassware[type="implementation", id="impl-trace-coverage-text--45e4276a", specifications="specification-spec-traces-cli-coverage--571a6cbb,specification-spec-traces-cli-coverage-visual--d06a6e97"]
192
- /**
193
- * Format coverage report as text with progress bars
194
- */
195
- export function formatCoverageReport(coverage) {
196
- const lines = [];
197
- lines.push('Trace Coverage');
198
- lines.push('═'.repeat(55));
199
- lines.push('');
200
- // Per node type stats
201
- for (const [nodeType, stats] of Object.entries(coverage.byNodeType)) {
202
- if (stats.total === 0)
203
- continue;
204
- const linkedCount = stats.fullyLinked + stats.partiallyLinked;
205
- const percentage = Math.round((linkedCount / stats.total) * 100);
206
- const bar = createProgressBar(percentage);
207
- lines.push(`${nodeType}:`);
208
- lines.push(` ${bar} ${percentage}% (${linkedCount}/${stats.total} linked)`);
209
- }
210
- lines.push('');
211
- lines.push('─'.repeat(55));
212
- // Summary
213
- const { summary } = coverage;
214
- lines.push(`Total traces: ${summary.totalTraces}`);
215
- lines.push(`Fully linked: ${summary.fullyLinked}`);
216
- lines.push(`Coverage: ${summary.coveragePercentage.toFixed(1)}%`);
217
- // Gaps
218
- if (coverage.orphaned.length > 0) {
219
- lines.push('');
220
- lines.push(`⚠ Orphaned traces: ${coverage.orphaned.length}`);
221
- }
222
- const missingCount = Object.values(coverage.missingEdges).reduce((sum, arr) => sum + arr.length, 0);
223
- if (missingCount > 0) {
224
- lines.push(`⚠ Missing edges: ${missingCount}`);
225
- }
226
- return lines.join('\n');
227
- }
228
- function createProgressBar(percentage, width = 16) {
229
- const filled = Math.round((percentage / 100) * width);
230
- const empty = width - filled;
231
- return '█'.repeat(filled) + '░'.repeat(empty);
232
- }
233
- // glassware[type="implementation", id="impl-trace-coverage-json--f30dd68a", specifications="specification-spec-traces-cli-coverage-json--f23ec095"]
234
- /**
235
- * Format coverage report as JSON
236
- */
237
- export function formatCoverageJson(coverage) {
238
- // Transform to agent-friendly format
239
- const requirements = coverage.byNodeType['requirement'] || { total: 0, fullyLinked: 0, partiallyLinked: 0, unlinked: 0 };
240
- const implementations = coverage.byNodeType['implementation'] || { total: 0, fullyLinked: 0, partiallyLinked: 0, unlinked: 0 };
241
- return JSON.stringify({
242
- coverage: {
243
- requirements: {
244
- total: requirements.total,
245
- implemented: requirements.fullyLinked + requirements.partiallyLinked,
246
- },
247
- implementations: {
248
- total: implementations.total,
249
- tested: implementations.fullyLinked,
250
- },
251
- },
252
- byNodeType: coverage.byNodeType,
253
- summary: coverage.summary,
254
- orphaned: coverage.orphaned.map(t => ({
255
- id: t.id,
256
- nodeType: t.nodeType,
257
- file: t.location.type === 'inline' ? t.location.file : undefined,
258
- line: t.location.type === 'inline' ? t.location.line : undefined,
259
- })),
260
- missingEdges: Object.fromEntries(Object.entries(coverage.missingEdges).map(([edge, traces]) => [
261
- edge,
262
- traces.map(t => ({
263
- id: t.id,
264
- nodeType: t.nodeType,
265
- file: t.location.type === 'inline' ? t.location.file : undefined,
266
- })),
267
- ])),
268
- }, null, 2);
269
- }
270
- // =============================================================================
271
- // Unmet Requirements Formatter
272
- // =============================================================================
273
- // glassware[type="implementation", id="impl-trace-unmet-text--fc495826", specifications="specification-spec-traces-cli-unmet--1c11203e,specification-spec-traces-cli-unmet-output--623dd824"]
274
- /**
275
- * Format unmet requirements list
276
- */
277
- export function formatUnmetRequirements(traces) {
278
- if (traces.length === 0) {
279
- return 'All requirements have implementations! 🎉';
280
- }
281
- const lines = [];
282
- lines.push('Unmet Requirements');
283
- lines.push('═'.repeat(55));
284
- lines.push('');
285
- for (const trace of traces) {
286
- const location = trace.location.type === 'inline'
287
- ? `${trace.location.file}:${trace.location.line}`
288
- : `mod:${trace.location.docId}`;
289
- const title = trace.text && trace.text !== trace.id
290
- ? trace.text.slice(0, 50)
291
- : trace.id.split('--')[0];
292
- lines.push(`✗ ${trace.id}`);
293
- lines.push(` "${title}"`);
294
- lines.push(` └─ ${location}`);
295
- lines.push('');
296
- }
297
- lines.push(`Total: ${traces.length} unmet requirements`);
298
- return lines.join('\n');
299
- }
300
- // glassware[type="implementation", id="impl-trace-unmet-json--aa05049d", specifications="specification-spec-traces-cli-json--abf2b82f"]
301
- /**
302
- * Format unmet requirements as JSON
303
- */
304
- export function formatUnmetJson(traces) {
305
- return JSON.stringify({
306
- unmet: traces.map(t => ({
307
- id: t.id,
308
- title: t.text || t.id.split('--')[0],
309
- file: t.location.type === 'inline' ? t.location.file : undefined,
310
- line: t.location.type === 'inline' ? t.location.line : undefined,
311
- })),
312
- total: traces.length,
313
- }, null, 2);
314
- }