@tom2012/cc-web 2026.6.17-b → 2026.9.6-c

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 (239) hide show
  1. package/CHANGELOG.json +96 -21
  2. package/backend/dist/adapters/claude-adapter.d.ts +4 -0
  3. package/backend/dist/adapters/claude-adapter.d.ts.map +1 -1
  4. package/backend/dist/adapters/claude-adapter.js +18 -2
  5. package/backend/dist/adapters/claude-adapter.js.map +1 -1
  6. package/backend/dist/adapters/types.d.ts +8 -0
  7. package/backend/dist/adapters/types.d.ts.map +1 -1
  8. package/backend/dist/auth.d.ts.map +0 -0
  9. package/backend/dist/config.d.ts +0 -0
  10. package/backend/dist/config.js +0 -0
  11. package/backend/dist/config.js.map +0 -0
  12. package/backend/dist/hooks-manager.d.ts +0 -1
  13. package/backend/dist/hooks-manager.d.ts.map +1 -1
  14. package/backend/dist/hooks-manager.js +19 -19
  15. package/backend/dist/hooks-manager.js.map +1 -1
  16. package/backend/dist/index.d.ts.map +1 -1
  17. package/backend/dist/index.js +76 -1
  18. package/backend/dist/index.js.map +1 -1
  19. package/backend/dist/logger.d.ts.map +1 -1
  20. package/backend/dist/logger.js +3 -0
  21. package/backend/dist/logger.js.map +1 -1
  22. package/backend/dist/routes/auth.d.ts +0 -0
  23. package/backend/dist/routes/auth.d.ts.map +0 -0
  24. package/backend/dist/routes/auth.js.map +0 -0
  25. package/backend/dist/routes/projects.d.ts.map +0 -0
  26. package/backend/dist/routes/projects.js.map +0 -0
  27. package/backend/dist/session-manager.d.ts +0 -0
  28. package/backend/dist/session-manager.d.ts.map +0 -0
  29. package/backend/dist/session-manager.js +0 -0
  30. package/backend/dist/session-manager.js.map +0 -0
  31. package/backend/dist/terminal-manager.d.ts +10 -1
  32. package/backend/dist/terminal-manager.d.ts.map +1 -1
  33. package/backend/dist/terminal-manager.js +19 -2
  34. package/backend/dist/terminal-manager.js.map +1 -1
  35. package/backend/dist/types.d.ts +0 -0
  36. package/backend/dist/types.d.ts.map +0 -0
  37. package/backend/dist/types.js +0 -0
  38. package/backend/dist/types.js.map +0 -0
  39. package/frontend/dist/assets/{ChatOverlay-Dp1BzsYb.js → ChatOverlay-CymdKeQK.js} +1 -1
  40. package/frontend/dist/assets/{ClaudeMemPage-CpzMjJnb.js → ClaudeMemPage-BZ4UtUoz.js} +1 -1
  41. package/frontend/dist/assets/{GraphPreview-DDY1yVOX.js → GraphPreview-21EwV_e_.js} +1 -1
  42. package/frontend/dist/assets/{MobilePage-BnnE820D.js → MobilePage-99vv9cWh.js} +3 -3
  43. package/frontend/dist/assets/{NotebookPage-BOiYcs-l.js → NotebookPage-B-mcSRJm.js} +1 -1
  44. package/frontend/dist/assets/{OfficePreview-C5N2gr8-.js → OfficePreview-C3rHS2Te.js} +2 -2
  45. package/frontend/dist/assets/{PdfPreview-COG-9AQa.js → PdfPreview-B-toyaoA.js} +1 -1
  46. package/frontend/dist/assets/{ProjectPage-ARPH_J5o.js → ProjectPage-CShqyrUl.js} +4 -4
  47. package/frontend/dist/assets/{ProjectSettingsPage-CMWcT-5r.js → ProjectSettingsPage-FxkEGuUP.js} +1 -1
  48. package/frontend/dist/assets/{SettingsPage-BMrIDtg8.js → SettingsPage-B-bqNp6b.js} +1 -1
  49. package/frontend/dist/assets/{SkillHubPage-Bq93A7Rt.js → SkillHubPage-DN79j9Is.js} +1 -1
  50. package/frontend/dist/assets/{check-circle-2-BGT1eH1f.js → check-circle-2-DRT7EX5I.js} +1 -1
  51. package/frontend/dist/assets/{chevron-down-Bbg11n9i.js → chevron-down-DdtdiM4b.js} +1 -1
  52. package/frontend/dist/assets/{chevron-left-BmStQriC.js → chevron-left-Chv-EE6G.js} +1 -1
  53. package/frontend/dist/assets/{file-text-D9WjmbhK.js → file-text-D3ZDULSr.js} +1 -1
  54. package/frontend/dist/assets/{index-EFhMcMWk.js → index-BIGQ6n-i.js} +2 -2
  55. package/frontend/dist/assets/index-BpdaJxoa.css +1 -0
  56. package/frontend/dist/assets/{index-BRqvDxO6.js → index-CH1oLpmL.js} +1 -1
  57. package/frontend/dist/assets/{index-Bhp9CVTp.js → index-Dbm49BgL.js} +1 -1
  58. package/frontend/dist/assets/{index-COZnAgez.js → index-xJR85RJZ.js} +1 -1
  59. package/frontend/dist/assets/{jszip.min-Dyo__hKc.js → jszip.min-CMcZF4_M.js} +1 -1
  60. package/frontend/dist/assets/{save-CAjdgnp7.js → save-Dhw-I0uF.js} +1 -1
  61. package/frontend/dist/assets/{search-DmWhhICR.js → search-zoOED2R0.js} +1 -1
  62. package/frontend/dist/assets/{select-DAfsBGCS.js → select-B7xEE81_.js} +1 -1
  63. package/frontend/dist/assets/{tabs-zra46FZv.js → tabs-BCHX4LWy.js} +1 -1
  64. package/frontend/dist/assets/{textarea-BG4Tvy0e.js → textarea-CGPmR1Ae.js} +1 -1
  65. package/frontend/dist/index.html +2 -2
  66. package/package.json +36 -10
  67. package/backend/dist/backup/config.d.ts +0 -10
  68. package/backend/dist/backup/config.d.ts.map +0 -1
  69. package/backend/dist/backup/config.js +0 -128
  70. package/backend/dist/backup/config.js.map +0 -1
  71. package/backend/dist/backup/engine.d.ts +0 -22
  72. package/backend/dist/backup/engine.d.ts.map +0 -1
  73. package/backend/dist/backup/engine.js +0 -298
  74. package/backend/dist/backup/engine.js.map +0 -1
  75. package/backend/dist/backup/providers/dropbox.d.ts +0 -25
  76. package/backend/dist/backup/providers/dropbox.d.ts.map +0 -1
  77. package/backend/dist/backup/providers/dropbox.js +0 -320
  78. package/backend/dist/backup/providers/dropbox.js.map +0 -1
  79. package/backend/dist/backup/providers/google-drive.d.ts +0 -29
  80. package/backend/dist/backup/providers/google-drive.d.ts.map +0 -1
  81. package/backend/dist/backup/providers/google-drive.js +0 -303
  82. package/backend/dist/backup/providers/google-drive.js.map +0 -1
  83. package/backend/dist/backup/providers/index.d.ts +0 -3
  84. package/backend/dist/backup/providers/index.d.ts.map +0 -1
  85. package/backend/dist/backup/providers/index.js +0 -19
  86. package/backend/dist/backup/providers/index.js.map +0 -1
  87. package/backend/dist/backup/providers/onedrive.d.ts +0 -29
  88. package/backend/dist/backup/providers/onedrive.d.ts.map +0 -1
  89. package/backend/dist/backup/providers/onedrive.js +0 -317
  90. package/backend/dist/backup/providers/onedrive.js.map +0 -1
  91. package/backend/dist/backup/scheduler.d.ts +0 -6
  92. package/backend/dist/backup/scheduler.d.ts.map +0 -1
  93. package/backend/dist/backup/scheduler.js +0 -55
  94. package/backend/dist/backup/scheduler.js.map +0 -1
  95. package/backend/dist/backup/types.d.ts +0 -73
  96. package/backend/dist/backup/types.d.ts.map +0 -1
  97. package/backend/dist/backup/types.js +0 -4
  98. package/backend/dist/backup/types.js.map +0 -1
  99. package/backend/dist/chat-process-manager.d.ts +0 -45
  100. package/backend/dist/chat-process-manager.d.ts.map +0 -1
  101. package/backend/dist/chat-process-manager.js +0 -258
  102. package/backend/dist/chat-process-manager.js.map +0 -1
  103. package/backend/dist/flows/runner.d.ts +0 -37
  104. package/backend/dist/flows/runner.d.ts.map +0 -1
  105. package/backend/dist/flows/runner.js +0 -660
  106. package/backend/dist/flows/runner.js.map +0 -1
  107. package/backend/dist/flows/store.d.ts +0 -40
  108. package/backend/dist/flows/store.d.ts.map +0 -1
  109. package/backend/dist/flows/store.js +0 -284
  110. package/backend/dist/flows/store.js.map +0 -1
  111. package/backend/dist/flows/types.d.ts +0 -176
  112. package/backend/dist/flows/types.d.ts.map +0 -1
  113. package/backend/dist/flows/types.js +0 -25
  114. package/backend/dist/flows/types.js.map +0 -1
  115. package/backend/dist/information/condenser.d.ts +0 -12
  116. package/backend/dist/information/condenser.d.ts.map +0 -1
  117. package/backend/dist/information/condenser.js +0 -568
  118. package/backend/dist/information/condenser.js.map +0 -1
  119. package/backend/dist/information/conversation-sync.d.ts +0 -22
  120. package/backend/dist/information/conversation-sync.d.ts.map +0 -1
  121. package/backend/dist/information/conversation-sync.js +0 -500
  122. package/backend/dist/information/conversation-sync.js.map +0 -1
  123. package/backend/dist/information/types.d.ts +0 -36
  124. package/backend/dist/information/types.d.ts.map +0 -1
  125. package/backend/dist/information/types.js +0 -4
  126. package/backend/dist/information/types.js.map +0 -1
  127. package/backend/dist/memory-pool/buoyancy.d.ts +0 -2
  128. package/backend/dist/memory-pool/buoyancy.d.ts.map +0 -1
  129. package/backend/dist/memory-pool/buoyancy.js +0 -12
  130. package/backend/dist/memory-pool/buoyancy.js.map +0 -1
  131. package/backend/dist/memory-pool/global-pool-manager.d.ts +0 -12
  132. package/backend/dist/memory-pool/global-pool-manager.d.ts.map +0 -1
  133. package/backend/dist/memory-pool/global-pool-manager.js +0 -295
  134. package/backend/dist/memory-pool/global-pool-manager.js.map +0 -1
  135. package/backend/dist/memory-pool/pool-lock.d.ts +0 -2
  136. package/backend/dist/memory-pool/pool-lock.d.ts.map +0 -1
  137. package/backend/dist/memory-pool/pool-lock.js +0 -31
  138. package/backend/dist/memory-pool/pool-lock.js.map +0 -1
  139. package/backend/dist/memory-pool/pool-manager.d.ts +0 -57
  140. package/backend/dist/memory-pool/pool-manager.d.ts.map +0 -1
  141. package/backend/dist/memory-pool/pool-manager.js +0 -322
  142. package/backend/dist/memory-pool/pool-manager.js.map +0 -1
  143. package/backend/dist/memory-pool/templates.d.ts +0 -5
  144. package/backend/dist/memory-pool/templates.d.ts.map +0 -1
  145. package/backend/dist/memory-pool/templates.js +0 -234
  146. package/backend/dist/memory-pool/templates.js.map +0 -1
  147. package/backend/dist/memory-pool/types.d.ts +0 -61
  148. package/backend/dist/memory-pool/types.d.ts.map +0 -1
  149. package/backend/dist/memory-pool/types.js +0 -4
  150. package/backend/dist/memory-pool/types.js.map +0 -1
  151. package/backend/dist/plan-control/checker.d.ts +0 -3
  152. package/backend/dist/plan-control/checker.d.ts.map +0 -1
  153. package/backend/dist/plan-control/checker.js +0 -103
  154. package/backend/dist/plan-control/checker.js.map +0 -1
  155. package/backend/dist/plan-control/executor.d.ts +0 -93
  156. package/backend/dist/plan-control/executor.d.ts.map +0 -1
  157. package/backend/dist/plan-control/executor.js +0 -955
  158. package/backend/dist/plan-control/executor.js.map +0 -1
  159. package/backend/dist/plan-control/parser.d.ts +0 -12
  160. package/backend/dist/plan-control/parser.d.ts.map +0 -1
  161. package/backend/dist/plan-control/parser.js +0 -216
  162. package/backend/dist/plan-control/parser.js.map +0 -1
  163. package/backend/dist/plan-control/templates.d.ts +0 -4
  164. package/backend/dist/plan-control/templates.d.ts.map +0 -1
  165. package/backend/dist/plan-control/templates.js +0 -271
  166. package/backend/dist/plan-control/templates.js.map +0 -1
  167. package/backend/dist/plan-control/types.d.ts +0 -102
  168. package/backend/dist/plan-control/types.d.ts.map +0 -1
  169. package/backend/dist/plan-control/types.js +0 -12
  170. package/backend/dist/plan-control/types.js.map +0 -1
  171. package/backend/dist/routes/backup.d.ts +0 -4
  172. package/backend/dist/routes/backup.d.ts.map +0 -1
  173. package/backend/dist/routes/backup.js +0 -274
  174. package/backend/dist/routes/backup.js.map +0 -1
  175. package/backend/dist/routes/flows.d.ts +0 -5
  176. package/backend/dist/routes/flows.d.ts.map +0 -1
  177. package/backend/dist/routes/flows.js +0 -457
  178. package/backend/dist/routes/flows.js.map +0 -1
  179. package/backend/dist/routes/global-flows.d.ts +0 -3
  180. package/backend/dist/routes/global-flows.d.ts.map +0 -1
  181. package/backend/dist/routes/global-flows.js +0 -90
  182. package/backend/dist/routes/global-flows.js.map +0 -1
  183. package/backend/dist/routes/information.d.ts +0 -3
  184. package/backend/dist/routes/information.d.ts.map +0 -1
  185. package/backend/dist/routes/information.js +0 -159
  186. package/backend/dist/routes/information.js.map +0 -1
  187. package/backend/dist/routes/memory-pool.d.ts +0 -3
  188. package/backend/dist/routes/memory-pool.d.ts.map +0 -1
  189. package/backend/dist/routes/memory-pool.js +0 -837
  190. package/backend/dist/routes/memory-pool.js.map +0 -1
  191. package/backend/dist/routes/plan-control.d.ts +0 -15
  192. package/backend/dist/routes/plan-control.d.ts.map +0 -1
  193. package/backend/dist/routes/plan-control.js +0 -337
  194. package/backend/dist/routes/plan-control.js.map +0 -1
  195. package/backend/dist/routes/share.d.ts +0 -3
  196. package/backend/dist/routes/share.d.ts.map +0 -1
  197. package/backend/dist/routes/share.js +0 -167
  198. package/backend/dist/routes/share.js.map +0 -1
  199. package/backend/dist/routes/sounds.d.ts +0 -3
  200. package/backend/dist/routes/sounds.d.ts.map +0 -1
  201. package/backend/dist/routes/sounds.js +0 -285
  202. package/backend/dist/routes/sounds.js.map +0 -1
  203. package/backend/dist/tracks/__tests__/verify-starter-templates.d.ts +0 -24
  204. package/backend/dist/tracks/__tests__/verify-starter-templates.d.ts.map +0 -1
  205. package/backend/dist/tracks/__tests__/verify-starter-templates.js +0 -175
  206. package/backend/dist/tracks/__tests__/verify-starter-templates.js.map +0 -1
  207. package/backend/dist/tracks/__tests__/verify-track-cancel.d.ts +0 -23
  208. package/backend/dist/tracks/__tests__/verify-track-cancel.d.ts.map +0 -1
  209. package/backend/dist/tracks/__tests__/verify-track-cancel.js +0 -153
  210. package/backend/dist/tracks/__tests__/verify-track-cancel.js.map +0 -1
  211. package/backend/dist/tracks/__tests__/verify-track-t1.d.ts +0 -11
  212. package/backend/dist/tracks/__tests__/verify-track-t1.d.ts.map +0 -1
  213. package/backend/dist/tracks/__tests__/verify-track-t1.js +0 -293
  214. package/backend/dist/tracks/__tests__/verify-track-t1.js.map +0 -1
  215. package/backend/dist/tracks/__tests__/verify-track.d.ts +0 -20
  216. package/backend/dist/tracks/__tests__/verify-track.d.ts.map +0 -1
  217. package/backend/dist/tracks/__tests__/verify-track.js +0 -187
  218. package/backend/dist/tracks/__tests__/verify-track.js.map +0 -1
  219. package/backend/dist/tracks/registry.d.ts +0 -61
  220. package/backend/dist/tracks/registry.d.ts.map +0 -1
  221. package/backend/dist/tracks/registry.js +0 -202
  222. package/backend/dist/tracks/registry.js.map +0 -1
  223. package/backend/dist/tracks/track-runner.d.ts +0 -69
  224. package/backend/dist/tracks/track-runner.d.ts.map +0 -1
  225. package/backend/dist/tracks/track-runner.js +0 -158
  226. package/backend/dist/tracks/track-runner.js.map +0 -1
  227. package/backend/dist/tracks/train-loader.d.ts +0 -44
  228. package/backend/dist/tracks/train-loader.d.ts.map +0 -1
  229. package/backend/dist/tracks/train-loader.js +0 -32
  230. package/backend/dist/tracks/train-loader.js.map +0 -1
  231. package/backend/dist/tracks/types-train.d.ts +0 -12
  232. package/backend/dist/tracks/types-train.d.ts.map +0 -1
  233. package/backend/dist/tracks/types-train.js +0 -13
  234. package/backend/dist/tracks/types-train.js.map +0 -1
  235. package/backend/dist/usage-terminal.d.ts +0 -18
  236. package/backend/dist/usage-terminal.d.ts.map +0 -1
  237. package/backend/dist/usage-terminal.js +0 -191
  238. package/backend/dist/usage-terminal.js.map +0 -1
  239. package/frontend/dist/assets/index-GfCaMXPO.css +0 -1
