@tuskydp/cli 0.2.0 → 0.3.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 (104) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/src/commands/decrypt.d.ts.map +1 -1
  3. package/dist/src/commands/decrypt.js +53 -21
  4. package/dist/src/commands/decrypt.js.map +1 -1
  5. package/dist/src/commands/download.d.ts +1 -0
  6. package/dist/src/commands/download.d.ts.map +1 -1
  7. package/dist/src/commands/download.js +81 -11
  8. package/dist/src/commands/download.js.map +1 -1
  9. package/dist/src/commands/export.d.ts +6 -0
  10. package/dist/src/commands/export.d.ts.map +1 -1
  11. package/dist/src/commands/export.js +29 -17
  12. package/dist/src/commands/export.js.map +1 -1
  13. package/dist/src/commands/files.d.ts.map +1 -1
  14. package/dist/src/commands/files.js +89 -10
  15. package/dist/src/commands/files.js.map +1 -1
  16. package/dist/src/commands/folder.d.ts +3 -0
  17. package/dist/src/commands/folder.d.ts.map +1 -0
  18. package/dist/src/commands/folder.js +151 -0
  19. package/dist/src/commands/folder.js.map +1 -0
  20. package/dist/src/commands/rehydrate.d.ts +1 -0
  21. package/dist/src/commands/rehydrate.d.ts.map +1 -1
  22. package/dist/src/commands/rehydrate.js +15 -7
  23. package/dist/src/commands/rehydrate.js.map +1 -1
  24. package/dist/src/commands/trash.d.ts +3 -0
  25. package/dist/src/commands/trash.d.ts.map +1 -0
  26. package/dist/src/commands/trash.js +109 -0
  27. package/dist/src/commands/trash.js.map +1 -0
  28. package/dist/src/commands/upload.d.ts +4 -0
  29. package/dist/src/commands/upload.d.ts.map +1 -1
  30. package/dist/src/commands/upload.js +104 -3
  31. package/dist/src/commands/upload.js.map +1 -1
  32. package/dist/src/commands/wallet.d.ts +3 -0
  33. package/dist/src/commands/wallet.d.ts.map +1 -0
  34. package/dist/src/commands/wallet.js +126 -0
  35. package/dist/src/commands/wallet.js.map +1 -0
  36. package/dist/src/commands/webhook.d.ts +3 -0
  37. package/dist/src/commands/webhook.d.ts.map +1 -0
  38. package/dist/src/commands/webhook.js +172 -0
  39. package/dist/src/commands/webhook.js.map +1 -0
  40. package/dist/src/crypto.d.ts +16 -0
  41. package/dist/src/crypto.d.ts.map +1 -1
  42. package/dist/src/crypto.js +26 -0
  43. package/dist/src/crypto.js.map +1 -1
  44. package/dist/src/index.js +17 -3
  45. package/dist/src/index.js.map +1 -1
  46. package/dist/src/mcp/server.d.ts.map +1 -1
  47. package/dist/src/mcp/server.js +2 -1
  48. package/dist/src/mcp/server.js.map +1 -1
  49. package/dist/src/mcp/tools/files.d.ts.map +1 -1
  50. package/dist/src/mcp/tools/files.js +40 -5
  51. package/dist/src/mcp/tools/files.js.map +1 -1
  52. package/dist/src/seal.d.ts +16 -0
  53. package/dist/src/seal.d.ts.map +1 -1
  54. package/dist/src/seal.js +23 -0
  55. package/dist/src/seal.js.map +1 -1
  56. package/dist/src/tui/files-panel.d.ts +31 -1
  57. package/dist/src/tui/files-panel.d.ts.map +1 -1
  58. package/dist/src/tui/files-panel.js +118 -11
  59. package/dist/src/tui/files-panel.js.map +1 -1
  60. package/dist/src/tui/index.d.ts.map +1 -1
  61. package/dist/src/tui/index.js +272 -33
  62. package/dist/src/tui/index.js.map +1 -1
  63. package/dist/src/tui/overview.d.ts.map +1 -1
  64. package/dist/src/tui/overview.js +24 -8
  65. package/dist/src/tui/overview.js.map +1 -1
  66. package/dist/src/tui/trash-screen.d.ts +4 -0
  67. package/dist/src/tui/trash-screen.d.ts.map +1 -0
  68. package/dist/src/tui/trash-screen.js +190 -0
  69. package/dist/src/tui/trash-screen.js.map +1 -0
  70. package/dist/src/tui/vaults-panel.d.ts +8 -0
  71. package/dist/src/tui/vaults-panel.d.ts.map +1 -1
  72. package/dist/src/tui/vaults-panel.js +45 -6
  73. package/dist/src/tui/vaults-panel.js.map +1 -1
  74. package/dist/src/version.d.ts +2 -0
  75. package/dist/src/version.d.ts.map +1 -0
  76. package/dist/src/version.js +21 -0
  77. package/dist/src/version.js.map +1 -0
  78. package/package.json +3 -3
  79. package/src/commands/decrypt.ts +56 -23
  80. package/src/commands/download.ts +82 -11
  81. package/src/commands/export.ts +35 -19
  82. package/src/commands/files.ts +93 -9
  83. package/src/commands/folder.ts +169 -0
  84. package/src/commands/rehydrate.ts +15 -8
  85. package/src/commands/trash.ts +121 -0
  86. package/src/commands/upload.ts +126 -3
  87. package/src/commands/wallet.ts +183 -0
  88. package/src/commands/webhook.ts +193 -0
  89. package/src/crypto.ts +35 -0
  90. package/src/index.ts +17 -4
  91. package/src/mcp/server.ts +2 -1
  92. package/src/mcp/tools/files.ts +43 -5
  93. package/src/seal.ts +34 -1
  94. package/src/tui/files-panel.ts +139 -11
  95. package/src/tui/index.ts +289 -33
  96. package/src/tui/overview.ts +22 -8
  97. package/src/tui/trash-screen.ts +203 -0
  98. package/src/tui/vaults-panel.ts +55 -6
  99. package/src/version.ts +21 -0
  100. package/vitest.config.ts +1 -0
  101. package/dist/src/client.d.ts +0 -120
  102. package/dist/src/client.d.ts.map +0 -1
  103. package/dist/src/client.js +0 -152
  104. package/dist/src/client.js.map +0 -1
