obsyncd 1.0.0

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 (102) hide show
  1. package/README.md +920 -0
  2. package/dist/cli/commands/init.d.ts +8 -0
  3. package/dist/cli/commands/init.d.ts.map +1 -0
  4. package/dist/cli/commands/init.js +104 -0
  5. package/dist/cli/commands/init.js.map +1 -0
  6. package/dist/cli/commands/status.d.ts +8 -0
  7. package/dist/cli/commands/status.d.ts.map +1 -0
  8. package/dist/cli/commands/status.js +117 -0
  9. package/dist/cli/commands/status.js.map +1 -0
  10. package/dist/cli/commands/sync.d.ts +13 -0
  11. package/dist/cli/commands/sync.d.ts.map +1 -0
  12. package/dist/cli/commands/sync.js +225 -0
  13. package/dist/cli/commands/sync.js.map +1 -0
  14. package/dist/cli/prompts/conflictPrompt.d.ts +10 -0
  15. package/dist/cli/prompts/conflictPrompt.d.ts.map +1 -0
  16. package/dist/cli/prompts/conflictPrompt.js +51 -0
  17. package/dist/cli/prompts/conflictPrompt.js.map +1 -0
  18. package/dist/cli/prompts/fileBrowser.d.ts +6 -0
  19. package/dist/cli/prompts/fileBrowser.d.ts.map +1 -0
  20. package/dist/cli/prompts/fileBrowser.js +91 -0
  21. package/dist/cli/prompts/fileBrowser.js.map +1 -0
  22. package/dist/cli/prompts/vaultSelector.d.ts +13 -0
  23. package/dist/cli/prompts/vaultSelector.d.ts.map +1 -0
  24. package/dist/cli/prompts/vaultSelector.js +63 -0
  25. package/dist/cli/prompts/vaultSelector.js.map +1 -0
  26. package/dist/cli/ui/colors.d.ts +50 -0
  27. package/dist/cli/ui/colors.d.ts.map +1 -0
  28. package/dist/cli/ui/colors.js +62 -0
  29. package/dist/cli/ui/colors.js.map +1 -0
  30. package/dist/cli/ui/output.d.ts +45 -0
  31. package/dist/cli/ui/output.d.ts.map +1 -0
  32. package/dist/cli/ui/output.js +116 -0
  33. package/dist/cli/ui/output.js.map +1 -0
  34. package/dist/cli/ui/spinner.d.ts +29 -0
  35. package/dist/cli/ui/spinner.d.ts.map +1 -0
  36. package/dist/cli/ui/spinner.js +80 -0
  37. package/dist/cli/ui/spinner.js.map +1 -0
  38. package/dist/cli/ui/table.d.ts +28 -0
  39. package/dist/cli/ui/table.d.ts.map +1 -0
  40. package/dist/cli/ui/table.js +123 -0
  41. package/dist/cli/ui/table.js.map +1 -0
  42. package/dist/cli/utils/terminal.d.ts +21 -0
  43. package/dist/cli/utils/terminal.d.ts.map +1 -0
  44. package/dist/cli/utils/terminal.js +59 -0
  45. package/dist/cli/utils/terminal.js.map +1 -0
  46. package/dist/cli.d.ts +3 -0
  47. package/dist/cli.d.ts.map +1 -0
  48. package/dist/cli.js +32 -0
  49. package/dist/cli.js.map +1 -0
  50. package/dist/config/index.d.ts +45 -0
  51. package/dist/config/index.d.ts.map +1 -0
  52. package/dist/config/index.js +112 -0
  53. package/dist/config/index.js.map +1 -0
  54. package/dist/index.d.ts +6 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +5 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/storage/index.d.ts +35 -0
  59. package/dist/storage/index.d.ts.map +1 -0
  60. package/dist/storage/index.js +97 -0
  61. package/dist/storage/index.js.map +1 -0
  62. package/dist/sync/changeDetector.d.ts +29 -0
  63. package/dist/sync/changeDetector.d.ts.map +1 -0
  64. package/dist/sync/changeDetector.js +259 -0
  65. package/dist/sync/changeDetector.js.map +1 -0
  66. package/dist/sync/conflictResolver.d.ts +29 -0
  67. package/dist/sync/conflictResolver.d.ts.map +1 -0
  68. package/dist/sync/conflictResolver.js +116 -0
  69. package/dist/sync/conflictResolver.js.map +1 -0
  70. package/dist/sync/directoryLister.d.ts +18 -0
  71. package/dist/sync/directoryLister.d.ts.map +1 -0
  72. package/dist/sync/directoryLister.js +39 -0
  73. package/dist/sync/directoryLister.js.map +1 -0
  74. package/dist/sync/index.d.ts +29 -0
  75. package/dist/sync/index.d.ts.map +1 -0
  76. package/dist/sync/index.js +212 -0
  77. package/dist/sync/index.js.map +1 -0
  78. package/dist/sync/manifest.d.ts +48 -0
  79. package/dist/sync/manifest.d.ts.map +1 -0
  80. package/dist/sync/manifest.js +137 -0
  81. package/dist/sync/manifest.js.map +1 -0
  82. package/dist/sync/types.d.ts +109 -0
  83. package/dist/sync/types.d.ts.map +1 -0
  84. package/dist/sync/types.js +5 -0
  85. package/dist/sync/types.js.map +1 -0
  86. package/dist/sync/watchMode.d.ts +84 -0
  87. package/dist/sync/watchMode.d.ts.map +1 -0
  88. package/dist/sync/watchMode.js +364 -0
  89. package/dist/sync/watchMode.js.map +1 -0
  90. package/dist/sync/watcher.d.ts +114 -0
  91. package/dist/sync/watcher.d.ts.map +1 -0
  92. package/dist/sync/watcher.js +293 -0
  93. package/dist/sync/watcher.js.map +1 -0
  94. package/dist/utils/index.d.ts +8 -0
  95. package/dist/utils/index.d.ts.map +1 -0
  96. package/dist/utils/index.js +25 -0
  97. package/dist/utils/index.js.map +1 -0
  98. package/dist/vault/index.d.ts +38 -0
  99. package/dist/vault/index.d.ts.map +1 -0
  100. package/dist/vault/index.js +106 -0
  101. package/dist/vault/index.js.map +1 -0
  102. package/package.json +68 -0
