@alta-foundation/plaud-extractor 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 (163) hide show
  1. package/.env.example +9 -0
  2. package/.github/workflows/ci.yml +33 -0
  3. package/.github/workflows/publish.yml +46 -0
  4. package/CLAUDE.md +53 -0
  5. package/README.md +318 -0
  6. package/dist/PlaudExtractor.d.ts +61 -0
  7. package/dist/PlaudExtractor.d.ts.map +1 -0
  8. package/dist/PlaudExtractor.js +236 -0
  9. package/dist/PlaudExtractor.js.map +1 -0
  10. package/dist/auth/browser-auth.d.ts +10 -0
  11. package/dist/auth/browser-auth.d.ts.map +1 -0
  12. package/dist/auth/browser-auth.js +220 -0
  13. package/dist/auth/browser-auth.js.map +1 -0
  14. package/dist/auth/token-store.d.ts +9 -0
  15. package/dist/auth/token-store.d.ts.map +1 -0
  16. package/dist/auth/token-store.js +74 -0
  17. package/dist/auth/token-store.js.map +1 -0
  18. package/dist/auth/types.d.ts +266 -0
  19. package/dist/auth/types.d.ts.map +1 -0
  20. package/dist/auth/types.js +32 -0
  21. package/dist/auth/types.js.map +1 -0
  22. package/dist/cli/bin.d.ts +3 -0
  23. package/dist/cli/bin.d.ts.map +1 -0
  24. package/dist/cli/bin.js +30 -0
  25. package/dist/cli/bin.js.map +1 -0
  26. package/dist/cli/commands/auth.d.ts +3 -0
  27. package/dist/cli/commands/auth.d.ts.map +1 -0
  28. package/dist/cli/commands/auth.js +22 -0
  29. package/dist/cli/commands/auth.js.map +1 -0
  30. package/dist/cli/commands/backfill.d.ts +3 -0
  31. package/dist/cli/commands/backfill.d.ts.map +1 -0
  32. package/dist/cli/commands/backfill.js +59 -0
  33. package/dist/cli/commands/backfill.js.map +1 -0
  34. package/dist/cli/commands/sync.d.ts +3 -0
  35. package/dist/cli/commands/sync.d.ts.map +1 -0
  36. package/dist/cli/commands/sync.js +55 -0
  37. package/dist/cli/commands/sync.js.map +1 -0
  38. package/dist/cli/commands/verify.d.ts +3 -0
  39. package/dist/cli/commands/verify.d.ts.map +1 -0
  40. package/dist/cli/commands/verify.js +28 -0
  41. package/dist/cli/commands/verify.js.map +1 -0
  42. package/dist/cli/exit-codes.d.ts +8 -0
  43. package/dist/cli/exit-codes.d.ts.map +1 -0
  44. package/dist/cli/exit-codes.js +16 -0
  45. package/dist/cli/exit-codes.js.map +1 -0
  46. package/dist/cli/options.d.ts +31 -0
  47. package/dist/cli/options.d.ts.map +1 -0
  48. package/dist/cli/options.js +11 -0
  49. package/dist/cli/options.js.map +1 -0
  50. package/dist/client/endpoints.d.ts +26 -0
  51. package/dist/client/endpoints.d.ts.map +1 -0
  52. package/dist/client/endpoints.js +54 -0
  53. package/dist/client/endpoints.js.map +1 -0
  54. package/dist/client/http.d.ts +17 -0
  55. package/dist/client/http.d.ts.map +1 -0
  56. package/dist/client/http.js +92 -0
  57. package/dist/client/http.js.map +1 -0
  58. package/dist/client/plaud-client.d.ts +14 -0
  59. package/dist/client/plaud-client.d.ts.map +1 -0
  60. package/dist/client/plaud-client.js +216 -0
  61. package/dist/client/plaud-client.js.map +1 -0
  62. package/dist/client/types.d.ts +154 -0
  63. package/dist/client/types.d.ts.map +1 -0
  64. package/dist/client/types.js +41 -0
  65. package/dist/client/types.js.map +1 -0
  66. package/dist/errors.d.ts +24 -0
  67. package/dist/errors.d.ts.map +1 -0
  68. package/dist/errors.js +51 -0
  69. package/dist/errors.js.map +1 -0
  70. package/dist/index.d.ts +7 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +5 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/logger.d.ts +9 -0
  75. package/dist/logger.d.ts.map +1 -0
  76. package/dist/logger.js +37 -0
  77. package/dist/logger.js.map +1 -0
  78. package/dist/mcp/job-tools.d.ts +3 -0
  79. package/dist/mcp/job-tools.d.ts.map +1 -0
  80. package/dist/mcp/job-tools.js +108 -0
  81. package/dist/mcp/job-tools.js.map +1 -0
  82. package/dist/mcp/read-tools.d.ts +3 -0
  83. package/dist/mcp/read-tools.d.ts.map +1 -0
  84. package/dist/mcp/read-tools.js +173 -0
  85. package/dist/mcp/read-tools.js.map +1 -0
  86. package/dist/mcp/server.d.ts +3 -0
  87. package/dist/mcp/server.d.ts.map +1 -0
  88. package/dist/mcp/server.js +32 -0
  89. package/dist/mcp/server.js.map +1 -0
  90. package/dist/storage/atomic.d.ts +5 -0
  91. package/dist/storage/atomic.d.ts.map +1 -0
  92. package/dist/storage/atomic.js +51 -0
  93. package/dist/storage/atomic.js.map +1 -0
  94. package/dist/storage/checksums.d.ts +15 -0
  95. package/dist/storage/checksums.d.ts.map +1 -0
  96. package/dist/storage/checksums.js +56 -0
  97. package/dist/storage/checksums.js.map +1 -0
  98. package/dist/storage/dataset-writer.d.ts +21 -0
  99. package/dist/storage/dataset-writer.d.ts.map +1 -0
  100. package/dist/storage/dataset-writer.js +52 -0
  101. package/dist/storage/dataset-writer.js.map +1 -0
  102. package/dist/storage/paths.d.ts +9 -0
  103. package/dist/storage/paths.d.ts.map +1 -0
  104. package/dist/storage/paths.js +38 -0
  105. package/dist/storage/paths.js.map +1 -0
  106. package/dist/storage/recording-store.d.ts +24 -0
  107. package/dist/storage/recording-store.d.ts.map +1 -0
  108. package/dist/storage/recording-store.js +161 -0
  109. package/dist/storage/recording-store.js.map +1 -0
  110. package/dist/sync/download-queue.d.ts +21 -0
  111. package/dist/sync/download-queue.d.ts.map +1 -0
  112. package/dist/sync/download-queue.js +82 -0
  113. package/dist/sync/download-queue.js.map +1 -0
  114. package/dist/sync/incremental.d.ts +21 -0
  115. package/dist/sync/incremental.d.ts.map +1 -0
  116. package/dist/sync/incremental.js +96 -0
  117. package/dist/sync/incremental.js.map +1 -0
  118. package/dist/sync/sync-engine.d.ts +6 -0
  119. package/dist/sync/sync-engine.d.ts.map +1 -0
  120. package/dist/sync/sync-engine.js +135 -0
  121. package/dist/sync/sync-engine.js.map +1 -0
  122. package/dist/sync/types.d.ts +130 -0
  123. package/dist/sync/types.d.ts.map +1 -0
  124. package/dist/sync/types.js +17 -0
  125. package/dist/sync/types.js.map +1 -0
  126. package/dist/transcript/formatter.d.ts +4 -0
  127. package/dist/transcript/formatter.d.ts.map +1 -0
  128. package/dist/transcript/formatter.js +88 -0
  129. package/dist/transcript/formatter.js.map +1 -0
  130. package/package.json +41 -0
  131. package/src/PlaudExtractor.ts +275 -0
  132. package/src/auth/browser-auth.ts +248 -0
  133. package/src/auth/token-store.ts +79 -0
  134. package/src/auth/types.ts +41 -0
  135. package/src/cli/bin.ts +30 -0
  136. package/src/cli/commands/auth.ts +27 -0
  137. package/src/cli/commands/backfill.ts +77 -0
  138. package/src/cli/commands/sync.ts +71 -0
  139. package/src/cli/commands/verify.ts +31 -0
  140. package/src/cli/exit-codes.ts +14 -0
  141. package/src/cli/options.ts +10 -0
  142. package/src/client/endpoints.ts +62 -0
  143. package/src/client/http.ts +110 -0
  144. package/src/client/plaud-client.ts +268 -0
  145. package/src/client/types.ts +62 -0
  146. package/src/errors.ts +57 -0
  147. package/src/index.ts +17 -0
  148. package/src/logger.ts +49 -0
  149. package/src/mcp/job-tools.ts +156 -0
  150. package/src/mcp/read-tools.ts +204 -0
  151. package/src/mcp/server.ts +39 -0
  152. package/src/storage/atomic.ts +51 -0
  153. package/src/storage/checksums.ts +76 -0
  154. package/src/storage/dataset-writer.ts +74 -0
  155. package/src/storage/paths.ts +44 -0
  156. package/src/storage/recording-store.ts +182 -0
  157. package/src/sync/download-queue.ts +102 -0
  158. package/src/sync/incremental.ts +111 -0
  159. package/src/sync/sync-engine.ts +183 -0
  160. package/src/sync/types.ts +64 -0
  161. package/src/transcript/formatter.ts +91 -0
  162. package/tsconfig.build.json +8 -0
  163. package/tsconfig.json +19 -0