@@ -1,298 +0,0 @@
1
- "use strict";
2
- // backend/src/backup/engine.ts
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || (function () {
20
- var ownKeys = function(o) {
21
- ownKeys = Object.getOwnPropertyNames || function (o) {
22
- var ar = [];
23
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
- return ar;
25
- };
26
- return ownKeys(o);
27
- };
28
- return function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
- })();
36
- Object.defineProperty(exports, "__esModule", { value: true });
37
- exports.computeHash = computeHash;
38
- exports.shouldExclude = shouldExclude;
39
- exports.scanDirectory = scanDirectory;
40
- exports.runBackup = runBackup;
41
- exports.runBackupAll = runBackupAll;
42
- const fs = __importStar(require("fs"));
43
- const path = __importStar(require("path"));
44
- const crypto = __importStar(require("crypto"));
45
- const minimatch_1 = require("minimatch");
46
- const uuid_1 = require("uuid");
47
- const config_1 = require("./config");
48
- const providers_1 = require("./providers");
49
- const config_2 = require("../config");
50
- function computeHash(filePath) {
51
- return new Promise((resolve, reject) => {
52
- const hash = crypto.createHash('sha256');
53
- const stream = fs.createReadStream(filePath);
54
- stream.on('data', (chunk) => hash.update(chunk));
55
- stream.on('end', () => resolve(`sha256:${hash.digest('hex')}`));
56
- stream.on('error', reject);
57
- });
58
- }
59
- function shouldExclude(relativePath, patterns) {
60
- const segments = relativePath.split('/');
61
- for (const pattern of patterns) {
62
- // Match full relative path
63
- if ((0, minimatch_1.minimatch)(relativePath, pattern, { dot: true, matchBase: true })) {
64
- return true;
65
- }
66
- // Match each path segment individually
67
- for (const segment of segments) {
68
- if ((0, minimatch_1.minimatch)(segment, pattern, { dot: true, matchBase: true })) {
69
- return true;
70
- }
71
- }
72
- }
73
- return false;
74
- }
75
- const MAX_SCAN_DEPTH = 50;
76
- function scanDirectory(dirPath, excludePatterns, basePath, depth = 0) {
77
- const result = new Map();
78
- if (depth > MAX_SCAN_DEPTH)
79
- return result; // prevent symlink cycles
80
- const base = basePath ?? dirPath;
81
- let entries;
82
- try {
83
- entries = fs.readdirSync(dirPath, { withFileTypes: true });
84
- }
85
- catch {
86
- return result;
87
- }
88
- for (const entry of entries) {
89
- const fullPath = path.join(dirPath, entry.name);
90
- const relativePath = path.relative(base, fullPath).replace(/\\/g, '/');
91
- if (shouldExclude(relativePath, excludePatterns)) {
92
- continue;
93
- }
94
- if (entry.isDirectory()) {
95
- const subResult = scanDirectory(fullPath, excludePatterns, base, depth + 1);
96
- for (const [relPath, info] of subResult) {
97
- result.set(relPath, info);
98
- }
99
- }
100
- else if (entry.isFile()) {
101
- try {
102
- const stat = fs.statSync(fullPath);
103
- result.set(relativePath, {
104
- mtime: stat.mtimeMs,
105
- size: stat.size,
106
- });
107
- }
108
- catch {
109
- // Skip unreadable files
110
- }
111
- }
112
- }
113
- return result;
114
- }
115
- async function runBackup(projectId, onProgress) {
116
- const config = (0, config_1.getBackupConfig)();
117
- const authorizedProviders = config.providers.filter((p) => p.tokens);
118
- if (authorizedProviders.length === 0) {
119
- return [];
120
- }
121
- const projects = (0, config_2.getProjects)();
122
- const project = projects.find((p) => p.id === projectId && !p.archived);
123
- if (!project) {
124
- throw new Error(`Project ${projectId} not found or archived`);
125
- }
126
- if (!fs.existsSync(project.folderPath)) {
127
- throw new Error(`Project folder does not exist: ${project.folderPath}`);
128
- }
129
- const excludePatterns = config.excludePatterns ?? [];
130
- // Step 1: Scan local files
131
- const scanned = scanDirectory(project.folderPath, excludePatterns);
132
- // Step 2: Load previous backup state
133
- const prevState = (0, config_1.getBackupState)(project.folderPath);
134
- // Step 3: Determine which files need uploading (changed or new)
135
- const newFiles = {};
136
- const toUpload = []; // relative paths
137
- for (const [relPath, { mtime, size }] of scanned) {
138
- const prev = prevState.files[relPath];
139
- if (prev && prev.mtime === mtime && prev.size === size) {
140
- // Unchanged: keep previous snapshot
141
- newFiles[relPath] = prev;
142
- }
143
- else {
144
- // Changed or new: compute hash
145
- const fullPath = path.join(project.folderPath, relPath);
146
- let hash;
147
- try {
148
- hash = await computeHash(fullPath);
149
- }
150
- catch {
151
- // Unreadable file, skip
152
- continue;
153
- }
154
- if (prev && prev.hash === hash) {
155
- // Content unchanged, just update mtime/size
156
- newFiles[relPath] = { mtime, size, hash };
157
- }
158
- else {
159
- // Content changed: queue for upload
160
- newFiles[relPath] = { mtime, size, hash };
161
- toUpload.push(relPath);
162
- }
163
- }
164
- }
165
- // Step 4: Detect deletions (files in prev state no longer present locally)
166
- const toDelete = [];
167
- for (const relPath of Object.keys(prevState.files)) {
168
- if (!scanned.has(relPath)) {
169
- toDelete.push(relPath);
170
- }
171
- }
172
- const totalFiles = scanned.size;
173
- const startTime = new Date().toISOString();
174
- const results = [];
175
- // Step 5: Run backup for each provider in parallel
176
- const providerResults = await Promise.all(authorizedProviders.map(async (providerConfig) => {
177
- const provider = (0, providers_1.createProvider)(providerConfig);
178
- let filesUploaded = 0;
179
- let filesDeleted = 0;
180
- let entryStatus = 'success';
181
- let errorMsg;
182
- const reportProgress = (status, uploaded = filesUploaded, deleted = filesDeleted) => {
183
- onProgress?.({
184
- projectId,
185
- projectName: project.name,
186
- providerId: providerConfig.id,
187
- providerLabel: providerConfig.label,
188
- status,
189
- filesUploaded: uploaded,
190
- filesDeleted: deleted,
191
- filesTotal: totalFiles,
192
- });
193
- };
194
- try {
195
- const tokensBefore = JSON.stringify(providerConfig.tokens);
196
- await provider.ensureAuth();
197
- // Persist refreshed tokens to disk if they changed
198
- // Re-read config to avoid overwriting other providers' token changes
199
- if (JSON.stringify(providerConfig.tokens) !== tokensBefore) {
200
- const freshConfig = (0, config_1.getBackupConfig)();
201
- const freshIdx = freshConfig.providers.findIndex((p) => p.id === providerConfig.id);
202
- if (freshIdx >= 0) {
203
- freshConfig.providers[freshIdx] = { ...freshConfig.providers[freshIdx], tokens: providerConfig.tokens };
204
- (0, config_1.saveBackupConfig)(freshConfig);
205
- }
206
- }
207
- // Create base remote directory
208
- const baseRemotePath = `CCWeb/${project.name}`;
209
- await provider.mkdir(baseRemotePath);
210
- // Upload changed files
211
- reportProgress('uploading');
212
- for (const relPath of toUpload) {
213
- const localPath = path.join(project.folderPath, relPath);
214
- const remotePath = `${baseRemotePath}/${relPath}`;
215
- // Ensure parent directory exists
216
- const remoteDir = path.dirname(remotePath).replace(/\\/g, '/');
217
- if (remoteDir !== baseRemotePath) {
218
- await provider.mkdir(remoteDir);
219
- }
220
- try {
221
- await provider.uploadFile(localPath, remotePath);
222
- filesUploaded++;
223
- reportProgress('uploading');
224
- }
225
- catch (err) {
226
- // Continue on individual file error
227
- entryStatus = 'partial';
228
- }
229
- }
230
- // Delete orphaned remote files
231
- reportProgress('deleting', filesUploaded, filesDeleted);
232
- for (const relPath of toDelete) {
233
- const remotePath = `${baseRemotePath}/${relPath}`;
234
- try {
235
- await provider.deleteFile(remotePath);
236
- filesDeleted++;
237
- reportProgress('deleting', filesUploaded, filesDeleted);
238
- }
239
- catch {
240
- // Ignore delete errors (file may already be gone)
241
- }
242
- }
243
- reportProgress('done', filesUploaded, filesDeleted);
244
- }
245
- catch (err) {
246
- entryStatus = 'failed';
247
- errorMsg = err?.message ?? String(err);
248
- reportProgress('error', filesUploaded, filesDeleted);
249
- }
250
- const endTime = new Date().toISOString();
251
- const entry = {
252
- id: (0, uuid_1.v4)(),
253
- projectId,
254
- projectName: project.name,
255
- providerId: providerConfig.id,
256
- providerType: providerConfig.type,
257
- providerLabel: providerConfig.label,
258
- startTime,
259
- endTime,
260
- status: entryStatus,
261
- filesUploaded,
262
- filesDeleted,
263
- filesTotal: totalFiles,
264
- error: errorMsg,
265
- };
266
- return { entry, success: entryStatus !== 'failed' };
267
- }));
268
- // Step 6: If any provider succeeded, save new backup state
269
- const anySuccess = providerResults.some((r) => r.success);
270
- if (anySuccess) {
271
- const newState = {
272
- lastBackupTime: new Date().toISOString(),
273
- files: newFiles,
274
- };
275
- (0, config_1.saveBackupState)(project.folderPath, newState);
276
- }
277
- // Step 7: Save history entries and collect results
278
- for (const { entry } of providerResults) {
279
- (0, config_1.addBackupHistory)(entry);
280
- results.push(entry);
281
- }
282
- return results;
283
- }
284
- async function runBackupAll(onProgress) {
285
- const projects = (0, config_2.getProjects)().filter((p) => !p.archived);
286
- const allResults = [];
287
- for (const project of projects) {
288
- try {
289
- const entries = await runBackup(project.id, onProgress);
290
- allResults.push(...entries);
291
- }
292
- catch {
293
- // Continue with other projects
294
- }
295
- }
296
- return allResults;
297
- }
298
- //# sourceMappingURL=engine.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/backup/engine.ts"],"names":[],"mappings":"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"}
@@ -1,25 +0,0 @@
1
- import { CloudProvider, ProviderConfig, ProviderTokens, RemoteFile } from '../types';
2
- export declare class DropboxProvider implements CloudProvider {
3
- config: ProviderConfig;
4
- private dbx;
5
- constructor(config: ProviderConfig);
6
- private initClient;
7
- private client;
8
- /**
9
- * Normalize a path to Dropbox format:
10
- * - Root is empty string ''
11
- * - All other paths start with '/' and have no trailing slash
12
- */
13
- private normPath;
14
- getAuthUrl(redirectUri: string, state?: string): string;
15
- handleCallback(code: string, redirectUri: string): Promise<ProviderTokens>;
16
- refreshToken(): Promise<ProviderTokens>;
17
- isAuthorized(): boolean;
18
- ensureAuth(): Promise<void>;
19
- listFiles(remotePath: string): Promise<RemoteFile[]>;
20
- uploadFile(localPath: string, remotePath: string): Promise<void>;
21
- deleteFile(remotePath: string): Promise<void>;
22
- mkdir(remotePath: string): Promise<void>;
23
- downloadFile(remotePath: string, localPath: string): Promise<void>;
24
- }
25
- //# sourceMappingURL=dropbox.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dropbox.d.ts","sourceRoot":"","sources":["../../../src/backup/providers/dropbox.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AASrF,qBAAa,eAAgB,YAAW,aAAa;IACnD,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,CAAC,GAAG,CAAwB;gBAEvB,MAAM,EAAE,cAAc;IAOlC,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,MAAM;IAOd;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAOhB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAWjD,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA8C1E,YAAY,IAAI,OAAO,CAAC,cAAc,CAAC;IAiD7C,YAAY,IAAI,OAAO;IAIjB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAuCpD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8EhE,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB7C,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAoBzE"}
@@ -1,320 +0,0 @@
1
- "use strict";
2
- // backend/src/backup/providers/dropbox.ts
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || (function () {
20
- var ownKeys = function(o) {
21
- ownKeys = Object.getOwnPropertyNames || function (o) {
22
- var ar = [];
23
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
- return ar;
25
- };
26
- return ownKeys(o);
27
- };
28
- return function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
- })();
36
- Object.defineProperty(exports, "__esModule", { value: true });
37
- exports.DropboxProvider = void 0;
38
- const fs = __importStar(require("fs"));
39
- const path = __importStar(require("path"));
40
- const dropbox_1 = require("dropbox");
41
- const TOKEN_ENDPOINT = 'https://api.dropboxapi.com/oauth2/token';
42
- // 150 MB threshold: above this use chunked upload session
43
- const SIMPLE_UPLOAD_MAX = 150 * 1024 * 1024;
44
- // 8 MB chunk size for upload sessions
45
- const CHUNK_SIZE = 8 * 1024 * 1024;
46
- class DropboxProvider {
47
- constructor(config) {
48
- this.dbx = null;
49
- this.config = config;
50
- if (config.tokens) {
51
- this.initClient(config.tokens.access_token);
52
- }
53
- }
54
- initClient(accessToken) {
55
- this.dbx = new dropbox_1.Dropbox({ accessToken });
56
- }
57
- client() {
58
- if (!this.dbx) {
59
- throw new Error('Dropbox client is not initialized');
60
- }
61
- return this.dbx;
62
- }
63
- /**
64
- * Normalize a path to Dropbox format:
65
- * - Root is empty string ''
66
- * - All other paths start with '/' and have no trailing slash
67
- */
68
- normPath(remotePath) {
69
- // Strip leading/trailing slashes then re-add leading slash if non-empty
70
- const stripped = remotePath.replace(/^\/+|\/+$/g, '');
71
- if (!stripped)
72
- return '';
73
- return '/' + stripped;
74
- }
75
- getAuthUrl(redirectUri, state) {
76
- const params = new URLSearchParams({
77
- client_id: this.config.clientId,
78
- response_type: 'code',
79
- redirect_uri: redirectUri,
80
- token_access_type: 'offline',
81
- ...(state ? { state } : {}),
82
- });
83
- return `https://www.dropbox.com/oauth2/authorize?${params.toString()}`;
84
- }
85
- async handleCallback(code, redirectUri) {
86
- const body = new URLSearchParams({
87
- code,
88
- grant_type: 'authorization_code',
89
- redirect_uri: redirectUri,
90
- });
91
- const credentials = Buffer.from(`${this.config.clientId}:${this.config.clientSecret}`).toString('base64');
92
- const res = await fetch(TOKEN_ENDPOINT, {
93
- method: 'POST',
94
- headers: {
95
- 'Content-Type': 'application/x-www-form-urlencoded',
96
- Authorization: `Basic ${credentials}`,
97
- },
98
- body: body.toString(),
99
- });
100
- if (!res.ok) {
101
- const text = await res.text();
102
- throw new Error(`Dropbox token exchange failed: ${res.status} ${text}`);
103
- }
104
- const data = (await res.json());
105
- if (!data.access_token || !data.refresh_token) {
106
- throw new Error('Missing tokens in Dropbox OAuth2 callback response');
107
- }
108
- const providerTokens = {
109
- access_token: data.access_token,
110
- refresh_token: data.refresh_token,
111
- expiry: new Date(Date.now() + data.expires_in * 1000).toISOString(),
112
- };
113
- this.config.tokens = providerTokens;
114
- this.initClient(providerTokens.access_token);
115
- return providerTokens;
116
- }
117
- async refreshToken() {
118
- if (!this.config.tokens?.refresh_token) {
119
- throw new Error('No refresh token available for Dropbox provider');
120
- }
121
- const body = new URLSearchParams({
122
- grant_type: 'refresh_token',
123
- refresh_token: this.config.tokens.refresh_token,
124
- });
125
- const credentials = Buffer.from(`${this.config.clientId}:${this.config.clientSecret}`).toString('base64');
126
- const res = await fetch(TOKEN_ENDPOINT, {
127
- method: 'POST',
128
- headers: {
129
- 'Content-Type': 'application/x-www-form-urlencoded',
130
- Authorization: `Basic ${credentials}`,
131
- },
132
- body: body.toString(),
133
- });
134
- if (!res.ok) {
135
- const text = await res.text();
136
- throw new Error(`Dropbox token refresh failed: ${res.status} ${text}`);
137
- }
138
- const data = (await res.json());
139
- if (!data.access_token) {
140
- throw new Error('Failed to refresh Dropbox access token');
141
- }
142
- const providerTokens = {
143
- access_token: data.access_token,
144
- refresh_token: data.refresh_token ?? this.config.tokens.refresh_token,
145
- expiry: new Date(Date.now() + data.expires_in * 1000).toISOString(),
146
- };
147
- this.config.tokens = providerTokens;
148
- this.initClient(providerTokens.access_token);
149
- return providerTokens;
150
- }
151
- isAuthorized() {
152
- return !!(this.config.tokens?.access_token && this.config.tokens?.refresh_token);
153
- }
154
- async ensureAuth() {
155
- if (!this.isAuthorized()) {
156
- throw new Error('Dropbox provider is not authorized');
157
- }
158
- const tokens = this.config.tokens;
159
- const expiryMs = new Date(tokens.expiry).getTime();
160
- const nowMs = Date.now();
161
- // Refresh if within 60 seconds of expiry
162
- if (expiryMs - nowMs < 60 * 1000) {
163
- await this.refreshToken();
164
- }
165
- }
166
- async listFiles(remotePath) {
167
- await this.ensureAuth();
168
- const dbxPath = this.normPath(remotePath);
169
- const results = [];
170
- let response = await this.client().filesListFolder({ path: dbxPath });
171
- while (true) {
172
- for (const entry of response.result.entries) {
173
- const isDirectory = entry['.tag'] === 'folder';
174
- const entryPath = entry.path_display ?? entry.path_lower ?? entry.name;
175
- // Return path relative to remotePath base (strip leading slash)
176
- const normalizedBase = remotePath.replace(/^\/+|\/+$/g, '');
177
- const relPath = normalizedBase
178
- ? `${normalizedBase}/${entry.name}`
179
- : entry.name;
180
- results.push({
181
- name: entry.name,
182
- path: relPath,
183
- isDirectory,
184
- size: isDirectory ? 0 : (entry.size ?? 0),
185
- modifiedTime: isDirectory
186
- ? new Date().toISOString()
187
- : (entry.server_modified ?? new Date().toISOString()),
188
- });
189
- }
190
- if (!response.result.has_more)
191
- break;
192
- response = await this.client().filesListFolderContinue({
193
- cursor: response.result.cursor,
194
- });
195
- }
196
- return results;
197
- }
198
- async uploadFile(localPath, remotePath) {
199
- await this.ensureAuth();
200
- const dbxPath = this.normPath(remotePath);
201
- const stat = fs.statSync(localPath);
202
- const fileSize = stat.size;
203
- if (fileSize < SIMPLE_UPLOAD_MAX) {
204
- // Simple upload
205
- const fileContent = fs.readFileSync(localPath);
206
- await this.client().filesUpload({
207
- path: dbxPath,
208
- mode: { '.tag': 'overwrite' },
209
- contents: fileContent,
210
- });
211
- }
212
- else {
213
- // Chunked upload session
214
- const fd = fs.openSync(localPath, 'r');
215
- try {
216
- // Start upload session with first chunk
217
- let offset = 0;
218
- const firstChunkSize = Math.min(CHUNK_SIZE, fileSize);
219
- const firstChunk = Buffer.alloc(firstChunkSize);
220
- fs.readSync(fd, firstChunk, 0, firstChunkSize, 0);
221
- offset += firstChunkSize;
222
- const startRes = await this.client().filesUploadSessionStart({
223
- close: false,
224
- contents: firstChunk,
225
- });
226
- const sessionId = startRes.result.session_id;
227
- // Append remaining chunks
228
- while (offset < fileSize) {
229
- const chunkSize = Math.min(CHUNK_SIZE, fileSize - offset);
230
- const chunk = Buffer.alloc(chunkSize);
231
- fs.readSync(fd, chunk, 0, chunkSize, offset);
232
- const isLast = offset + chunkSize >= fileSize;
233
- if (isLast) {
234
- // Finish the session
235
- await this.client().filesUploadSessionFinish({
236
- cursor: { session_id: sessionId, offset },
237
- commit: {
238
- path: dbxPath,
239
- mode: { '.tag': 'overwrite' },
240
- },
241
- contents: chunk,
242
- });
243
- }
244
- else {
245
- await this.client().filesUploadSessionAppendV2({
246
- cursor: { session_id: sessionId, offset },
247
- close: false,
248
- contents: chunk,
249
- });
250
- }
251
- offset += chunkSize;
252
- }
253
- // Edge case: file exactly one chunk — finish with empty content
254
- if (fileSize === firstChunkSize) {
255
- await this.client().filesUploadSessionFinish({
256
- cursor: { session_id: sessionId, offset },
257
- commit: {
258
- path: dbxPath,
259
- mode: { '.tag': 'overwrite' },
260
- },
261
- contents: Buffer.alloc(0),
262
- });
263
- }
264
- }
265
- finally {
266
- fs.closeSync(fd);
267
- }
268
- }
269
- }
270
- async deleteFile(remotePath) {
271
- await this.ensureAuth();
272
- const dbxPath = this.normPath(remotePath);
273
- try {
274
- await this.client().filesDeleteV2({ path: dbxPath });
275
- }
276
- catch (err) {
277
- // Ignore path_lookup errors (file not found) — treat as success
278
- const errObj = err;
279
- const summary = errObj?.error?.error_summary ?? '';
280
- if (!summary.startsWith('path_lookup/')) {
281
- throw err;
282
- }
283
- }
284
- }
285
- async mkdir(remotePath) {
286
- await this.ensureAuth();
287
- const dbxPath = this.normPath(remotePath);
288
- if (!dbxPath)
289
- return; // root always exists
290
- try {
291
- await this.client().filesCreateFolderV2({ path: dbxPath });
292
- }
293
- catch (err) {
294
- // Ignore path/conflict errors (folder already exists)
295
- const errObj = err;
296
- const summary = errObj?.error?.error_summary ?? '';
297
- if (!summary.startsWith('path/conflict')) {
298
- throw err;
299
- }
300
- }
301
- }
302
- async downloadFile(remotePath, localPath) {
303
- await this.ensureAuth();
304
- const dbxPath = this.normPath(remotePath);
305
- const res = await this.client().filesDownload({ path: dbxPath });
306
- // The SDK returns the binary content as `fileBinary` in the result
307
- const fileBinary = res.result.fileBinary;
308
- if (!fileBinary) {
309
- throw new Error(`Dropbox filesDownload returned no fileBinary for: ${remotePath}`);
310
- }
311
- // Ensure parent directory exists
312
- const parentDir = path.dirname(localPath);
313
- if (!fs.existsSync(parentDir)) {
314
- fs.mkdirSync(parentDir, { recursive: true });
315
- }
316
- fs.writeFileSync(localPath, fileBinary);
317
- }
318
- }
319
- exports.DropboxProvider = DropboxProvider;
320
- //# sourceMappingURL=dropbox.js.map