@@ -0,0 +1,91 @@
1
+ import { select } from '@inquirer/prompts';
2
+ import * as fs from 'fs/promises';
3
+ import * as path from 'path';
4
+ import { theme, symbols } from '../ui/colors.js';
5
+ /**
6
+ * Check if a directory is an Obsidian vault
7
+ */
8
+ async function isObsidianVault(dirPath) {
9
+ try {
10
+ const obsidianPath = path.join(dirPath, '.obsidian');
11
+ const stat = await fs.stat(obsidianPath);
12
+ return stat.isDirectory();
13
+ }
14
+ catch {
15
+ return false;
16
+ }
17
+ }
18
+ /**
19
+ * Format a directory name with indicators
20
+ */
21
+ async function formatDirectoryName(name, fullPath) {
22
+ const isVault = await isObsidianVault(fullPath);
23
+ if (isVault) {
24
+ return `${symbols.vault} ${theme.highlight(name)} ${theme.muted('(Obsidian vault)')}`;
25
+ }
26
+ return `${symbols.folder} ${name}`;
27
+ }
28
+ /**
29
+ * Browse directories interactively
30
+ * Returns the selected directory path
31
+ */
32
+ export async function browseForDirectory(startPath) {
33
+ let currentPath = path.resolve(startPath);
34
+ while (true) {
35
+ // Get directory contents
36
+ let entries;
37
+ try {
38
+ const dirents = await fs.readdir(currentPath, { withFileTypes: true });
39
+ entries = dirents
40
+ .filter((d) => d.isDirectory())
41
+ .filter((d) => !d.name.startsWith('.')) // Hide hidden directories
42
+ .map((d) => ({ name: d.name }))
43
+ .sort((a, b) => a.name.localeCompare(b.name));
44
+ }
45
+ catch {
46
+ // If we can't read the directory, go up one level
47
+ currentPath = path.dirname(currentPath);
48
+ continue;
49
+ }
50
+ // Build choices
51
+ const choices = [];
52
+ // Add navigation options
53
+ choices.push({
54
+ value: '__SELECT__',
55
+ name: `${theme.success('\u2713')} ${theme.bold('Select this folder')} ${theme.muted(`(${currentPath})`)}`,
56
+ });
57
+ choices.push({
58
+ value: '__PARENT__',
59
+ name: `${theme.muted('..')} ${theme.muted('(parent directory)')}`,
60
+ });
61
+ // Add subdirectories
62
+ for (const entry of entries) {
63
+ const fullPath = path.join(currentPath, entry.name);
64
+ const formattedName = await formatDirectoryName(entry.name, fullPath);
65
+ choices.push({
66
+ value: entry.name,
67
+ name: formattedName,
68
+ });
69
+ }
70
+ // Show the prompt
71
+ const selection = await select({
72
+ message: `${theme.dim('Current:')} ${theme.cyan(currentPath)}`,
73
+ choices,
74
+ pageSize: 15,
75
+ });
76
+ // Handle selection
77
+ if (selection === '__SELECT__') {
78
+ return currentPath;
79
+ }
80
+ if (selection === '__PARENT__') {
81
+ const parentPath = path.dirname(currentPath);
82
+ if (parentPath !== currentPath) {
83
+ currentPath = parentPath;
84
+ }
85
+ continue;
86
+ }
87
+ // Navigate into subdirectory
88
+ currentPath = path.join(currentPath, selection);
89
+ }
90
+ }
91
+ //# sourceMappingURL=fileBrowser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileBrowser.js","sourceRoot":"","sources":["../../../src/cli/prompts/fileBrowser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Prompt the user to enter or browse for a vault path
3
+ */
4
+ export declare function promptForVaultPath(message: string): Promise<string>;
5
+ /**
6
+ * Prompt for source vault with context
7
+ */
8
+ export declare function promptForSourceVault(): Promise<string>;
9
+ /**
10
+ * Prompt for destination vault with context
11
+ */
12
+ export declare function promptForDestinationVault(): Promise<string>;
13
+ //# sourceMappingURL=vaultSelector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vaultSelector.d.ts","sourceRoot":"","sources":["../../../src/cli/prompts/vaultSelector.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA2CzE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAK5D;AAED;;GAEG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,MAAM,CAAC,CAKjE"}
@@ -0,0 +1,63 @@
1
+ import { input, confirm } from '@inquirer/prompts';
2
+ import path from 'path';
3
+ import { ObsidianVault } from '../../vault/index.js';
4
+ import { theme, formatPath } from '../ui/colors.js';
5
+ import { logWarning } from '../ui/output.js';
6
+ import { browseForDirectory } from './fileBrowser.js';
7
+ /**
8
+ * Prompt the user to enter or browse for a vault path
9
+ */
10
+ export async function promptForVaultPath(message) {
11
+ const useBrowser = await confirm({
12
+ message: 'Would you like to browse for the folder?',
13
+ default: true,
14
+ });
15
+ let selectedPath;
16
+ if (useBrowser) {
17
+ selectedPath = await browseForDirectory(process.cwd());
18
+ }
19
+ else {
20
+ selectedPath = await input({
21
+ message,
22
+ validate: async (value) => {
23
+ if (!value.trim()) {
24
+ return 'Path is required';
25
+ }
26
+ return true;
27
+ },
28
+ });
29
+ }
30
+ const resolvedPath = path.resolve(selectedPath);
31
+ // Validate it's an Obsidian vault
32
+ const vault = new ObsidianVault({ vaultPath: resolvedPath });
33
+ const isVault = await vault.isObsidianVault(resolvedPath);
34
+ if (!isVault) {
35
+ logWarning(`${formatPath(resolvedPath)} is not an Obsidian vault (no .obsidian directory)`);
36
+ const continueAnyway = await confirm({
37
+ message: 'Continue anyway?',
38
+ default: false,
39
+ });
40
+ if (!continueAnyway) {
41
+ // Recursively prompt again
42
+ return promptForVaultPath(message);
43
+ }
44
+ }
45
+ return resolvedPath;
46
+ }
47
+ /**
48
+ * Prompt for source vault with context
49
+ */
50
+ export async function promptForSourceVault() {
51
+ console.log(theme.bold('\nSelect source vault'));
52
+ console.log(theme.muted('This is the vault you want to sync FROM\n'));
53
+ return promptForVaultPath('Enter source vault path:');
54
+ }
55
+ /**
56
+ * Prompt for destination vault with context
57
+ */
58
+ export async function promptForDestinationVault() {
59
+ console.log(theme.bold('\nSelect destination vault'));
60
+ console.log(theme.muted('This is the vault you want to sync TO\n'));
61
+ return promptForVaultPath('Enter destination vault path:');
62
+ }
63
+ //# sourceMappingURL=vaultSelector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vaultSelector.js","sourceRoot":"","sources":["../../../src/cli/prompts/vaultSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAe;IACtD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC;QAC/B,OAAO,EAAE,0CAA0C;QACnD,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;IAEH,IAAI,YAAoB,CAAC;IAEzB,IAAI,UAAU,EAAE,CAAC;QACf,YAAY,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,YAAY,GAAG,MAAM,KAAK,CAAC;YACzB,OAAO;YACP,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACxB,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;oBAClB,OAAO,kBAAkB,CAAC;gBAC5B,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAEhD,kCAAkC;IAClC,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IAE1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,UAAU,CAAC,GAAG,UAAU,CAAC,YAAY,CAAC,oDAAoD,CAAC,CAAC;QAE5F,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC;YACnC,OAAO,EAAE,kBAAkB;YAC3B,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,2BAA2B;YAC3B,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC,CAAC;IAEtE,OAAO,kBAAkB,CAAC,0BAA0B,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB;IAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC,CAAC;IAEpE,OAAO,kBAAkB,CAAC,+BAA+B,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Semantic color theme for consistent CLI output
3
+ */
4
+ export declare const theme: {
5
+ success: import("picocolors/types").Formatter;
6
+ error: import("picocolors/types").Formatter;
7
+ warning: import("picocolors/types").Formatter;
8
+ info: import("picocolors/types").Formatter;
9
+ muted: import("picocolors/types").Formatter;
10
+ highlight: import("picocolors/types").Formatter;
11
+ cyan: import("picocolors/types").Formatter;
12
+ bold: import("picocolors/types").Formatter;
13
+ dim: import("picocolors/types").Formatter;
14
+ };
15
+ /**
16
+ * Unicode symbols for status indicators
17
+ */
18
+ export declare const symbols: {
19
+ success: string;
20
+ error: string;
21
+ warning: string;
22
+ info: string;
23
+ arrow: string;
24
+ bullet: string;
25
+ folder: string;
26
+ vault: string;
27
+ };
28
+ /**
29
+ * Format a label with a value
30
+ */
31
+ export declare function label(name: string, value: string | number): string;
32
+ /**
33
+ * Format a path for display
34
+ */
35
+ export declare function formatPath(filePath: string): string;
36
+ /**
37
+ * Format a number with appropriate color based on value
38
+ */
39
+ export declare function formatCount(count: number, options?: {
40
+ zeroMuted?: boolean;
41
+ }): string;
42
+ /**
43
+ * Create a header/title line
44
+ */
45
+ export declare function header(text: string): string;
46
+ /**
47
+ * Create a section divider
48
+ */
49
+ export declare function divider(width?: number): string;
50
+ //# sourceMappingURL=colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../../src/cli/ui/colors.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,KAAK;;;;;;;;;;CAUjB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO;;;;;;;;;CASnB,CAAC;AAEF;;GAEG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAElE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAKpF;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,GAAE,MAAW,GAAG,MAAM,CAElD"}
@@ -0,0 +1,62 @@
1
+ import pc from 'picocolors';
2
+ /**
3
+ * Semantic color theme for consistent CLI output
4
+ */
5
+ export const theme = {
6
+ success: pc.green,
7
+ error: pc.red,
8
+ warning: pc.yellow,
9
+ info: pc.blue,
10
+ muted: pc.gray,
11
+ highlight: pc.cyan,
12
+ cyan: pc.cyan,
13
+ bold: pc.bold,
14
+ dim: pc.dim,
15
+ };
16
+ /**
17
+ * Unicode symbols for status indicators
18
+ */
19
+ export const symbols = {
20
+ success: pc.green('\u2713'), // ✓
21
+ error: pc.red('\u2717'), // ✗
22
+ warning: pc.yellow('\u26A0'), // ⚠
23
+ info: pc.blue('\u2139'), // ℹ
24
+ arrow: pc.cyan('\u2192'), // →
25
+ bullet: pc.dim('\u2022'), // •
26
+ folder: '\uD83D\uDCC1', // 📁
27
+ vault: '\uD83D\uDDC4\uFE0F', // 🗄️
28
+ };
29
+ /**
30
+ * Format a label with a value
31
+ */
32
+ export function label(name, value) {
33
+ return `${pc.dim(name + ':')} ${value}`;
34
+ }
35
+ /**
36
+ * Format a path for display
37
+ */
38
+ export function formatPath(filePath) {
39
+ return pc.cyan(filePath);
40
+ }
41
+ /**
42
+ * Format a number with appropriate color based on value
43
+ */
44
+ export function formatCount(count, options) {
45
+ if (count === 0 && options?.zeroMuted) {
46
+ return pc.dim('0');
47
+ }
48
+ return count > 0 ? pc.bold(String(count)) : String(count);
49
+ }
50
+ /**
51
+ * Create a header/title line
52
+ */
53
+ export function header(text) {
54
+ return pc.bold(pc.underline(text));
55
+ }
56
+ /**
57
+ * Create a section divider
58
+ */
59
+ export function divider(width = 40) {
60
+ return pc.dim('\u2500'.repeat(width));
61
+ }
62
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../../src/cli/ui/colors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;GAEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,OAAO,EAAE,EAAE,CAAC,KAAK;IACjB,KAAK,EAAE,EAAE,CAAC,GAAG;IACb,OAAO,EAAE,EAAE,CAAC,MAAM;IAClB,IAAI,EAAE,EAAE,CAAC,IAAI;IACb,KAAK,EAAE,EAAE,CAAC,IAAI;IACd,SAAS,EAAE,EAAE,CAAC,IAAI;IAClB,IAAI,EAAE,EAAE,CAAC,IAAI;IACb,IAAI,EAAE,EAAE,CAAC,IAAI;IACb,GAAG,EAAE,EAAE,CAAC,GAAG;CACZ,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI;IACjC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI;IAC7B,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI;IAClC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI;IAC7B,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI;IAC9B,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI;IAC9B,MAAM,EAAE,cAAc,EAAE,KAAK;IAC7B,KAAK,EAAE,oBAAoB,EAAE,MAAM;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,KAAsB;IACxD,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,OAAiC;IAC1E,IAAI,KAAK,KAAK,CAAC,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,QAAgB,EAAE;IACxC,OAAO,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Log a success message with a green checkmark
3
+ */
4
+ export declare function logSuccess(message: string): void;
5
+ /**
6
+ * Log an error message with a red X
7
+ */
8
+ export declare function logError(message: string): void;
9
+ /**
10
+ * Log a warning message with a yellow warning sign
11
+ */
12
+ export declare function logWarning(message: string): void;
13
+ /**
14
+ * Log an info message with a blue info symbol
15
+ */
16
+ export declare function logInfo(message: string): void;
17
+ /**
18
+ * Log a muted/dimmed message
19
+ */
20
+ export declare function logMuted(message: string): void;
21
+ /**
22
+ * Log a blank line
23
+ */
24
+ export declare function logBlank(): void;
25
+ /**
26
+ * Log a key-value pair with formatting
27
+ */
28
+ export declare function logKeyValue(key: string, value: string | number, indent?: number): void;
29
+ /**
30
+ * Log a section header
31
+ */
32
+ export declare function logHeader(title: string): void;
33
+ /**
34
+ * Log a list item with a bullet point
35
+ */
36
+ export declare function logListItem(item: string, indent?: number): void;
37
+ /**
38
+ * Print an error and exit the process
39
+ */
40
+ export declare function exitWithError(message: string, code?: number): never;
41
+ /**
42
+ * Check if running in interactive mode
43
+ */
44
+ export declare function requireInteractive(featureName: string): void;
45
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/cli/ui/output.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAMhD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAM9C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAMhD;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAM7C;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAM9C;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,IAAI,CAE/B;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,GAAE,MAAU,GAAG,IAAI,CAOzF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAQ7C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,GAAG,IAAI,CAOlE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU,GAAG,KAAK,CAGtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAM5D"}
@@ -0,0 +1,116 @@
1
+ import { theme, symbols } from './colors.js';
2
+ import { isInteractive, supportsColor } from '../utils/terminal.js';
3
+ /**
4
+ * Log a success message with a green checkmark
5
+ */
6
+ export function logSuccess(message) {
7
+ if (supportsColor()) {
8
+ console.log(`${symbols.success} ${theme.success(message)}`);
9
+ }
10
+ else {
11
+ console.log(`[OK] ${message}`);
12
+ }
13
+ }
14
+ /**
15
+ * Log an error message with a red X
16
+ */
17
+ export function logError(message) {
18
+ if (supportsColor()) {
19
+ console.error(`${symbols.error} ${theme.error(message)}`);
20
+ }
21
+ else {
22
+ console.error(`[ERROR] ${message}`);
23
+ }
24
+ }
25
+ /**
26
+ * Log a warning message with a yellow warning sign
27
+ */
28
+ export function logWarning(message) {
29
+ if (supportsColor()) {
30
+ console.log(`${symbols.warning} ${theme.warning(message)}`);
31
+ }
32
+ else {
33
+ console.log(`[WARN] ${message}`);
34
+ }
35
+ }
36
+ /**
37
+ * Log an info message with a blue info symbol
38
+ */
39
+ export function logInfo(message) {
40
+ if (supportsColor()) {
41
+ console.log(`${symbols.info} ${theme.info(message)}`);
42
+ }
43
+ else {
44
+ console.log(`[INFO] ${message}`);
45
+ }
46
+ }
47
+ /**
48
+ * Log a muted/dimmed message
49
+ */
50
+ export function logMuted(message) {
51
+ if (supportsColor()) {
52
+ console.log(theme.muted(message));
53
+ }
54
+ else {
55
+ console.log(message);
56
+ }
57
+ }
58
+ /**
59
+ * Log a blank line
60
+ */
61
+ export function logBlank() {
62
+ console.log();
63
+ }
64
+ /**
65
+ * Log a key-value pair with formatting
66
+ */
67
+ export function logKeyValue(key, value, indent = 0) {
68
+ const padding = ' '.repeat(indent);
69
+ if (supportsColor()) {
70
+ console.log(`${padding}${theme.dim(key + ':')} ${value}`);
71
+ }
72
+ else {
73
+ console.log(`${padding}${key}: ${value}`);
74
+ }
75
+ }
76
+ /**
77
+ * Log a section header
78
+ */
79
+ export function logHeader(title) {
80
+ logBlank();
81
+ if (supportsColor()) {
82
+ console.log(theme.bold(title));
83
+ }
84
+ else {
85
+ console.log(title);
86
+ console.log('='.repeat(title.length));
87
+ }
88
+ }
89
+ /**
90
+ * Log a list item with a bullet point
91
+ */
92
+ export function logListItem(item, indent = 2) {
93
+ const padding = ' '.repeat(indent);
94
+ if (supportsColor()) {
95
+ console.log(`${padding}${symbols.bullet} ${item}`);
96
+ }
97
+ else {
98
+ console.log(`${padding}- ${item}`);
99
+ }
100
+ }
101
+ /**
102
+ * Print an error and exit the process
103
+ */
104
+ export function exitWithError(message, code = 1) {
105
+ logError(message);
106
+ process.exit(code);
107
+ }
108
+ /**
109
+ * Check if running in interactive mode
110
+ */
111
+ export function requireInteractive(featureName) {
112
+ if (!isInteractive()) {
113
+ exitWithError(`${featureName} requires an interactive terminal. Please provide all required options via command line flags.`);
114
+ }
115
+ }
116
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/cli/ui/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Spinner instance interface for consistent API
3
+ */
4
+ export interface SpinnerInstance {
5
+ start(): SpinnerInstance;
6
+ stop(): SpinnerInstance;
7
+ succeed(text?: string): SpinnerInstance;
8
+ fail(text?: string): SpinnerInstance;
9
+ warn(text?: string): SpinnerInstance;
10
+ info(text?: string): SpinnerInstance;
11
+ text: string;
12
+ }
13
+ /**
14
+ * Create a spinner with consistent styling
15
+ * Falls back to simple text output in non-interactive mode
16
+ */
17
+ export declare function createSpinner(text: string): SpinnerInstance;
18
+ /**
19
+ * Create a spinner and immediately start it
20
+ */
21
+ export declare function startSpinner(text: string): SpinnerInstance;
22
+ /**
23
+ * Run an async operation with a spinner
24
+ */
25
+ export declare function withSpinner<T>(text: string, operation: () => Promise<T>, options?: {
26
+ successText?: string | ((result: T) => string);
27
+ failText?: string;
28
+ }): Promise<T>;
29
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../../src/cli/ui/spinner.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,IAAI,eAAe,CAAC;IACzB,IAAI,IAAI,eAAe,CAAC;IACxB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;IACxC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;IACrC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;IACrC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAkDD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAU3D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAG1D;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,OAAO,CAAC,EAAE;IACR,WAAW,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,CAAC,CAAC,CAeZ"}
@@ -0,0 +1,80 @@
1
+ import ora from 'ora';
2
+ import { isInteractive } from '../utils/terminal.js';
3
+ /**
4
+ * Non-interactive fallback spinner that just logs text
5
+ */
6
+ class FallbackSpinner {
7
+ _text;
8
+ constructor(text) {
9
+ this._text = text;
10
+ }
11
+ get text() {
12
+ return this._text;
13
+ }
14
+ set text(value) {
15
+ this._text = value;
16
+ }
17
+ start() {
18
+ console.log(`[...] ${this._text}`);
19
+ return this;
20
+ }
21
+ stop() {
22
+ return this;
23
+ }
24
+ succeed(text) {
25
+ console.log(`[OK] ${text || this._text}`);
26
+ return this;
27
+ }
28
+ fail(text) {
29
+ console.error(`[FAIL] ${text || this._text}`);
30
+ return this;
31
+ }
32
+ warn(text) {
33
+ console.log(`[WARN] ${text || this._text}`);
34
+ return this;
35
+ }
36
+ info(text) {
37
+ console.log(`[INFO] ${text || this._text}`);
38
+ return this;
39
+ }
40
+ }
41
+ /**
42
+ * Create a spinner with consistent styling
43
+ * Falls back to simple text output in non-interactive mode
44
+ */
45
+ export function createSpinner(text) {
46
+ if (!isInteractive()) {
47
+ return new FallbackSpinner(text);
48
+ }
49
+ return ora({
50
+ text,
51
+ spinner: 'dots',
52
+ color: 'cyan',
53
+ });
54
+ }
55
+ /**
56
+ * Create a spinner and immediately start it
57
+ */
58
+ export function startSpinner(text) {
59
+ const spinner = createSpinner(text);
60
+ return spinner.start();
61
+ }
62
+ /**
63
+ * Run an async operation with a spinner
64
+ */
65
+ export async function withSpinner(text, operation, options) {
66
+ const spinner = startSpinner(text);
67
+ try {
68
+ const result = await operation();
69
+ const successText = typeof options?.successText === 'function'
70
+ ? options.successText(result)
71
+ : options?.successText;
72
+ spinner.succeed(successText);
73
+ return result;
74
+ }
75
+ catch (error) {
76
+ spinner.fail(options?.failText);
77
+ throw error;
78
+ }
79
+ }
80
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../../src/cli/ui/spinner.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAerD;;GAEG;AACH,MAAM,eAAe;IACX,KAAK,CAAS;IAEtB,YAAY,IAAY;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAI,IAAI,CAAC,KAAa;QACpB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,KAAK;QACH,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,IAAa;QACnB,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAa;QAChB,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAa;QAChB,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAa;QAChB,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,GAAG,CAAC;QACT,IAAI;QACJ,OAAO,EAAE,MAAM;QACf,KAAK,EAAE,MAAM;KACd,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,SAA2B,EAC3B,OAGC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAEnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,WAAW,GACf,OAAO,OAAO,EAAE,WAAW,KAAK,UAAU;YACxC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC;YAC7B,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC;QAC3B,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { SyncResult } from '../../sync/types.js';
2
+ /**
3
+ * Format sync results as formatted text
4
+ */
5
+ export declare function formatSyncResultTable(result: SyncResult): string;
6
+ /**
7
+ * Format vault status information
8
+ */
9
+ export declare function formatVaultInfoTable(info: {
10
+ name: string;
11
+ path: string;
12
+ fileCount: number;
13
+ totalSize: string;
14
+ lastModified: string;
15
+ }): string;
16
+ /**
17
+ * Format sync status
18
+ */
19
+ export declare function formatSyncStatusTable(status: {
20
+ syncId: string;
21
+ lastSync: string;
22
+ trackedFiles: number;
23
+ }): string;
24
+ /**
25
+ * Format a list of files with an optional header
26
+ */
27
+ export declare function formatFileList(files: string[], header: string, maxItems?: number): string;
28
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/cli/ui/table.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAqDhE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAsBT;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAoBT;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAW,GACpB,MAAM,CAmBR"}