@@ -0,0 +1,266 @@
1
+ import { z } from 'zod';
2
+ export declare const CookieSchema: z.ZodObject<{
3
+ name: z.ZodString;
4
+ value: z.ZodString;
5
+ domain: z.ZodString;
6
+ path: z.ZodString;
7
+ httpOnly: z.ZodBoolean;
8
+ secure: z.ZodBoolean;
9
+ sameSite: z.ZodOptional<z.ZodEnum<["Strict", "Lax", "None"]>>;
10
+ expires: z.ZodOptional<z.ZodNumber>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ name: string;
13
+ value: string;
14
+ domain: string;
15
+ path: string;
16
+ httpOnly: boolean;
17
+ secure: boolean;
18
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
19
+ expires?: number | undefined;
20
+ }, {
21
+ name: string;
22
+ value: string;
23
+ domain: string;
24
+ path: string;
25
+ httpOnly: boolean;
26
+ secure: boolean;
27
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
28
+ expires?: number | undefined;
29
+ }>;
30
+ export declare const EndpointMapSchema: z.ZodObject<{
31
+ listRecordings: z.ZodOptional<z.ZodString>;
32
+ batchDetail: z.ZodOptional<z.ZodString>;
33
+ getAudioUrl: z.ZodOptional<z.ZodString>;
34
+ userProfile: z.ZodOptional<z.ZodString>;
35
+ apiBaseUrl: z.ZodOptional<z.ZodString>;
36
+ /** @deprecated — transcript is embedded in the recording, not a separate endpoint */
37
+ getTranscript: z.ZodOptional<z.ZodString>;
38
+ }, "strip", z.ZodTypeAny, {
39
+ listRecordings?: string | undefined;
40
+ batchDetail?: string | undefined;
41
+ getAudioUrl?: string | undefined;
42
+ userProfile?: string | undefined;
43
+ apiBaseUrl?: string | undefined;
44
+ getTranscript?: string | undefined;
45
+ }, {
46
+ listRecordings?: string | undefined;
47
+ batchDetail?: string | undefined;
48
+ getAudioUrl?: string | undefined;
49
+ userProfile?: string | undefined;
50
+ apiBaseUrl?: string | undefined;
51
+ getTranscript?: string | undefined;
52
+ }>;
53
+ export type EndpointMap = z.infer<typeof EndpointMapSchema>;
54
+ export declare const AuthSessionSchema: z.ZodObject<{
55
+ cookies: z.ZodArray<z.ZodObject<{
56
+ name: z.ZodString;
57
+ value: z.ZodString;
58
+ domain: z.ZodString;
59
+ path: z.ZodString;
60
+ httpOnly: z.ZodBoolean;
61
+ secure: z.ZodBoolean;
62
+ sameSite: z.ZodOptional<z.ZodEnum<["Strict", "Lax", "None"]>>;
63
+ expires: z.ZodOptional<z.ZodNumber>;
64
+ }, "strip", z.ZodTypeAny, {
65
+ name: string;
66
+ value: string;
67
+ domain: string;
68
+ path: string;
69
+ httpOnly: boolean;
70
+ secure: boolean;
71
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
72
+ expires?: number | undefined;
73
+ }, {
74
+ name: string;
75
+ value: string;
76
+ domain: string;
77
+ path: string;
78
+ httpOnly: boolean;
79
+ secure: boolean;
80
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
81
+ expires?: number | undefined;
82
+ }>, "many">;
83
+ authToken: z.ZodOptional<z.ZodString>;
84
+ apiBaseUrl: z.ZodString;
85
+ capturedAt: z.ZodString;
86
+ expiresAt: z.ZodOptional<z.ZodString>;
87
+ endpointMap: z.ZodOptional<z.ZodObject<{
88
+ listRecordings: z.ZodOptional<z.ZodString>;
89
+ batchDetail: z.ZodOptional<z.ZodString>;
90
+ getAudioUrl: z.ZodOptional<z.ZodString>;
91
+ userProfile: z.ZodOptional<z.ZodString>;
92
+ apiBaseUrl: z.ZodOptional<z.ZodString>;
93
+ /** @deprecated — transcript is embedded in the recording, not a separate endpoint */
94
+ getTranscript: z.ZodOptional<z.ZodString>;
95
+ }, "strip", z.ZodTypeAny, {
96
+ listRecordings?: string | undefined;
97
+ batchDetail?: string | undefined;
98
+ getAudioUrl?: string | undefined;
99
+ userProfile?: string | undefined;
100
+ apiBaseUrl?: string | undefined;
101
+ getTranscript?: string | undefined;
102
+ }, {
103
+ listRecordings?: string | undefined;
104
+ batchDetail?: string | undefined;
105
+ getAudioUrl?: string | undefined;
106
+ userProfile?: string | undefined;
107
+ apiBaseUrl?: string | undefined;
108
+ getTranscript?: string | undefined;
109
+ }>>;
110
+ }, "strip", z.ZodTypeAny, {
111
+ cookies: {
112
+ name: string;
113
+ value: string;
114
+ domain: string;
115
+ path: string;
116
+ httpOnly: boolean;
117
+ secure: boolean;
118
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
119
+ expires?: number | undefined;
120
+ }[];
121
+ apiBaseUrl: string;
122
+ capturedAt: string;
123
+ authToken?: string | undefined;
124
+ expiresAt?: string | undefined;
125
+ endpointMap?: {
126
+ listRecordings?: string | undefined;
127
+ batchDetail?: string | undefined;
128
+ getAudioUrl?: string | undefined;
129
+ userProfile?: string | undefined;
130
+ apiBaseUrl?: string | undefined;
131
+ getTranscript?: string | undefined;
132
+ } | undefined;
133
+ }, {
134
+ cookies: {
135
+ name: string;
136
+ value: string;
137
+ domain: string;
138
+ path: string;
139
+ httpOnly: boolean;
140
+ secure: boolean;
141
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
142
+ expires?: number | undefined;
143
+ }[];
144
+ apiBaseUrl: string;
145
+ capturedAt: string;
146
+ authToken?: string | undefined;
147
+ expiresAt?: string | undefined;
148
+ endpointMap?: {
149
+ listRecordings?: string | undefined;
150
+ batchDetail?: string | undefined;
151
+ getAudioUrl?: string | undefined;
152
+ userProfile?: string | undefined;
153
+ apiBaseUrl?: string | undefined;
154
+ getTranscript?: string | undefined;
155
+ } | undefined;
156
+ }>;
157
+ export type AuthSession = z.infer<typeof AuthSessionSchema>;
158
+ export declare const StoredCredentialsSchema: z.ZodObject<{
159
+ cookies: z.ZodArray<z.ZodObject<{
160
+ name: z.ZodString;
161
+ value: z.ZodString;
162
+ domain: z.ZodString;
163
+ path: z.ZodString;
164
+ httpOnly: z.ZodBoolean;
165
+ secure: z.ZodBoolean;
166
+ sameSite: z.ZodOptional<z.ZodEnum<["Strict", "Lax", "None"]>>;
167
+ expires: z.ZodOptional<z.ZodNumber>;
168
+ }, "strip", z.ZodTypeAny, {
169
+ name: string;
170
+ value: string;
171
+ domain: string;
172
+ path: string;
173
+ httpOnly: boolean;
174
+ secure: boolean;
175
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
176
+ expires?: number | undefined;
177
+ }, {
178
+ name: string;
179
+ value: string;
180
+ domain: string;
181
+ path: string;
182
+ httpOnly: boolean;
183
+ secure: boolean;
184
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
185
+ expires?: number | undefined;
186
+ }>, "many">;
187
+ authToken: z.ZodOptional<z.ZodString>;
188
+ apiBaseUrl: z.ZodString;
189
+ capturedAt: z.ZodString;
190
+ expiresAt: z.ZodOptional<z.ZodString>;
191
+ endpointMap: z.ZodOptional<z.ZodObject<{
192
+ listRecordings: z.ZodOptional<z.ZodString>;
193
+ batchDetail: z.ZodOptional<z.ZodString>;
194
+ getAudioUrl: z.ZodOptional<z.ZodString>;
195
+ userProfile: z.ZodOptional<z.ZodString>;
196
+ apiBaseUrl: z.ZodOptional<z.ZodString>;
197
+ /** @deprecated — transcript is embedded in the recording, not a separate endpoint */
198
+ getTranscript: z.ZodOptional<z.ZodString>;
199
+ }, "strip", z.ZodTypeAny, {
200
+ listRecordings?: string | undefined;
201
+ batchDetail?: string | undefined;
202
+ getAudioUrl?: string | undefined;
203
+ userProfile?: string | undefined;
204
+ apiBaseUrl?: string | undefined;
205
+ getTranscript?: string | undefined;
206
+ }, {
207
+ listRecordings?: string | undefined;
208
+ batchDetail?: string | undefined;
209
+ getAudioUrl?: string | undefined;
210
+ userProfile?: string | undefined;
211
+ apiBaseUrl?: string | undefined;
212
+ getTranscript?: string | undefined;
213
+ }>>;
214
+ } & {
215
+ schemaVersion: z.ZodLiteral<1>;
216
+ }, "strip", z.ZodTypeAny, {
217
+ cookies: {
218
+ name: string;
219
+ value: string;
220
+ domain: string;
221
+ path: string;
222
+ httpOnly: boolean;
223
+ secure: boolean;
224
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
225
+ expires?: number | undefined;
226
+ }[];
227
+ apiBaseUrl: string;
228
+ capturedAt: string;
229
+ schemaVersion: 1;
230
+ authToken?: string | undefined;
231
+ expiresAt?: string | undefined;
232
+ endpointMap?: {
233
+ listRecordings?: string | undefined;
234
+ batchDetail?: string | undefined;
235
+ getAudioUrl?: string | undefined;
236
+ userProfile?: string | undefined;
237
+ apiBaseUrl?: string | undefined;
238
+ getTranscript?: string | undefined;
239
+ } | undefined;
240
+ }, {
241
+ cookies: {
242
+ name: string;
243
+ value: string;
244
+ domain: string;
245
+ path: string;
246
+ httpOnly: boolean;
247
+ secure: boolean;
248
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
249
+ expires?: number | undefined;
250
+ }[];
251
+ apiBaseUrl: string;
252
+ capturedAt: string;
253
+ schemaVersion: 1;
254
+ authToken?: string | undefined;
255
+ expiresAt?: string | undefined;
256
+ endpointMap?: {
257
+ listRecordings?: string | undefined;
258
+ batchDetail?: string | undefined;
259
+ getAudioUrl?: string | undefined;
260
+ userProfile?: string | undefined;
261
+ apiBaseUrl?: string | undefined;
262
+ getTranscript?: string | undefined;
263
+ } | undefined;
264
+ }>;
265
+ export type StoredCredentials = z.infer<typeof StoredCredentialsSchema>;
266
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;EASvB,CAAA;AAEF,eAAO,MAAM,iBAAiB;;;;;;IAM5B,qFAAqF;;;;;;;;;;;;;;;;EAErF,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAN5B,qFAAqF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAarF,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAjBlC,qFAAqF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBrF,CAAA;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA"}
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod';
2
+ export const CookieSchema = z.object({
3
+ name: z.string(),
4
+ value: z.string(),
5
+ domain: z.string(),
6
+ path: z.string(),
7
+ httpOnly: z.boolean(),
8
+ secure: z.boolean(),
9
+ sameSite: z.enum(['Strict', 'Lax', 'None']).optional(),
10
+ expires: z.number().optional(),
11
+ });
12
+ export const EndpointMapSchema = z.object({
13
+ listRecordings: z.string().optional(), // GET /file/simple/web
14
+ batchDetail: z.string().optional(), // POST /file/list
15
+ getAudioUrl: z.string().optional(), // GET /file/temp-url/<id>
16
+ userProfile: z.string().optional(), // GET /user/me
17
+ apiBaseUrl: z.string().optional(),
18
+ /** @deprecated — transcript is embedded in the recording, not a separate endpoint */
19
+ getTranscript: z.string().optional(),
20
+ });
21
+ export const AuthSessionSchema = z.object({
22
+ cookies: z.array(CookieSchema),
23
+ authToken: z.string().optional(),
24
+ apiBaseUrl: z.string(),
25
+ capturedAt: z.string().datetime(),
26
+ expiresAt: z.string().datetime().optional(),
27
+ endpointMap: EndpointMapSchema.optional(),
28
+ });
29
+ export const StoredCredentialsSchema = AuthSessionSchema.extend({
30
+ schemaVersion: z.literal(1),
31
+ });
32
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;IACrB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;IACtD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAI,uBAAuB;IAChE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAQ,kBAAkB;IAC5D,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAQ,0BAA0B;IACpE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAQ,eAAe;IACzD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,qFAAqF;IACrF,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAA;AAIF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IAC9B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC3C,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAA;AAIF,MAAM,CAAC,MAAM,uBAAuB,GAAG,iBAAiB,CAAC,MAAM,CAAC;IAC9D,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;CAC5B,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { registerAuthCommand } from './commands/auth.js';
4
+ import { registerSyncCommand } from './commands/sync.js';
5
+ import { registerBackfillCommand } from './commands/backfill.js';
6
+ import { registerVerifyCommand } from './commands/verify.js';
7
+ import { toExitCode } from './exit-codes.js';
8
+ const program = new Command()
9
+ .name('alta-plaud')
10
+ .description('Export recordings, transcripts, and metadata from Plaud')
11
+ .version('1.0.0')
12
+ .helpOption('-h, --help', 'Show help');
13
+ registerAuthCommand(program);
14
+ registerSyncCommand(program);
15
+ registerBackfillCommand(program);
16
+ registerVerifyCommand(program);
17
+ program.parseAsync(process.argv).catch((err) => {
18
+ // This is the only place in the codebase where process.exit() is called.
19
+ const code = toExitCode(err);
20
+ if (err instanceof Error) {
21
+ console.error(`\nError: ${err.message}`);
22
+ if (process.env['DEBUG'])
23
+ console.error(err.stack);
24
+ }
25
+ else {
26
+ console.error(`\nUnexpected error: ${String(err)}`);
27
+ }
28
+ process.exit(code);
29
+ });
30
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAY,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;KAC1B,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,yDAAyD,CAAC;KACtE,OAAO,CAAC,OAAO,CAAC;KAChB,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;AAExC,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,uBAAuB,CAAC,OAAO,CAAC,CAAA;AAChC,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAE9B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,yEAAyE;IACzE,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;IAC5B,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACxC,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACpD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,uBAAuB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACrD,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACpB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerAuthCommand(program: Command): void;
3
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqB1D"}
@@ -0,0 +1,22 @@
1
+ import { PlaudExtractor } from '../../PlaudExtractor.js';
2
+ import { authTokenPath } from '../../auth/token-store.js';
3
+ export function registerAuthCommand(program) {
4
+ program
5
+ .command('auth')
6
+ .description('Authenticate with Plaud by launching a browser (required before first sync)')
7
+ .option('--headless', 'Run browser in headless mode (requires PLAUD_EMAIL + PLAUD_PASSWORD env vars)', false)
8
+ .option('--out <dir>', 'Data directory for logs', undefined)
9
+ .action(async (opts) => {
10
+ const extractor = new PlaudExtractor({ outDir: opts.out });
11
+ console.log('Launching browser to authenticate with Plaud...');
12
+ await extractor.authenticate({
13
+ headless: opts.headless,
14
+ email: process.env['PLAUD_EMAIL'],
15
+ password: process.env['PLAUD_PASSWORD'],
16
+ });
17
+ console.log(`\nAuthentication successful!`);
18
+ console.log(`Credentials saved to: ${authTokenPath()}`);
19
+ console.log(`\nYou can now run: alta-plaud sync`);
20
+ });
21
+ }
22
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/cli/commands/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEzD,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,6EAA6E,CAAC;SAC1F,MAAM,CAAC,YAAY,EAAE,+EAA+E,EAAE,KAAK,CAAC;SAC5G,MAAM,CAAC,aAAa,EAAE,yBAAyB,EAAE,SAAS,CAAC;SAC3D,MAAM,CAAC,KAAK,EAAE,IAAyC,EAAE,EAAE;QAC1D,MAAM,SAAS,GAAG,IAAI,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAE1D,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAA;QAE9D,MAAM,SAAS,CAAC,YAAY,CAAC;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;YACjC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;SACxC,CAAC,CAAA;QAEF,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QAC3C,OAAO,CAAC,GAAG,CAAC,yBAAyB,aAAa,EAAE,EAAE,CAAC,CAAA;QACvD,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerBackfillCommand(program: Command): void;
3
+ //# sourceMappingURL=backfill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backfill.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/backfill.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsD9D"}
@@ -0,0 +1,59 @@
1
+ import { PlaudExtractor } from '../../PlaudExtractor.js';
2
+ import { defaultOutDir } from '../../storage/paths.js';
3
+ export function registerBackfillCommand(program) {
4
+ program
5
+ .command('backfill')
6
+ .description('Download all recordings from scratch (ignores incremental state)')
7
+ .option('--out <dir>', 'Output directory', defaultOutDir())
8
+ .option('--since <iso>', 'Only backfill recordings after this ISO date')
9
+ .option('--limit <n>', 'Max number of recordings to process', parseInt)
10
+ .option('--concurrency <n>', 'Parallel downloads (default: 3)', parseInt, 3)
11
+ .option('--formats <list>', 'Transcript formats: json,txt,md (default: all)', 'json,txt,md')
12
+ .option('--dataset', 'Append to datasets/plaud_transcripts.jsonl (default: on)', true)
13
+ .option('--no-dataset', 'Skip dataset output')
14
+ .option('--dry-run', 'Print plan without downloading', false)
15
+ .option('--verbose', 'Verbose logging', false)
16
+ .option('--yes', 'Skip confirmation prompt', false)
17
+ .action(async (opts) => {
18
+ if (!opts.yes && !opts.dryRun) {
19
+ const confirmed = await confirm('Backfill will re-evaluate all recordings and may overwrite existing files. Continue? (y/N) ');
20
+ if (!confirmed) {
21
+ console.log('Aborted.');
22
+ return;
23
+ }
24
+ }
25
+ const extractor = new PlaudExtractor({ outDir: opts.out, verbose: opts.verbose });
26
+ const formats = parseFormats(opts.formats);
27
+ const result = await extractor.backfill({
28
+ since: opts.since ? new Date(opts.since) : undefined,
29
+ limit: opts.limit,
30
+ concurrency: opts.concurrency,
31
+ formats,
32
+ includeDataset: opts.dataset,
33
+ dryRun: opts.dryRun,
34
+ });
35
+ const durationSec = (result.durationMs / 1000).toFixed(1);
36
+ console.log(`\nBackfill complete (${durationSec}s)`);
37
+ console.log(` Downloaded: ${result.succeeded}`);
38
+ console.log(` Skipped: ${result.skipped}`);
39
+ console.log(` Failed: ${result.failed}`);
40
+ if (result.datasetPath)
41
+ console.log(` Dataset: ${result.datasetPath}`);
42
+ });
43
+ }
44
+ function parseFormats(str) {
45
+ const valid = ['json', 'txt', 'md'];
46
+ return str.split(',').filter((f) => valid.includes(f));
47
+ }
48
+ async function confirm(message) {
49
+ const { createInterface } = await import('node:readline');
50
+ process.stdout.write(message);
51
+ return new Promise(resolve => {
52
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
53
+ rl.once('line', (answer) => {
54
+ rl.close();
55
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
56
+ });
57
+ });
58
+ }
59
+ //# sourceMappingURL=backfill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backfill.js","sourceRoot":"","sources":["../../../src/cli/commands/backfill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerSyncCommand(program: Command): void;
3
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2C1D"}
@@ -0,0 +1,55 @@
1
+ import { PlaudExtractor } from '../../PlaudExtractor.js';
2
+ import { defaultOutDir } from '../../storage/paths.js';
3
+ export function registerSyncCommand(program) {
4
+ program
5
+ .command('sync')
6
+ .description('Pull new or updated recordings from Plaud (incremental)')
7
+ .option('--out <dir>', 'Output directory', defaultOutDir())
8
+ .option('--since <iso>', 'Only sync recordings after this ISO date (overrides last-sync state)')
9
+ .option('--limit <n>', 'Max number of recordings to process', parseInt)
10
+ .option('--concurrency <n>', 'Parallel downloads (default: 3)', parseInt, 3)
11
+ .option('--formats <list>', 'Transcript formats: json,txt,md (default: all)', 'json,txt,md')
12
+ .option('--dataset', 'Append to datasets/plaud_transcripts.jsonl (default: on)', true)
13
+ .option('--no-dataset', 'Skip dataset output')
14
+ .option('--dry-run', 'Print plan without downloading', false)
15
+ .option('--verbose', 'Verbose logging', false)
16
+ .option('--redact', 'Redact tokens from logs', false)
17
+ .action(async (opts) => {
18
+ const extractor = new PlaudExtractor({
19
+ outDir: opts.out,
20
+ verbose: opts.verbose,
21
+ redact: opts.redact,
22
+ });
23
+ const formats = parseFormats(opts.formats);
24
+ const result = await extractor.sync({
25
+ since: opts.since ? new Date(opts.since) : undefined,
26
+ limit: opts.limit,
27
+ concurrency: opts.concurrency,
28
+ formats,
29
+ includeDataset: opts.dataset,
30
+ dryRun: opts.dryRun,
31
+ });
32
+ printSyncSummary(result);
33
+ });
34
+ }
35
+ function parseFormats(str) {
36
+ const valid = ['json', 'txt', 'md'];
37
+ return str.split(',').filter((f) => valid.includes(f));
38
+ }
39
+ function printSyncSummary(result) {
40
+ const durationSec = (result.durationMs / 1000).toFixed(1);
41
+ console.log(`\nSync complete (${durationSec}s)`);
42
+ console.log(` Downloaded: ${result.succeeded}`);
43
+ console.log(` Skipped: ${result.skipped}`);
44
+ console.log(` Failed: ${result.failed}`);
45
+ if (result.datasetPath) {
46
+ console.log(` Dataset: ${result.datasetPath}`);
47
+ }
48
+ if (result.errors.length > 0) {
49
+ console.error(`\nFailed recordings:`);
50
+ for (const { recordingId, error } of result.errors) {
51
+ console.error(` ${recordingId}: ${error.message}`);
52
+ }
53
+ }
54
+ }
55
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/cli/commands/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerVerifyCommand(program: Command): void;
3
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/verify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAIxC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0B5D"}
@@ -0,0 +1,28 @@
1
+ import { PlaudExtractor } from '../../PlaudExtractor.js';
2
+ import { defaultOutDir } from '../../storage/paths.js';
3
+ export function registerVerifyCommand(program) {
4
+ program
5
+ .command('verify')
6
+ .description('Verify checksums for all downloaded recordings')
7
+ .option('--out <dir>', 'Output directory', defaultOutDir())
8
+ .option('--repair', 'Re-download files with checksum mismatches', false)
9
+ .option('--verbose', 'Verbose logging', false)
10
+ .action(async (opts) => {
11
+ const extractor = new PlaudExtractor({ outDir: opts.out, verbose: opts.verbose });
12
+ console.log(`Verifying recordings in ${opts.out}...`);
13
+ const result = await extractor.verify({ repair: opts.repair });
14
+ console.log(`\nVerify complete`);
15
+ console.log(` Scanned: ${result.scanned}`);
16
+ console.log(` OK: ${result.ok}`);
17
+ console.log(` Failed: ${result.failed}`);
18
+ if (opts.repair)
19
+ console.log(` Repaired: ${result.repaired}`);
20
+ if (result.issues.length > 0) {
21
+ console.error(`\nIssues found:`);
22
+ for (const issue of result.issues) {
23
+ console.error(` ${issue.recordingId}/${issue.file}: ${issue.issue}`);
24
+ }
25
+ }
26
+ });
27
+ }
28
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/cli/commands/verify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAEtD,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,gDAAgD,CAAC;SAC7D,MAAM,CAAC,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC;SAC1D,MAAM,CAAC,UAAU,EAAE,4CAA4C,EAAE,KAAK,CAAC;SACvE,MAAM,CAAC,WAAW,EAAE,iBAAiB,EAAE,KAAK,CAAC;SAC7C,MAAM,CAAC,KAAK,EAAE,IAAwD,EAAE,EAAE;QACzE,MAAM,SAAS,GAAG,IAAI,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QAEjF,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,CAAC,GAAG,KAAK,CAAC,CAAA;QACrD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QAE9D,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;QAChC,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;QAC5C,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;QACvC,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;QAC3C,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;QAE9D,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;YAChC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClC,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;YACvE,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare enum ExitCode {
2
+ Success = 0,
3
+ PartialFailure = 1,
4
+ AuthFailure = 2,
5
+ StorageError = 3
6
+ }
7
+ export declare function toExitCode(err: unknown): ExitCode;
8
+ //# sourceMappingURL=exit-codes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../../src/cli/exit-codes.ts"],"names":[],"mappings":"AAEA,oBAAY,QAAQ;IAClB,OAAO,IAAI;IACX,cAAc,IAAI;IAClB,WAAW,IAAI;IACf,YAAY,IAAI;CACjB;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAIjD"}
@@ -0,0 +1,16 @@
1
+ import { AuthError, StorageError } from '../errors.js';
2
+ export var ExitCode;
3
+ (function (ExitCode) {
4
+ ExitCode[ExitCode["Success"] = 0] = "Success";
5
+ ExitCode[ExitCode["PartialFailure"] = 1] = "PartialFailure";
6
+ ExitCode[ExitCode["AuthFailure"] = 2] = "AuthFailure";
7
+ ExitCode[ExitCode["StorageError"] = 3] = "StorageError";
8
+ })(ExitCode || (ExitCode = {}));
9
+ export function toExitCode(err) {
10
+ if (err instanceof AuthError)
11
+ return ExitCode.AuthFailure;
12
+ if (err instanceof StorageError)
13
+ return ExitCode.StorageError;
14
+ return ExitCode.PartialFailure;
15
+ }
16
+ //# sourceMappingURL=exit-codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../../src/cli/exit-codes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEtD,MAAM,CAAN,IAAY,QAKX;AALD,WAAY,QAAQ;IAClB,6CAAW,CAAA;IACX,2DAAkB,CAAA;IAClB,qDAAe,CAAA;IACf,uDAAgB,CAAA;AAClB,CAAC,EALW,QAAQ,KAAR,QAAQ,QAKnB;AAED,MAAM,UAAU,UAAU,CAAC,GAAY;IACrC,IAAI,GAAG,YAAY,SAAS;QAAE,OAAO,QAAQ,CAAC,WAAW,CAAA;IACzD,IAAI,GAAG,YAAY,YAAY;QAAE,OAAO,QAAQ,CAAC,YAAY,CAAA;IAC7D,OAAO,QAAQ,CAAC,cAAc,CAAA;AAChC,CAAC"}
@@ -0,0 +1,31 @@
1
+ export declare const COMMON_OPTIONS: {
2
+ out: {
3
+ flags: string;
4
+ description: string;
5
+ };
6
+ verbose: {
7
+ flags: string;
8
+ description: string;
9
+ };
10
+ redact: {
11
+ flags: string;
12
+ description: string;
13
+ };
14
+ dryRun: {
15
+ flags: string;
16
+ description: string;
17
+ };
18
+ concurrency: {
19
+ flags: string;
20
+ description: string;
21
+ };
22
+ formats: {
23
+ flags: string;
24
+ description: string;
25
+ };
26
+ limit: {
27
+ flags: string;
28
+ description: string;
29
+ };
30
+ };
31
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/cli/options.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQ1B,CAAA"}