@tom2012/cc-web 2026.4.19-t → 2026.4.19-u

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 (40) hide show
  1. package/README.md +1 -1
  2. package/backend/dist/adapters/claude-adapter.d.ts.map +1 -1
  3. package/backend/dist/adapters/claude-adapter.js +107 -1
  4. package/backend/dist/adapters/claude-adapter.js.map +1 -1
  5. package/backend/dist/adapters/gemini-adapter.js +1 -1
  6. package/backend/dist/adapters/gemini-adapter.js.map +1 -1
  7. package/backend/dist/adapters/types.d.ts +3 -0
  8. package/backend/dist/adapters/types.d.ts.map +1 -1
  9. package/backend/dist/routes/skillhub.d.ts +27 -0
  10. package/backend/dist/routes/skillhub.d.ts.map +1 -1
  11. package/backend/dist/routes/skillhub.js +149 -180
  12. package/backend/dist/routes/skillhub.js.map +1 -1
  13. package/backend/dist/sync-service.d.ts +9 -6
  14. package/backend/dist/sync-service.d.ts.map +1 -1
  15. package/backend/dist/sync-service.js +84 -14
  16. package/backend/dist/sync-service.js.map +1 -1
  17. package/backend/package-lock.json +26 -0
  18. package/backend/package.json +2 -0
  19. package/frontend/dist/assets/{AssistantMessageContent-D1-3VpWE.js → AssistantMessageContent-DuOuKxgH.js} +2 -2
  20. package/frontend/dist/assets/{GraphPreview-CeI4sbtV.js → GraphPreview-UVA4ODDv.js} +1 -1
  21. package/frontend/dist/assets/MobilePage-8bMFdgD9.js +14 -0
  22. package/frontend/dist/assets/{OfficePreview-Dgs4aiYi.js → OfficePreview-DFa568OD.js} +2 -2
  23. package/frontend/dist/assets/{ProjectPage-DPv57nD9.js → ProjectPage-D23Cx4LX.js} +5 -5
  24. package/frontend/dist/assets/SettingsPage-CTTCafJA.js +13 -0
  25. package/frontend/dist/assets/SkillHubPage-BBWaNxzY.js +13 -0
  26. package/frontend/dist/assets/{chevron-down-CyDTNuVw.js → chevron-down-XjVVezAn.js} +1 -1
  27. package/frontend/dist/assets/{chevron-up-BURz786o.js → chevron-up-BD4j4icv.js} +1 -1
  28. package/frontend/dist/assets/index-BL3iZx_u.css +1 -0
  29. package/frontend/dist/assets/{index-z4qRGojt.js → index-Cz7UGH1l.js} +1 -1
  30. package/frontend/dist/assets/index-Qowsi3Ey.js +13 -0
  31. package/frontend/dist/assets/{index-BFWZX3Hz.js → index-hLxTQaCY.js} +10 -10
  32. package/frontend/dist/assets/{jszip.min-CPG_u-b-.js → jszip.min-BvfmA-CV.js} +1 -1
  33. package/frontend/dist/assets/{search-CZ83atP-.js → search-CdJtkP3F.js} +1 -1
  34. package/frontend/dist/index.html +2 -2
  35. package/package.json +1 -1
  36. package/frontend/dist/assets/MobilePage-BP7c3W3D.js +0 -14
  37. package/frontend/dist/assets/SettingsPage-CFSmKovg.js +0 -13
  38. package/frontend/dist/assets/SkillHubPage-4g29B-Hr.js +0 -13
  39. package/frontend/dist/assets/index-D0NB3R9q.css +0 -1
  40. package/frontend/dist/assets/index-Uy-V98k3.js +0 -13
@@ -34,34 +34,39 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const express_1 = require("express");
37
- const config_1 = require("../config");
38
- const uuid_1 = require("uuid");
39
37
  const https = __importStar(require("https"));