@@ -0,0 +1,4 @@
1
+ import blessed from 'blessed';
2
+ import type { TuskyClient } from '@tuskydp/sdk';
3
+ export declare function showTrashScreen(screen: blessed.Widgets.Screen, sdk: TuskyClient): Promise<void>;
4
+ //# sourceMappingURL=trash-screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trash-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/trash-screen.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,wBAAsB,eAAe,CACnC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAC9B,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,IAAI,CAAC,CAmMf"}
@@ -0,0 +1,190 @@
1
+ import blessed from 'blessed';
2
+ import { formatBytes, formatDate, showError, showMessage } from './helpers.js';
3
+ export async function showTrashScreen(screen, sdk) {
4
+ return new Promise((resolve) => {
5
+ const container = blessed.box({
6
+ parent: screen,
7
+ top: 0,
8
+ left: 0,
9
+ width: '100%',
10
+ height: '100%',
11
+ tags: true,
12
+ border: { type: 'line' },
13
+ style: {
14
+ border: { fg: 'yellow' },
15
+ fg: 'white',
16
+ },
17
+ label: ' Trash ',
18
+ });
19
+ const list = blessed.list({
20
+ parent: container,
21
+ top: 0,
22
+ left: 0,
23
+ width: '100%',
24
+ height: '100%-3',
25
+ style: {
26
+ fg: 'white',
27
+ selected: { bg: 'yellow', fg: 'black' },
28
+ },
29
+ keys: true,
30
+ vi: true,
31
+ interactive: true,
32
+ scrollable: true,
33
+ alwaysScroll: true,
34
+ scrollbar: { style: { bg: 'yellow' } },
35
+ tags: true,
36
+ padding: { left: 1, right: 1 },
37
+ });
38
+ const hint = blessed.box({
39
+ parent: container,
40
+ bottom: 0,
41
+ left: 0,
42
+ width: '100%',
43
+ height: 1,
44
+ tags: true,
45
+ style: { fg: 'gray' },
46
+ content: ' {bold}r{/bold} restore {bold}d{/bold} permanent delete {bold}e{/bold} empty all {bold}Esc{/bold} back',
47
+ });
48
+ let items = [];
49
+ async function loadTrash() {
50
+ list.setItems(['Loading trash...']);
51
+ screen.render();
52
+ try {
53
+ const trashed = await sdk.trash.list();
54
+ items = [];
55
+ for (const v of trashed.vaults) {
56
+ items.push({
57
+ id: v.id,
58
+ type: 'vault',
59
+ name: v.name,
60
+ size: v.totalSizeBytes,
61
+ deletedAt: v.deletedAt || '',
62
+ });
63
+ }
64
+ for (const f of trashed.files) {
65
+ items.push({
66
+ id: f.id,
67
+ type: 'file',
68
+ name: f.name,
69
+ size: f.plaintextSizeBytes || f.sizeBytes,
70
+ deletedAt: f.deletedAt || '',
71
+ });
72
+ }
73
+ if (items.length === 0) {
74
+ list.setItems(['{gray-fg}Trash is empty.{/gray-fg}']);
75
+ }
76
+ else {
77
+ const listItems = items.map((item) => {
78
+ const typeTag = item.type === 'vault'
79
+ ? '{yellow-fg}[vault]{/yellow-fg}'
80
+ : '{cyan-fg}[file]{/cyan-fg} ';
81
+ const deleted = item.deletedAt ? formatDate(item.deletedAt) : 'N/A';
82
+ return ` ${typeTag} ${item.name} ${formatBytes(item.size)} deleted ${deleted}`;
83
+ });
84
+ list.setItems(listItems);
85
+ }
86
+ list.select(0);
87
+ screen.render();
88
+ }
89
+ catch (err) {
90
+ list.setItems([`{red-fg}Error: ${err.message}{/red-fg}`]);
91
+ screen.render();
92
+ }
93
+ }
94
+ function close() {
95
+ container.destroy();
96
+ screen.render();
97
+ resolve();
98
+ }
99
+ // Restore
100
+ list.key(['r'], async () => {
101
+ const idx = list.selected;
102
+ const entry = items[idx];
103
+ if (!entry)
104
+ return;
105
+ try {
106
+ await sdk.trash.restore(entry.id);
107
+ showMessage(screen, `Restored: ${entry.name}`, ' Trash ');
108
+ await loadTrash();
109
+ }
110
+ catch (err) {
111
+ showError(screen, err.message);
112
+ }
113
+ });
114
+ // Permanent delete
115
+ list.key(['d'], async () => {
116
+ const idx = list.selected;
117
+ const entry = items[idx];
118
+ if (!entry)
119
+ return;
120
+ // Inline confirm via question
121
+ const dialog = blessed.question({
122
+ parent: screen,
123
+ top: 'center',
124
+ left: 'center',
125
+ width: '50%',
126
+ height: 'shrink',
127
+ border: { type: 'line' },
128
+ style: { border: { fg: 'red' }, fg: 'white' },
129
+ label: ' Confirm ',
130
+ tags: true,
131
+ keys: true,
132
+ vi: true,
133
+ });
134
+ dialog.ask(`Permanently delete "${entry.name}"? (cannot be undone)`, async (err, value) => {
135
+ dialog.destroy();
136
+ screen.render();
137
+ if (!err && value) {
138
+ try {
139
+ await sdk.trash.delete(entry.id);
140
+ showMessage(screen, `Permanently deleted: ${entry.name}`, ' Trash ');
141
+ await loadTrash();
142
+ }
143
+ catch (e) {
144
+ showError(screen, e.message);
145
+ }
146
+ }
147
+ list.focus();
148
+ });
149
+ });
150
+ // Empty all trash
151
+ list.key(['e'], async () => {
152
+ if (items.length === 0)
153
+ return;
154
+ const dialog = blessed.question({
155
+ parent: screen,
156
+ top: 'center',
157
+ left: 'center',
158
+ width: '50%',
159
+ height: 'shrink',
160
+ border: { type: 'line' },
161
+ style: { border: { fg: 'red' }, fg: 'white' },
162
+ label: ' Confirm ',
163
+ tags: true,
164
+ keys: true,
165
+ vi: true,
166
+ });
167
+ dialog.ask('Permanently delete ALL trashed items? (cannot be undone)', async (err, value) => {
168
+ dialog.destroy();
169
+ screen.render();
170
+ if (!err && value) {
171
+ try {
172
+ await sdk.trash.empty();
173
+ showMessage(screen, 'Trash emptied', ' Trash ');
174
+ await loadTrash();
175
+ }
176
+ catch (e) {
177
+ showError(screen, e.message);
178
+ }
179
+ }
180
+ list.focus();
181
+ });
182
+ });
183
+ container.key(['escape', 'q'], close);
184
+ list.key(['escape'], close);
185
+ loadTrash();
186
+ list.focus();
187
+ screen.render();
188
+ });
189
+ }
190
+ //# sourceMappingURL=trash-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trash-screen.js","sourceRoot":"","sources":["../../../src/tui/trash-screen.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,14 @@ export interface VaultItem {
7
7
  visibility: string;