38
+ const yaml = __importStar(require("js-yaml"));
39
+ /**
40
+ * CCWeb Hub proxy.
41
+ *
42
+ * Serves a read-only view of `zbc0315/ccweb-hub`, which stores community-shared
43
+ * Quick Prompts (Shortcuts) and Agent Prompts as individual `.md` files in
44
+ * `quick-prompts/` and `agent-prompts/` directories. Each file has YAML
45
+ * frontmatter (`label`, `kind`, `author`, `tags`, `description`) and a body
46
+ * that is the prompt itself.
47
+ *
48
+ * Submission is handled client-side via a pre-filled GitHub Issue URL — there
49
+ * is no longer any write path through this server (avoids pitfalls #30: no
50
+ * token bundled in the npm package, ever).
51
+ *
52
+ * Plugin Hub (`/plugins` endpoint) still proxies `plugins.json` at repo root
53
+ * for the separate PluginDock install flow.
54
+ */
40
55
  const router = (0, express_1.Router)();
41
56
  const REPO_OWNER = 'zbc0315';
42
- const REPO_NAME = 'ccweb-skillhub';
57
+ const REPO_NAME = 'ccweb-hub';
43
58
  const RAW_BASE = `https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/main`;
44
59
  const API_BASE = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}`;
45
- // ── GitHub token ─────────────────────────────────────────────────────────────
46
- // SkillHub write operations (submit issue, download-count bump) require a GitHub
47
- // PAT scoped to the SkillHub repo. The token MUST come from the CCWEB_GITHUB_TOKEN
48
- // environment variable — never bundled in the npm package, since any installed
49
- // user would be able to extract it from backend/dist and gain write access to
50
- // the SkillHub repo (which in turn would poison every ccweb client via
51
- // plugins.json / skills.json).
60
+ // ── HTTP ─────────────────────────────────────────────────────────────────────
52
61
  //
53
- // When the env var is absent, write endpoints fail fast with a clear message;
54
- // read-only endpoints (/skills, /plugins) continue to work unauthenticated.
55
- function getGithubToken() {
56
- const token = process.env.CCWEB_GITHUB_TOKEN;
57
- return token && token.trim() ? token.trim() : null;
58
- }
59
- let cachedSkills = null;
60
- let cacheTime = 0;
61
- const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
62
- function httpGet(url, maxRedirects = 5) {
62
+ // Two distinct helpers: `apiGet` talks to the GitHub v3 API (JSON, versioned
63
+ // Accept header); `rawGet` fetches raw file content with no content negotiation
64
+ // assumption. Previously a single helper sent the API Accept header for raw
65
+ // requests too — harmless today but would break if GitHub raw ever starts to
66
+ // respect the Accept header strictly.
67
+ function request(url, accept, maxRedirects = 5) {
63
68
  return new Promise((resolve, reject) => {
64
- https.get(url, { headers: { 'User-Agent': 'CCWeb' } }, (res) => {
69
+ https.get(url, { headers: { 'User-Agent': 'CCWeb', 'Accept': accept } }, (res) => {
65
70
  if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
66
71
  if (maxRedirects <= 0) {
67
72
  reject(new Error('Too many redirects'));
@@ -72,14 +77,14 @@ function httpGet(url, maxRedirects = 5) {
72
77
  reject(new Error('Redirect to non-HTTPS URL blocked'));
73
78
  return;
74
79
  }
75
- httpGet(loc, maxRedirects - 1).then(resolve, reject);
80
+ request(loc, accept, maxRedirects - 1).then(resolve, reject);
76
81
  return;
77
82
  }
78
83
  let data = '';
79
84
  res.on('data', (chunk) => { data += chunk; });
80
85
  res.on('end', () => {
81
86
  if (res.statusCode && res.statusCode >= 400) {
82
- reject(new Error(`HTTP ${res.statusCode}: ${data}`));
87
+ reject(new Error(`HTTP ${res.statusCode}: ${data.slice(0, 200)}`));
83
88
  }
84
89
  else {
85
90
  resolve(data);
@@ -89,196 +94,160 @@ function httpGet(url, maxRedirects = 5) {
89
94
  }).on('error', reject);
90
95
  });
91
96
  }
92
- function githubApi(method, endpoint, body) {
93
- const token = getGithubToken();
94
- if (!token) {
95
- return Promise.reject(new Error('SkillHub write operations require CCWEB_GITHUB_TOKEN env var'));
97
+ const apiGet = (url) => request(url, 'application/vnd.github.v3+json');
98
+ const rawGet = (url) => request(url, '*/*');
99
+ function parseMarkdown(raw) {
100
+ // Recognize `---\n<yaml>\n---\n<body>`; anything else whole file is body.
101
+ const match = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/);
102
+ if (!match)
103
+ return { meta: {}, body: raw };
104
+ let meta = {};
105
+ try {
106
+ const loaded = yaml.load(match[1], { schema: yaml.FAILSAFE_SCHEMA });
107
+ if (loaded && typeof loaded === 'object')
108
+ meta = loaded;
96
109
  }
97
- const url = new URL(`${API_BASE}${endpoint}`);
98
- const postData = body ? JSON.stringify(body) : '';
99
- return new Promise((resolve, reject) => {
100
- const req = https.request({
101
- hostname: url.hostname,
102
- path: url.pathname + url.search,
103
- method,
104
- headers: {
105
- 'User-Agent': 'CCWeb',
106
- 'Authorization': `Bearer ${token}`,
107
- 'Accept': 'application/vnd.github.v3+json',
108
- 'Content-Type': 'application/json',
109
- 'Content-Length': Buffer.byteLength(postData),
110
- },
111
- }, (res) => {
112
- let data = '';
113
- res.on('data', (chunk) => { data += chunk; });
114
- res.on('end', () => {
115
- if (res.statusCode && res.statusCode >= 400) {
116
- reject(new Error(`GitHub API ${res.statusCode}: ${data}`));
117
- }
118
- else {
119
- resolve(data);
120
- }
121
- });
122
- res.on('error', reject);
123
- });
124
- req.on('error', reject);
125
- if (postData)
126
- req.write(postData);
127
- req.end();
128
- });
129
- }
130
- async function fetchSkills(forceRefresh = false) {
131
- const now = Date.now();
132
- if (!forceRefresh && cachedSkills && (now - cacheTime) < CACHE_TTL) {
133
- return cachedSkills;
110
+ catch {
111
+ // YAML malformed treat as no frontmatter rather than crashing the hub
134
112
  }
135
- try {
136
- const raw = await httpGet(`${RAW_BASE}/skills.json`);
137
- cachedSkills = JSON.parse(raw);
138
- cacheTime = now;
139
- return cachedSkills;
113
+ return { meta, body: match[2].trimStart() };
114
+ }
115
+ function coerceTags(raw) {
116
+ if (Array.isArray(raw)) {
117
+ const out = raw.filter((x) => typeof x === 'string');
118
+ return out.length ? out : undefined;
140
119
  }
141
- catch (err) {
142
- // Return cached data if available, even if expired
143
- if (cachedSkills)
144
- return cachedSkills;
145
- throw err;
120
+ if (typeof raw === 'string') {
121
+ // Single string split on comma for forgiving input
122
+ const split = raw.split(',').map((s) => s.trim()).filter(Boolean);
123
+ return split.length ? split : undefined;
146
124
  }
125
+ return undefined;
147
126
  }
148
- // ── Routes ───────────────────────────────────────────────────────────────────
149
- // GET /skills — fetch skill index
150
- router.get('/skills', async (_req, res) => {
127
+ // ── Cache ────────────────────────────────────────────────────────────────────
128
+ let cachedItems = null;
129
+ let cacheTime = 0;
130
+ const CACHE_TTL = 5 * 60 * 1000;
131
+ async function listDir(dir) {
151
132
  try {
152
- const skills = await fetchSkills();
153
- res.json(skills);
133
+ const raw = await apiGet(`${API_BASE}/contents/${dir}`);
134
+ const parsed = JSON.parse(raw);
135
+ return Array.isArray(parsed)
136
+ ? parsed.filter((f) => f && f.type === 'file' && f.name.endsWith('.md'))
137
+ : [];
154
138
  }
155
- catch (err) {
156
- res.status(502).json({ error: 'Failed to fetch SkillHub index', detail: err.message });
139
+ catch {
140
+ return []; // 404 = directory empty / absent — not an error
157
141
  }
158
- });
159
- // POST /submit — submit a skill via GitHub Issue
160
- router.post('/submit', async (req, res) => {
161
- const { label, command, description, author, tags, parentId } = req.body;
162
- if (!label || !command) {
163
- res.status(400).json({ error: 'label and command are required' });
164
- return;
142
+ }
143
+ async function fetchKind(kind) {
144
+ const dir = kind === 'quick-prompt' ? 'quick-prompts' : 'agent-prompts';
145
+ const files = await listDir(dir);
146
+ if (files.length === 0)
147
+ return [];
148
+ // Raw fetches are on raw.githubusercontent.com (not counted against the
149
+ // 60/hr GitHub API anon limit), so parallelizing is safe.
150
+ const results = await Promise.allSettled(files.map(async (file) => {
151
+ if (!file.download_url)
152
+ return null;
153
+ try {
154
+ const content = await rawGet(file.download_url);
155
+ const { meta, body } = parseMarkdown(content);
156
+ const basename = file.name.replace(/\.md$/, '');
157
+ const label = typeof meta.label === 'string' && meta.label ? meta.label : basename;
158
+ return {
159
+ id: `${kind}/${basename}`,
160
+ kind,
161
+ label,
162
+ body: body.trim(),
163
+ author: typeof meta.author === 'string' ? meta.author : undefined,
164
+ tags: coerceTags(meta.tags),
165
+ description: typeof meta.description === 'string' ? meta.description : undefined,
166
+ file: `${dir}/${file.name}`,
167
+ };
168
+ }
169
+ catch {
170
+ return null; // One bad file can't poison the whole kind
171
+ }
172
+ }));
173
+ return results
174
+ .map((r) => (r.status === 'fulfilled' ? r.value : null))
175
+ .filter((x) => x !== null);
176
+ }
177
+ async function fetchAllItems(forceRefresh = false) {
178
+ const now = Date.now();
179
+ if (!forceRefresh && cachedItems && (now - cacheTime) < CACHE_TTL) {
180
+ return cachedItems;
165
181
  }
166
- const skillData = {
167
- label,
168
- command,
169
- description: description || '',
170
- author: author || 'anonymous',
171
- tags: tags || [],
172
- createdAt: new Date().toISOString().slice(0, 10),
173
- };
174
- if (parentId)
175
- skillData.parentId = parentId;
176
- const issueBody = '```json\n' + JSON.stringify(skillData, null, 2) + '\n```';
182
+ // Resolve each kind independently — a transient failure on one directory
183
+ // should not make the whole hub appear broken.
184
+ const [quickRes, agentRes] = await Promise.allSettled([
185
+ fetchKind('quick-prompt'),
186
+ fetchKind('agent-prompt'),
187
+ ]);
188
+ const quick = quickRes.status === 'fulfilled' ? quickRes.value : [];
189
+ const agent = agentRes.status === 'fulfilled' ? agentRes.value : [];
190
+ if (quickRes.status === 'rejected')
191
+ console.warn('[ccweb-hub] quick-prompts fetch failed:', quickRes.reason);
192
+ if (agentRes.status === 'rejected')
193
+ console.warn('[ccweb-hub] agent-prompts fetch failed:', agentRes.reason);
194
+ cachedItems = [...quick, ...agent];
195
+ cacheTime = now;
196
+ return cachedItems;
197
+ }
198
+ // ── Routes ───────────────────────────────────────────────────────────────────
199
+ // GET /items — unified list of Quick Prompts + Agent Prompts in ccweb-hub
200
+ router.get('/items', async (_req, res) => {
177
201
  try {
178
- await githubApi('POST', '/issues', {
179
- title: `[Skill] ${label}`,
180
- body: issueBody,
181
- labels: ['new-skill'],
182
- });
183
- res.json({ success: true });
202
+ const items = await fetchAllItems();
203
+ res.json(items);
184
204
  }
185
205
  catch (err) {
186
- res.status(502).json({ error: 'Failed to submit to SkillHub', detail: err.message });
206
+ res.status(502).json({ error: 'Failed to fetch ccweb-hub', detail: err.message });
187
207
  }
188
208
  });
189
- // POST /download/:id download skill as global shortcut
190
- router.post('/download/:id', async (req, res) => {
191
- const { id } = req.params;
192
- const username = req.user?.username;
209
+ // GET /skills legacy alias for pre-hub clients. Returns the Quick Prompts
210
+ // subset in the old SkillHubItem shape. `createdAt` is set to current ISO so
211
+ // clients that sort by date don't choke on empty strings.
212
+ router.get('/skills', async (_req, res) => {
193
213
  try {
194
- const skills = await fetchSkills();
195
- const skill = skills.find((s) => s.id === id);
196
- if (!skill) {
197
- res.status(404).json({ error: 'Skill not found' });
198
- return;
199
- }
200
- // Resolve the full inheritance chain (parent first)
201
- const chain = [];
202
- const visited = new Set();
203
- let current = skill;
204
- while (current) {
205
- if (visited.has(current.id))
206
- break;
207
- visited.add(current.id);
208
- chain.unshift(current); // parent goes first
209
- current = current.parentId ? skills.find((s) => s.id === current.parentId) : undefined;
210
- }
211
- // Add all skills in the chain to global shortcuts, preserving parentId links
212
- const shortcuts = (0, config_1.getGlobalShortcuts)(username);
213
- // Map from SkillHub id → local shortcut id
214
- const idMap = new Map();
215
- for (const item of chain) {
216
- // Check if already exists
217
- const existing = shortcuts.find((s) => s.label === item.label && s.command === item.command);
218
- if (existing) {
219
- idMap.set(item.id, existing.id);
220
- }
221
- else {
222
- const localId = (0, uuid_1.v4)();
223
- const localParentId = item.parentId ? idMap.get(item.parentId) : undefined;
224
- const newItem = { id: localId, label: item.label, command: item.command };
225
- if (localParentId)
226
- newItem.parentId = localParentId;
227
- shortcuts.push(newItem);
228
- idMap.set(item.id, localId);
229
- }
230
- }
231
- (0, config_1.saveGlobalShortcuts)(shortcuts, username);
232
- const newShortcut = shortcuts.find((s) => s.id === idMap.get(skill.id));
233
- // Try to update download count in repo (best-effort, don't fail the request)
234
- try {
235
- // Get current skills.json content and sha
236
- const fileResp = await githubApi('GET', '/contents/skills.json');
237
- const fileData = JSON.parse(fileResp);
238
- const content = Buffer.from(fileData.content, 'base64').toString('utf-8');
239
- const repoSkills = JSON.parse(content);
240
- const target = repoSkills.find((s) => s.id === id);
241
- if (target) {
242
- target.downloads = (target.downloads || 0) + 1;
243
- const updated = Buffer.from(JSON.stringify(repoSkills, null, 2) + '\n').toString('base64');
244
- await githubApi('PUT', '/contents/skills.json', {
245
- message: `bump download count for ${id}`,
246
- content: updated,
247
- sha: fileData.sha,
248
- });
249
- // Update cache
250
- cachedSkills = repoSkills;
251
- cacheTime = Date.now();
252
- }
253
- }
254
- catch {
255
- // Silently ignore download count update failures
256
- }
257
- res.json(newShortcut);
214
+ const items = await fetchAllItems();
215
+ const iso = new Date().toISOString();
216
+ const legacy = items
217
+ .filter((i) => i.kind === 'quick-prompt')
218
+ .map((i) => ({
219
+ id: i.id,
220
+ label: i.label,
221
+ command: i.body,
222
+ description: i.description ?? '',
223
+ author: i.author ?? 'anonymous',
224
+ tags: i.tags ?? [],
225
+ downloads: 0,
226
+ createdAt: iso,
227
+ }));
228
+ res.json(legacy);
258
229
  }
259
230
  catch (err) {
260
- res.status(500).json({ error: 'Failed to download skill', detail: err.message });
231
+ res.status(502).json({ error: 'Failed to fetch ccweb-hub', detail: err.message });
261
232
  }
262
233
  });
263
- // ── Plugin Hub ──────────────────────────────────────────────────────────────
234
+ // ── Plugin Hub (unchanged — proxies plugins.json at hub repo root) ─────────
264
235
  let _pluginCache = null;
265
236
  let _pluginCacheTime = 0;
266
- const PLUGIN_CACHE_TTL = 5 * 60000; // 5 minutes
237
+ const PLUGIN_CACHE_TTL = 5 * 60000;
267
238
  router.get('/plugins', async (_req, res) => {
268
239
  const now = Date.now();
269
240
  if (_pluginCache && now - _pluginCacheTime < PLUGIN_CACHE_TTL) {
270
241
  return res.json(_pluginCache);
271
242
  }
272
243
  try {
273
- const url = `${RAW_BASE}/plugins.json`;
274
- const data = await httpGet(url);
244
+ const data = await rawGet(`${RAW_BASE}/plugins.json`);
275
245
  const plugins = JSON.parse(data);
276
246
  _pluginCache = Array.isArray(plugins) ? plugins : [];
277
247
  _pluginCacheTime = now;
278
248
  res.json(_pluginCache);
279
249
  }
280
250
  catch {
281
- // Return stale cache or empty
282
251
  res.json(_pluginCache ?? []);
283
252
  }
284
253
  });
@@ -1 +1 @@
1
- {"version":3,"file":"skillhub.js","sourceRoot":"","sources":["../../src/routes/skillhub.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skillhub.js","sourceRoot":"","sources":["../../src/routes/skillhub.ts"],"names":[],"mappings":"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"}
@@ -15,11 +15,15 @@ import { type SyncDirection } from './sync-config';
15
15
  * - **Concurrency**: one in-flight sync per (user, project); subsequent calls return
16
16
  * `{ skipped: true }`.
17
17
  * - **Logs**: written via createWriteStream (ordered); file truncated to keep the last
18
- * ~20 runs, preventing long-term growth (--stats is used so a run is ~20 lines, not
19
- * the hundreds of lines --progress emitted).
18
+ * ~20 runs, preventing long-term growth.
20
19
  * - **bidirectional**: is NOT a safe two-way sync (rsync can't). The push leg is run
21
20
  * without --delete and with -u (update-if-newer), so remote-newer files survive the
22
21
  * pull leg that follows. Deletions must be handled manually.
22
+ * - **openrsync (macOS 15+)**: shipped at `/usr/bin/rsync`, protocol 29. Doesn't support
23
+ * `--stats`; `-v` output doesn't include per-file lines. We use `-avzi` (itemize
24
+ * changes) which works on both GNU and openrsync, and parses telemetry from formats
25
+ * both emit (`>f`/`<f`-prefixed lines and the `total size is N` tail). A homebrew
26
+ * GNU rsync at `/opt/homebrew/bin/rsync` is preferred when present for richer output.
23
27
  */
24
28
  export interface SyncResult {
25
29
  ok: boolean;
@@ -39,10 +43,9 @@ export declare function syncProject(username: string, projectId: string, project
39
43
  export declare function isSyncing(username: string, projectId: string): boolean;
40
44
  export declare function listInFlight(username: string): string[];
41
45
  /**
42
- * Non-destructive connection test: runs `rsync --version` through the same
43
- * wrapper script rsync would use, so if this succeeds a real sync's
44
- * SSH setup will also succeed. Uses the test `exit 0` on the remote instead
45
- * of `--version` (which doesn't touch ssh at all).
46
+ * Non-destructive connection test: runs the wrapper script directly with
47
+ * `<user@host> true`. Uses the identical exec path as rsync's `-e`, so if
48
+ * this succeeds the sync's SSH setup will also succeed.
46
49
  */
47
50
  export declare function testConnection(username: string): Promise<{
48
51
  ok: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"sync-service.d.ts","sourceRoot":"","sources":["../src/sync-service.ts"],"names":[],"mappings":"AAMA,OAAO,EAEY,KAAK,aAAa,EACpC,MAAM,eAAe,CAAC;AAEvB;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA4ND;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,iBAAiB,CAAC,EAAE,aAAa,GAChC,OAAO,CAAC,UAAU,CAAC,CAsDrB;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAOvD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAkChG"}
1
+ {"version":3,"file":"sync-service.d.ts","sourceRoot":"","sources":["../src/sync-service.ts"],"names":[],"mappings":"AAMA,OAAO,EAEY,KAAK,aAAa,EACpC,MAAM,eAAe,CAAC;AAEvB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAkSD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,iBAAiB,CAAC,EAAE,aAAa,GAChC,OAAO,CAAC,UAAU,CAAC,CA6DrB;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAOvD;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAwChG"}