8
8
  fileCount: number;
9
9
  totalSizeBytes: number;
10
+ description: string | null;
11
+ sealAllowlistObjectId?: string | null;
12
+ sealPackageId?: string | null;
13
+ sealKeyServerIds?: string[] | null;
14
+ sealThreshold?: number | null;
15
+ createdAt: string;
16
+ isSharedMembership?: boolean;
17
+ memberRole?: string;
10
18
  }
11
19
  export declare class VaultsPanel {
12
20
  list: blessed.Widgets.ListElement;
@@ -1 +1 @@
1
- {"version":3,"file":"vaults-panel.d.ts","sourceRoot":"","sources":["../../../src/tui/vaults-panel.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,WAAW;IACtB,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;IAClC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAA6B;gBAG3C,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAC9B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,EAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI;IA4ChC,IAAI;IAkDV,WAAW,IAAI,SAAS,GAAG,IAAI;IAK/B,SAAS,IAAI,SAAS,EAAE;IAIxB,KAAK;IAML,IAAI;IAKJ,OAAO;CAGR"}
1
+ {"version":3,"file":"vaults-panel.d.ts","sourceRoot":"","sources":["../../../src/tui/vaults-panel.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAElB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,WAAW;IACtB,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;IAClC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAA6B;gBAG3C,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAC9B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,EAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI;IA4ChC,IAAI;IAyFV,WAAW,IAAI,SAAS,GAAG,IAAI;IAK/B,SAAS,IAAI,SAAS,EAAE;IAIxB,KAAK;IAML,IAAI;IAKJ,OAAO;CAGR"}
@@ -54,15 +54,40 @@ export class VaultsPanel {
54
54
  this.list.setItems(['Loading vaults...']);
55
55
  this.screen.render();
56
56
  try {
57
- const vaults = await this.sdk.vaults.list();
58
- this.vaults = vaults.map((v) => ({
57
+ // Fetch owned vaults + shared vault memberships in parallel
58
+ const [ownedVaults, sharedResult] = await Promise.all([
59
+ this.sdk.vaults.list(),
60
+ this.sdk.sharedVaults.list().catch(() => ({ vaults: [] })),
61
+ ]);
62
+ this.vaults = ownedVaults.map((v) => ({
59
63
  id: v.id,
60
64
  name: v.name,
61
65
  slug: v.slug,
62
66
  visibility: v.visibility,
63
67
  fileCount: v.fileCount || 0,
64
68
  totalSizeBytes: v.totalSizeBytes || 0,
69
+ description: v.description,
70
+ sealAllowlistObjectId: v.sealAllowlistObjectId,
71
+ sealPackageId: v.sealPackageId,
72
+ sealKeyServerIds: v.sealKeyServerIds,
73
+ sealThreshold: v.sealThreshold,
74
+ createdAt: v.createdAt,
65
75
  }));
76
+ // Append shared vault memberships (vaults user doesn't own but has access to)
77
+ for (const entry of sharedResult.vaults) {
78
+ this.vaults.push({
79
+ id: entry.vault.id,
80
+ name: entry.vault.name,
81
+ slug: entry.vault.slug,
82
+ visibility: 'shared',
83
+ fileCount: entry.vault.fileCount || 0,
84
+ totalSizeBytes: entry.vault.totalSizeBytes || 0,
85
+ description: entry.vault.description,
86
+ createdAt: entry.grantedAt,
87
+ isSharedMembership: true,
88
+ memberRole: entry.role,
89
+ });
90
+ }
66
91
  if (this.vaults.length === 0) {
67
92
  this.list.setItems(['(no vaults — press n to create)']);
68
93
  }
@@ -70,15 +95,29 @@ export class VaultsPanel {
70
95
  // Calculate available width (subtract border + padding)
71
96
  const totalW = this.list.width - 4;
72
97
  const filesW = 7; // "999 files" max ~9
73
- const visW = 7; // "private"
98
+ const visW = 8; // "shared" + tag
74
99
  const sizeW = 9; // "999.9 GB"
75
100
  const nameW = Math.max(8, totalW - filesW - visW - sizeW - 3);
76
101
  const items = this.vaults.map((v) => {
77
- const vis = v.visibility === 'private' ? 'private' : 'public';
78
- const visTagged = v.visibility === 'private' ? '{yellow-fg}private{/yellow-fg}' : '{green-fg}public{/green-fg}';
102
+ let vis;
103
+ let visTagged;
104
+ if (v.visibility === 'private') {
105
+ vis = 'private';
106
+ visTagged = '{yellow-fg}private{/yellow-fg}';
107
+ }
108
+ else if (v.visibility === 'shared') {
109
+ vis = v.isSharedMembership ? 'member' : 'shared';
110
+ visTagged = v.isSharedMembership
111
+ ? '{magenta-fg}member{/magenta-fg}'
112
+ : '{magenta-fg}shared{/magenta-fg}';
113
+ }
114
+ else {
115
+ vis = 'public';
116
+ visTagged = '{green-fg}public{/green-fg}';
117
+ }
79
118
  const size = formatBytes(v.totalSizeBytes);
80
119
  const files = `${v.fileCount}`;
81
- const name = v.name.length > nameW ? v.name.slice(0, nameW - 1) + '' : v.name;
120
+ const name = v.name.length > nameW ? v.name.slice(0, nameW - 1) + '...' : v.name;
82
121
  return formatRow([
83
122
  { text: name, width: nameW },
84
123
  { text: vis, tagged: visTagged, width: visW },
@@ -1 +1 @@
1
- {"version":3,"file":"vaults-panel.js","sourceRoot":"","sources":["../../../src/tui/vaults-panel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vaults-panel.js","sourceRoot":"","sources":["../../../src/tui/vaults-panel.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAqBvE,MAAM,OAAO,WAAW;IACtB,IAAI,CAA8B;IAC1B,MAAM,CAAyB;IAC/B,GAAG,CAAc;IACjB,MAAM,GAAgB,EAAE,CAAC;IACzB,OAAO,GAAG,KAAK,CAAC;IAChB,QAAQ,CAA6B;IAE7C,YACE,MAA8B,EAC9B,GAAgB,EAChB,MAAkC,EAClC,QAAoC;QAEpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YACvB,MAAM;YACN,GAAG,EAAE,CAAC;YACN,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACxB,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;gBACtB,EAAE,EAAE,OAAO;gBACX,QAAQ,EAAE;oBACR,EAAE,EAAE,MAAM;oBACV,EAAE,EAAE,OAAO;iBACZ;gBACD,KAAK,EAAE;oBACL,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE;iBACxB;aACF;YACD,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,IAAI;YACV,EAAE,EAAE,IAAI;YACR,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,IAAI;YAChB,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE;gBACT,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;aACtB;SACF,CAAC,CAAC;QAEH,wEAAwE;QACxE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,KAAU,EAAE,KAAa,EAAE,EAAE;YACxD,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,mBAAmB,CAAQ,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAErB,IAAI,CAAC;YACH,4DAA4D;YAC5D,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACpD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;gBACtB,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;aAC3D,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpC,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC;gBAC3B,cAAc,EAAE,CAAC,CAAC,cAAc,IAAI,CAAC;gBACrC,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,qBAAqB,EAAE,CAAC,CAAC,qBAAqB;gBAC9C,aAAa,EAAE,CAAC,CAAC,aAAa;gBAC9B,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,aAAa,EAAE,CAAC,CAAC,aAAa;gBAC9B,SAAS,EAAE,CAAC,CAAC,SAAS;aACvB,CAAC,CAAC,CAAC;YAEJ,8EAA8E;YAC9E,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;gBACxC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;oBACf,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;oBAClB,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;oBACtB,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;oBACtB,UAAU,EAAE,QAAQ;oBACpB,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC;oBACrC,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC;oBAC/C,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW;oBACpC,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,kBAAkB,EAAE,IAAI;oBACxB,UAAU,EAAE,KAAK,CAAC,IAAI;iBACvB,CAAC,CAAC;YACL,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,iCAAiC,CAAQ,CAAC,CAAC;YACjE,CAAC;iBAAM,CAAC;gBACN,wDAAwD;gBACxD,MAAM,MAAM,GAAI,IAAI,CAAC,IAAI,CAAC,KAAgB,GAAG,CAAC,CAAC;gBAC/C,MAAM,MAAM,GAAG,CAAC,CAAC,CAAE,qBAAqB;gBACxC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAI,iBAAiB;gBACpC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAG,aAAa;gBAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;gBAE9D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBAClC,IAAI,GAAW,CAAC;oBAChB,IAAI,SAAiB,CAAC;oBACtB,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;wBAC/B,GAAG,GAAG,SAAS,CAAC;wBAChB,SAAS,GAAG,gCAAgC,CAAC;oBAC/C,CAAC;yBAAM,IAAI,CAAC,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;wBACrC,GAAG,GAAG,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;wBACjD,SAAS,GAAG,CAAC,CAAC,kBAAkB;4BAC9B,CAAC,CAAC,iCAAiC;4BACnC,CAAC,CAAC,iCAAiC,CAAC;oBACxC,CAAC;yBAAM,CAAC;wBACN,GAAG,GAAG,QAAQ,CAAC;wBACf,SAAS,GAAG,6BAA6B,CAAC;oBAC5C,CAAC;oBACD,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;oBAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC;oBAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBACjF,OAAO,SAAS,CAAC;wBACf,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;wBAC5B,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE;wBAC7C,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE;wBAC9C,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE;qBAC7C,EAAE,MAAM,CAAC,CAAC;gBACb,CAAC,CAAC,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAY,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAQ,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;IAED,WAAW;QACT,MAAM,GAAG,GAAI,IAAI,CAAC,IAAY,CAAC,QAAkB,CAAC;QAClD,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IAClC,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,WAAW,EAAS,CAAC;QACtE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,MAAM,EAAS,CAAC;QACjE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;IAED,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export declare const CLI_VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,WAAW,EAAE,MAAsB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ function loadVersion() {
6
+ // Walk up from current dir until we find package.json with our package name
7
+ let dir = __dirname;
8
+ for (let i = 0; i < 5; i++) {
9
+ try {
10
+ const pkgPath = resolve(dir, 'package.json');
11
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
12
+ if (pkg.name === '@tuskydp/cli')
13
+ return pkg.version;
14
+ }
15
+ catch { /* keep walking */ }
16
+ dir = resolve(dir, '..');
17
+ }
18
+ return '0.0.0';
19
+ }
20
+ export const CLI_VERSION = loadVersion();
21
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,SAAS,WAAW;IAClB,4EAA4E;IAC5E,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YACvD,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc;gBAAE,OAAO,GAAG,CAAC,OAAO,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAC9B,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAW,WAAW,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuskydp/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "tusky": "./dist/bin/tuskydp.js",
@@ -19,8 +19,8 @@
19
19
  "mime-types": "^3.0.0",
20
20
  "ora": "^8.0.0",
21
21
  "zod": "3",
22
- "@tuskydp/sdk": "0.2.0",
23
- "@tuskydp/shared": "0.2.0"
22
+ "@tuskydp/sdk": "0.3.0",
23
+ "@tuskydp/shared": "0.3.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/blessed": "^0.1.27",
@@ -15,6 +15,7 @@ import type { Command } from 'commander';
15
15
  import { readFileSync, writeFileSync, existsSync } from 'fs';
16
16
  import { resolve, basename } from 'path';
17
17
  import chalk from 'chalk';
18
+ import ora from 'ora';
18
19
  import inquirer from 'inquirer';
19
20
  import { getApiUrl, getApiKey } from '../config.js';
20
21
  import { createSDKClient } from '../sdk.js';
@@ -87,19 +88,32 @@ async function resolveMasterKey(options: {
87
88
  // Command registration
88
89
  // ---------------------------------------------------------------------------
89
90
 
91
+ async function readStdin(): Promise<Buffer> {
92
+ return new Promise((resolve, reject) => {
93
+ const chunks: Buffer[] = [];
94
+ process.stdin.on('data', (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
95
+ process.stdin.on('end', () => resolve(Buffer.concat(chunks)));
96
+ process.stdin.on('error', reject);
97
+ });
98
+ }
99
+
90
100
  export function registerDecryptCommand(program: Command) {
91
101
  program
92
- .command('decrypt <encrypted-file>')
102
+ .command('decrypt [encrypted-file]')
93
103
  .description('Decrypt a file downloaded from Walrus using your encryption passphrase')
94
104
  .option('-o, --output <path>', 'Output path for decrypted file')
105
+ .option('--stdin', 'Read ciphertext from stdin (for sandboxed agents without filesystem access)')
106
+ .option('--stdout', 'Write plaintext to stdout instead of a file')
95
107
  .option('--file-id <id>', 'Tusky file ID (to look up wrappedKey/iv from API)')
96
108
  .option('--export <path>', 'Path to tusky-export.json manifest (for offline decryption)')
97
109
  .option('--passphrase <passphrase>', 'Encryption passphrase (also reads TUSKYDP_PASSWORD env var)')
98
110
  .option('--wrapped-key <key>', 'Per-file wrapped key (base64, from export manifest)')
99
111
  .option('--iv <iv>', 'Per-file encryption IV (base64, from export manifest)')
100
112
  .option('--checksum <sha256>', 'Expected plaintext SHA-256 checksum (hex)')
101
- .action(async (encryptedFile: string, options: {
113
+ .action(async (encryptedFile: string | undefined, options: {
102
114
  output?: string;
115
+ stdin?: boolean;
116
+ stdout?: boolean;
103
117
  fileId?: string;
104
118
  export?: string;
105
119
  passphrase?: string;
@@ -107,21 +121,37 @@ export function registerDecryptCommand(program: Command) {
107
121
  iv?: string;
108
122
  checksum?: string;
109
123
  }) => {
110
- const spinner = createSpinner('Preparing decryption...');
124
+ // When piping to stdout, send spinner to stderr to avoid polluting the binary stream
125
+ const spinnerStream = options.stdout ? process.stderr : process.stdout;
126
+ const spinner = ora({ text: 'Preparing decryption...', stream: spinnerStream as NodeJS.WritableStream });
111
127
  spinner.start();
112
128
 
113
129
  try {
114
- // Resolve the encrypted file
115
- const inputPath = resolve(encryptedFile);
116
- if (!existsSync(inputPath)) {
117
- spinner.fail(`File not found: ${inputPath}`);
118
- return;
130
+ // Resolve ciphertext source: --stdin, or file path
131
+ let ciphertext: Buffer;
132
+ let defaultFileName = 'decrypted';
133
+
134
+ if (options.stdin) {
135
+ spinner.text = 'Reading ciphertext from stdin...';
136
+ ciphertext = await readStdin();
137
+ } else {
138
+ if (!encryptedFile) {
139
+ spinner.fail('Provide an encrypted file path, or use --stdin to read from stdin.');
140
+ return;
141
+ }
142
+ const inputPath = resolve(encryptedFile);
143
+ if (!existsSync(inputPath)) {
144
+ spinner.fail(`File not found: ${inputPath}`);
145
+ return;
146
+ }
147
+ defaultFileName = basename(inputPath).replace(/\.enc$/, '');
148
+ ciphertext = readFileSync(inputPath);
119
149
  }
120
150
 
121
151
  let wrappedKey: string;
122
152
  let iv: string;
123
153
  let checksum: string | undefined = options.checksum;
124
- let fileName: string = basename(inputPath).replace(/\.enc$/, '');
154
+ let fileName: string = defaultFileName;
125
155
  let encryptionParams: { salt?: string; verifier?: string; encryptedMasterKey?: string } = {};
126
156
 
127
157
  // ── Mode 1: Export manifest ──────────────────────────────────
@@ -139,10 +169,8 @@ export function registerDecryptCommand(program: Command) {
139
169
  if (options.fileId) {
140
170
  exportedFile = manifest.files.find((f) => f.fileId === options.fileId);
141
171
  } else {
142
- // Try to match by filename
143
- const inputBase = basename(inputPath);
144
172
  exportedFile = manifest.files.find((f) =>
145
- f.name === inputBase || f.name === fileName,
173
+ f.name === defaultFileName || f.name === encryptedFile,
146
174
  );
147
175
 
148
176
  if (!exportedFile && manifest.files.length === 1) {
@@ -154,7 +182,7 @@ export function registerDecryptCommand(program: Command) {
154
182
  spinner.fail(
155
183
  options.fileId
156
184
  ? `File ID ${options.fileId} not found in export manifest.`
157
- : `Could not match "${basename(inputPath)}" to a file in the export manifest. Use --file-id to specify.`,
185
+ : `Could not match "${defaultFileName}" to a file in the export manifest. Use --file-id to specify.`,
158
186
  );
159
187
  return;
160
188
  }
@@ -252,19 +280,24 @@ export function registerDecryptCommand(program: Command) {
252
280
  ...encryptionParams,
253
281
  });
254
282
 
255
- // Read and decrypt
283
+ // Decrypt
256
284
  spinner.text = 'Decrypting...';
257
- const ciphertext = readFileSync(inputPath);
258
285
  const plaintext = decryptBuffer(ciphertext, wrappedKey, iv, masterKey, checksum);
259
286
 
260
- // Write output
261
- const outputPath = options.output ? resolve(options.output) : resolve(fileName);
262
- writeFileSync(outputPath, plaintext);
263
-
264
- spinner.succeed(`Decrypted -> ${outputPath} (${plaintext.length} bytes)`);
265
-
266
- if (checksum) {
267
- console.log(chalk.dim(' Integrity check passed (SHA-256)'));
287
+ if (options.stdout) {
288
+ spinner.stop();
289
+ process.stdout.write(plaintext);
290
+ if (checksum) {
291
+ process.stderr.write(chalk.dim(' Integrity check passed (SHA-256)\n'));
292
+ }
293
+ } else {
294
+ // Write to disk
295
+ const outputPath = options.output ? resolve(options.output) : resolve(fileName);
296
+ writeFileSync(outputPath, plaintext);
297
+ spinner.succeed(`Decrypted -> ${outputPath} (${plaintext.length} bytes)`);
298
+ if (checksum) {
299
+ console.log(chalk.dim(' Integrity check passed (SHA-256)'));
300
+ }
268
301
  }
269
302
  } catch (err: any) {
270
303
  spinner.fail(`Decryption failed: ${err.message}`);