@quantiya/codevibe-core 1.0.2 → 1.0.4

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 (49) hide show
  1. package/README.md +15 -6
  2. package/bin/codevibe.js +1 -1
  3. package/dist/index.js +216 -67
  4. package/package.json +10 -10
  5. package/dist/appsync/appsync-client.d.ts +0 -132
  6. package/dist/appsync/appsync-client.js +0 -575
  7. package/dist/appsync/index.d.ts +0 -2
  8. package/dist/appsync/index.js +0 -10
  9. package/dist/appsync/queries.d.ts +0 -16
  10. package/dist/appsync/queries.js +0 -189
  11. package/dist/auth/auth-cli.d.ts +0 -5
  12. package/dist/auth/auth-cli.js +0 -217
  13. package/dist/auth/auth-service.d.ts +0 -53
  14. package/dist/auth/auth-service.js +0 -310
  15. package/dist/auth/index.d.ts +0 -2
  16. package/dist/auth/index.js +0 -9
  17. package/dist/config/config.d.ts +0 -53
  18. package/dist/config/config.js +0 -123
  19. package/dist/config/index.d.ts +0 -2
  20. package/dist/config/index.js +0 -8
  21. package/dist/crypto/crypto-service.d.ts +0 -118
  22. package/dist/crypto/crypto-service.js +0 -284
  23. package/dist/crypto/index.d.ts +0 -1
  24. package/dist/crypto/index.js +0 -9
  25. package/dist/index.d.ts +0 -14
  26. package/dist/keychain/index.d.ts +0 -1
  27. package/dist/keychain/index.js +0 -8
  28. package/dist/keychain/keychain-manager.d.ts +0 -125
  29. package/dist/keychain/keychain-manager.js +0 -375
  30. package/dist/logger/index.d.ts +0 -1
  31. package/dist/logger/index.js +0 -8
  32. package/dist/logger/logger.d.ts +0 -35
  33. package/dist/logger/logger.js +0 -142
  34. package/dist/prompt-parser.d.ts +0 -39
  35. package/dist/prompt-parser.js +0 -236
  36. package/dist/session/index.d.ts +0 -2
  37. package/dist/session/index.js +0 -7
  38. package/dist/session/session-resume.d.ts +0 -55
  39. package/dist/session/session-resume.js +0 -151
  40. package/dist/types/auth.d.ts +0 -15
  41. package/dist/types/auth.js +0 -3
  42. package/dist/types/encryption.d.ts +0 -54
  43. package/dist/types/encryption.js +0 -3
  44. package/dist/types/events.d.ts +0 -74
  45. package/dist/types/events.js +0 -28
  46. package/dist/types/index.d.ts +0 -4
  47. package/dist/types/index.js +0 -22
  48. package/dist/types/session.d.ts +0 -59
  49. package/dist/types/session.js +0 -22
@@ -1,236 +0,0 @@
1
- "use strict";
2
- /**
3
- * Shared prompt parser for interactive terminal prompts.
4
- *
5
- * Parses terminal snapshots (from tmux capture-pane) to extract
6
- * interactive prompt options displayed by CLI tools (Gemini, Codex, etc.).
7
- *
8
- * Used by multiple plugins to dynamically capture options instead of hardcoding.
9
- */
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.parseInteractivePrompt = parseInteractivePrompt;
12
- exports.normalizeSnapshot = normalizeSnapshot;
13
- const ANSI_PATTERN = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
14
- /**
15
- * Parse a terminal snapshot to extract interactive prompt options.
16
- *
17
- * Detects two prompt types:
18
- * - Yes/No prompts: [y/n] patterns
19
- * - Numbered prompts: "1. Allow once", "2. Allow for this session", etc.
20
- *
21
- * Returns null if no prompt is detected.
22
- */
23
- function parseInteractivePrompt(snapshot) {
24
- const normalized = normalizeSnapshot(snapshot);
25
- if (!normalized) {
26
- return null;
27
- }
28
- const yesNo = parseYesNoPrompt(normalized);
29
- if (yesNo) {
30
- return yesNo;
31
- }
32
- const numbered = parseNumberedPrompt(normalized);
33
- if (numbered) {
34
- return numbered;
35
- }
36
- return null;
37
- }
38
- /**
39
- * Strip ANSI escape codes, box-drawing characters, and normalize whitespace
40
- * from terminal output.
41
- *
42
- * Box-drawing characters (│, ┌, ┐, └, ┘, ─, etc.) are used by TUI apps like
43
- * Gemini CLI to render bordered panels. Stripping them exposes the text content
44
- * so the parser can match option lines inside boxes.
45
- */
46
- function normalizeSnapshot(snapshot) {
47
- return snapshot
48
- .replace(/\r/g, '\n')
49
- .replace(ANSI_PATTERN, '')
50
- .replace(/[│┌┐└┘─├┤┬┴┼╌╎╭╮╯╰║═╔╗╚╝╠╣╦╩╬]/g, ' ')
51
- .replace(/[ \t]+\n/g, '\n')
52
- .replace(/\n{3,}/g, '\n\n')
53
- .trim();
54
- }
55
- function parseYesNoPrompt(snapshot) {
56
- const lines = snapshot.split('\n').map(line => line.trim());
57
- const promptLineIndex = findLastMatchingLineIndex(lines, line => /\[(?:y\/n|Y\/n|y\/N)\]/.test(line));
58
- const promptLine = promptLineIndex >= 0 ? lines[promptLineIndex] : null;
59
- if (!promptLine) {
60
- return null;
61
- }
62
- const promptLines = extractPromptBlock(lines, promptLineIndex);
63
- const promptText = promptLines.length > 0 ? promptLines.join('\n') : promptLine;
64
- const lower = promptText.toLowerCase();
65
- const requiresFollowUpText = lower.includes('what to change') ||
66
- lower.includes('what should') ||
67
- lower.includes('provide') ||
68
- lower.includes('instructions');
69
- const options = requiresFollowUpText
70
- ? [
71
- { number: '1', text: 'Yes' },
72
- { number: '2', text: 'No, provide instructions' },
73
- ]
74
- : [
75
- { number: '1', text: 'Yes' },
76
- { number: '2', text: 'No' },
77
- ];
78
- const submitMap = {
79
- '1': 'y',
80
- '2': 'n',
81
- };
82
- return {
83
- kind: 'yes_no',
84
- promptText,
85
- options,
86
- submitMap,
87
- requiresFollowUpText,
88
- };
89
- }
90
- function parseNumberedPrompt(snapshot) {
91
- const lines = snapshot.split('\n').map(line => line.trim());
92
- const optionBlock = findTrailingOptionBlock(lines);
93
- if (optionBlock.length < 2) {
94
- return null;
95
- }
96
- const options = optionBlock
97
- .map(({ line }) => parseOptionLine(line))
98
- .filter((option) => !!option);
99
- const submitMap = {};
100
- for (const option of options) {
101
- submitMap[option.number] = option.number;
102
- }
103
- const firstOptionIndex = optionBlock[0]?.index ?? -1;
104
- const promptLines = extractPromptBlock(lines, firstOptionIndex - 1);
105
- const promptText = promptLines.length > 0 ? promptLines.join('\n') : 'Select an option';
106
- return {
107
- kind: 'numbered',
108
- promptText,
109
- options,
110
- submitMap,
111
- };
112
- }
113
- function findLastMatchingLineIndex(lines, predicate) {
114
- for (let index = lines.length - 1; index >= 0; index -= 1) {
115
- if (predicate(lines[index])) {
116
- return index;
117
- }
118
- }
119
- return -1;
120
- }
121
- function parseOptionLine(line) {
122
- const match = line.match(/^(?:[>›❯▸▶➜➤*●]\s*)?(\d+)\.\s+(.*)$/);
123
- if (!match) {
124
- return null;
125
- }
126
- return {
127
- number: match[1],
128
- text: match[2],
129
- };
130
- }
131
- function findTrailingOptionBlock(lines) {
132
- const matches = lines
133
- .map((line, index) => ({ index, line, parsed: parseOptionLine(line) }))
134
- .filter((entry) => !!entry.parsed);
135
- if (matches.length === 0) {
136
- return [];
137
- }
138
- const block = [matches[matches.length - 1]];
139
- for (let index = matches.length - 2; index >= 0; index -= 1) {
140
- const current = matches[index];
141
- const next = block[0];
142
- if (current.index !== next.index - 1) {
143
- break;
144
- }
145
- block.unshift(current);
146
- }
147
- return block.map(({ index, line }) => ({ index, line }));
148
- }
149
- function extractPromptBlock(lines, endIndex) {
150
- if (endIndex < 0) {
151
- return [];
152
- }
153
- let cursor = skipBlankLinesUp(lines, endIndex);
154
- if (cursor < 0) {
155
- return [];
156
- }
157
- const { start: mainBlockStart, end: blockEnd } = findNonEmptyBlockEndingAt(lines, cursor);
158
- const mainBlock = lines.slice(mainBlockStart, blockEnd + 1).filter(Boolean);
159
- if (isDiffPreviewBlock(mainBlock)) {
160
- const recoveredPrompt = collectPromptBlocksAbove(lines, mainBlockStart - 1);
161
- return recoveredPrompt.length > 0 ? recoveredPrompt : mainBlock;
162
- }
163
- if (mainBlockStart <= 1) {
164
- return mainBlock;
165
- }
166
- let gapCursor = mainBlockStart - 1;
167
- gapCursor = skipBlankLinesUp(lines, gapCursor);
168
- if (gapCursor < 0 || gapCursor === mainBlockStart - 1) {
169
- return mainBlock;
170
- }
171
- const { start: headingBlockStart, end: headingBlockEnd } = findNonEmptyBlockEndingAt(lines, gapCursor);
172
- const headingBlock = lines.slice(headingBlockStart, headingBlockEnd + 1).filter(Boolean);
173
- const headingMatched = headingBlock.some(isPromptHeadingLine);
174
- if (!headingMatched) {
175
- return mainBlock;
176
- }
177
- return [...headingBlock, ...mainBlock];
178
- }
179
- function isPromptHeadingLine(line) {
180
- return /^(?:would you like to|do you want to|the model would like to|action required|confirm)\b/i.test(line);
181
- }
182
- function isLikelyFileSummaryLine(line) {
183
- return /^.+\/[^/]+\s+\(\+\d+\s+-\d+\)$/.test(line);
184
- }
185
- function skipBlankLinesUp(lines, startIndex) {
186
- let cursor = startIndex;
187
- while (cursor >= 0 && !lines[cursor]) {
188
- cursor -= 1;
189
- }
190
- return cursor;
191
- }
192
- function findNonEmptyBlockEndingAt(lines, endIndex) {
193
- let cursor = endIndex;
194
- while (cursor >= 0 && lines[cursor]) {
195
- cursor -= 1;
196
- }
197
- return {
198
- start: cursor + 1,
199
- end: endIndex,
200
- };
201
- }
202
- function collectPromptBlocksAbove(lines, startIndex) {
203
- const blocks = [];
204
- let cursor = startIndex;
205
- while (cursor >= 0 && blocks.length < 2) {
206
- cursor = skipBlankLinesUp(lines, cursor);
207
- if (cursor < 0) {
208
- break;
209
- }
210
- const { start, end } = findNonEmptyBlockEndingAt(lines, cursor);
211
- const block = lines.slice(start, end + 1).filter(Boolean);
212
- if (block.length > 0) {
213
- blocks.unshift(block);
214
- }
215
- cursor = start - 1;
216
- }
217
- if (blocks.length === 0) {
218
- return [];
219
- }
220
- const headingBlockIndex = blocks.findIndex(block => block.some(isPromptHeadingLine));
221
- if (headingBlockIndex >= 0) {
222
- return blocks.slice(headingBlockIndex).flat();
223
- }
224
- return blocks[blocks.length - 1];
225
- }
226
- function isDiffPreviewBlock(lines) {
227
- if (lines.length === 0) {
228
- return false;
229
- }
230
- const lineNumberedRows = lines.filter(isLineNumberedDiffLine).length;
231
- return lineNumberedRows >= Math.max(2, Math.ceil(lines.length / 2));
232
- }
233
- function isLineNumberedDiffLine(line) {
234
- return /^\d+\s/.test(line);
235
- }
236
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbXB0LXBhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wcm9tcHQtcGFyc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7OztHQU9HOztBQTRCSCx3REFpQkM7QUFVRCw4Q0FRQztBQTlDRCxNQUFNLFlBQVksR0FBRyx3Q0FBd0MsQ0FBQztBQUU5RDs7Ozs7Ozs7R0FRRztBQUNILFNBQWdCLHNCQUFzQixDQUFDLFFBQWdCO0lBQ3JELE1BQU0sVUFBVSxHQUFHLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQy9DLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMzQyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ1YsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsTUFBTSxRQUFRLEdBQUcsbUJBQW1CLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDakQsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUNiLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsU0FBZ0IsaUJBQWlCLENBQUMsUUFBZ0I7SUFDaEQsT0FBTyxRQUFRO1NBQ1osT0FBTyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUM7U0FDcEIsT0FBTyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUM7U0FDekIsT0FBTyxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsQ0FBQztTQUMvQyxPQUFPLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQztTQUMxQixPQUFPLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQztTQUMxQixJQUFJLEVBQUUsQ0FBQztBQUNaLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLFFBQWdCO0lBQ3hDLE1BQU0sS0FB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TUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVELFNBQVMsa0JBQWtCLENBQUMsS0FBZTtJQUN6QyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdkIsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3JFLE9BQU8sZ0JBQWdCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEUsQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQUMsSUFBWTtJQUMxQyxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDN0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2hhcmVkIHByb21wdCBwYXJzZXIgZm9yIGludGVyYWN0aXZlIHRlcm1pbmFsIHByb21wdHMuXG4gKlxuICogUGFyc2VzIHRlcm1pbmFsIHNuYXBzaG90cyAoZnJvbSB0bXV4IGNhcHR1cmUtcGFuZSkgdG8gZXh0cmFjdFxuICogaW50ZXJhY3RpdmUgcHJvbXB0IG9wdGlvbnMgZGlzcGxheWVkIGJ5IENMSSB0b29scyAoR2VtaW5pLCBDb2RleCwgZXRjLikuXG4gKlxuICogVXNlZCBieSBtdWx0aXBsZSBwbHVnaW5zIHRvIGR5bmFtaWNhbGx5IGNhcHR1cmUgb3B0aW9ucyBpbnN0ZWFkIG9mIGhhcmRjb2RpbmcuXG4gKi9cblxuZXhwb3J0IHR5cGUgUHJvbXB0S2luZCA9ICd5ZXNfbm8nIHwgJ251bWJlcmVkJyB8ICd0ZXh0JztcblxuZXhwb3J0IGludGVyZmFjZSBJbnRlcmFjdGl2ZVByb21wdE9wdGlvbiB7XG4gIG51bWJlcjogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VkSW50ZXJhY3RpdmVQcm9tcHQge1xuICBraW5kOiBQcm9tcHRLaW5kO1xuICBwcm9tcHRUZXh0OiBzdHJpbmc7XG4gIG9wdGlvbnM6IEludGVyYWN0aXZlUHJvbXB0T3B0aW9uW107XG4gIHN1Ym1pdE1hcDogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgcmVxdWlyZXNGb2xsb3dVcFRleHQ/OiBib29sZWFuO1xufVxuXG5jb25zdCBBTlNJX1BBVFRFUk4gPSAvXFx4MUIoPzpbQC1aXFxcXC1fXXxcXFtbMC0/XSpbIC0vXSpbQC1+XSkvZztcblxuLyoqXG4gKiBQYXJzZSBhIHRlcm1pbmFsIHNuYXBzaG90IHRvIGV4dHJhY3QgaW50ZXJhY3RpdmUgcHJvbXB0IG9wdGlvbnMuXG4gKlxuICogRGV0ZWN0cyB0d28gcHJvbXB0IHR5cGVzOlxuICogLSBZZXMvTm8gcHJvbXB0czogW3kvbl0gcGF0dGVybnNcbiAqIC0gTnVtYmVyZWQgcHJvbXB0czogXCIxLiBBbGxvdyBvbmNlXCIsIFwiMi4gQWxsb3cgZm9yIHRoaXMgc2Vzc2lvblwiLCBldGMuXG4gKlxuICogUmV0dXJucyBudWxsIGlmIG5vIHByb21wdCBpcyBkZXRlY3RlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlSW50ZXJhY3RpdmVQcm9tcHQoc25hcHNob3Q6IHN0cmluZyk6IFBhcnNlZEludGVyYWN0aXZlUHJvbXB0IHwgbnVsbCB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVTbmFwc2hvdChzbmFwc2hvdCk7XG4gIGlmICghbm9ybWFsaXplZCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgeWVzTm8gPSBwYXJzZVllc05vUHJvbXB0KG5vcm1hbGl6ZWQpO1xuICBpZiAoeWVzTm8pIHtcbiAgICByZXR1cm4geWVzTm87XG4gIH1cblxuICBjb25zdCBudW1iZXJlZCA9IHBhcnNlTnVtYmVyZWRQcm9tcHQobm9ybWFsaXplZCk7XG4gIGlmIChudW1iZXJlZCkge1xuICAgIHJldHVybiBudW1iZXJlZDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFN0cmlwIEFOU0kgZXNjYXBlIGNvZGVzLCBib3gtZHJhd2luZyBjaGFyYWN0ZXJzLCBhbmQgbm9ybWFsaXplIHdoaXRlc3BhY2VcbiAqIGZyb20gdGVybWluYWwgb3V0cHV0LlxuICpcbiAqIEJveC1kcmF3aW5nIGNoYXJhY3RlcnMgKOKUgiwg4pSMLCDilJAsIOKUlCwg4pSYLCDilIAsIGV0Yy4pIGFyZSB1c2VkIGJ5IFRVSSBhcHBzIGxpa2VcbiAqIEdlbWluaSBDTEkgdG8gcmVuZGVyIGJvcmRlcmVkIHBhbmVscy4gU3RyaXBwaW5nIHRoZW0gZXhwb3NlcyB0aGUgdGV4dCBjb250ZW50XG4gKiBzbyB0aGUgcGFyc2VyIGNhbiBtYXRjaCBvcHRpb24gbGluZXMgaW5zaWRlIGJveGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplU25hcHNob3Qoc25hcHNob3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBzbmFwc2hvdFxuICAgIC5yZXBsYWNlKC9cXHIvZywgJ1xcbicpXG4gICAgLnJlcGxhY2UoQU5TSV9QQVRURVJOLCAnJylcbiAgICAucmVwbGFjZSgvW+KUguKUjOKUkOKUlOKUmOKUgOKUnOKUpOKUrOKUtOKUvOKVjOKVjuKVreKVruKVr+KVsOKVkeKVkOKVlOKVl+KVmuKVneKVoOKVo+KVpuKVqeKVrF0vZywgJyAnKVxuICAgIC5yZXBsYWNlKC9bIFxcdF0rXFxuL2csICdcXG4nKVxuICAgIC5yZXBsYWNlKC9cXG57Myx9L2csICdcXG5cXG4nKVxuICAgIC50cmltKCk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlWWVzTm9Qcm9tcHQoc25hcHNob3Q6IHN0cmluZyk6IFBhcnNlZEludGVyYWN0aXZlUHJvbXB0IHwgbnVsbCB7XG4gIGNvbnN0IGxpbmVzID0gc25hcHNob3Quc3BsaXQoJ1xcbicpLm1hcChsaW5lID0+IGxpbmUudHJpbSgpKTtcbiAgY29uc3QgcHJvbXB0TGluZUluZGV4ID0gZmluZExhc3RNYXRjaGluZ0xpbmVJbmRleChsaW5lcywgbGluZSA9PiAvXFxbKD86eVxcL258WVxcL258eVxcL04pXFxdLy50ZXN0KGxpbmUpKTtcbiAgY29uc3QgcHJvbXB0TGluZSA9IHByb21wdExpbmVJbmRleCA+PSAwID8gbGluZXNbcHJvbXB0TGluZUluZGV4XSA6IG51bGw7XG5cbiAgaWYgKCFwcm9tcHRMaW5lKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBwcm9tcHRMaW5lcyA9IGV4dHJhY3RQcm9tcHRCbG9jayhsaW5lcywgcHJvbXB0TGluZUluZGV4KTtcbiAgY29uc3QgcHJvbXB0VGV4dCA9IHByb21wdExpbmVzLmxlbmd0aCA+IDAgPyBwcm9tcHRMaW5lcy5qb2luKCdcXG4nKSA6IHByb21wdExpbmU7XG5cbiAgY29uc3QgbG93ZXIgPSBwcm9tcHRUZXh0LnRvTG93ZXJDYXNlKCk7XG4gIGNvbnN0IHJlcXVpcmVzRm9sbG93VXBUZXh0ID1cbiAgICBsb3dlci5pbmNsdWRlcygnd2hhdCB0byBjaGFuZ2UnKSB8fFxuICAgIGxvd2VyLmluY2x1ZGVzKCd3aGF0IHNob3VsZCcpIHx8XG4gICAgbG93ZXIuaW5jbHVkZXMoJ3Byb3ZpZGUnKSB8fFxuICAgIGxvd2VyLmluY2x1ZGVzKCdpbnN0cnVjdGlvbnMnKTtcblxuICBjb25zdCBvcHRpb25zOiBJbnRlcmFjdGl2ZVByb21wdE9wdGlvbltdID0gcmVxdWlyZXNGb2xsb3dVcFRleHRcbiAgICA/IFtcbiAgICAgICAgeyBudW1iZXI6ICcxJywgdGV4dDogJ1llcycgfSxcbiAgICAgICAgeyBudW1iZXI6ICcyJywgdGV4dDogJ05vLCBwcm92aWRlIGluc3RydWN0aW9ucycgfSxcbiAgICAgIF1cbiAgICA6IFtcbiAgICAgICAgeyBudW1iZXI6ICcxJywgdGV4dDogJ1llcycgfSxcbiAgICAgICAgeyBudW1iZXI6ICcyJywgdGV4dDogJ05vJyB9LFxuICAgICAgXTtcblxuICBjb25zdCBzdWJtaXRNYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgJzEnOiAneScsXG4gICAgJzInOiAnbicsXG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBraW5kOiAneWVzX25vJyxcbiAgICBwcm9tcHRUZXh0LFxuICAgIG9wdGlvbnMsXG4gICAgc3VibWl0TWFwLFxuICAgIHJlcXVpcmVzRm9sbG93VXBUZXh0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBwYXJzZU51bWJlcmVkUHJvbXB0KHNuYXBzaG90OiBzdHJpbmcpOiBQYXJzZWRJbnRlcmFjdGl2ZVByb21wdCB8IG51bGwge1xuICBjb25zdCBsaW5lcyA9IHNuYXBzaG90LnNwbGl0KCdcXG4nKS5tYXAobGluZSA9PiBsaW5lLnRyaW0oKSk7XG5cbiAgY29uc3Qgb3B0aW9uQmxvY2sgPSBmaW5kVHJhaWxpbmdPcHRpb25CbG9jayhsaW5lcyk7XG4gIGlmIChvcHRpb25CbG9jay5sZW5ndGggPCAyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0gb3B0aW9uQmxvY2tcbiAgICAubWFwKCh7IGxpbmUgfSkgPT4gcGFyc2VPcHRpb25MaW5lKGxpbmUpKVxuICAgIC5maWx0ZXIoKG9wdGlvbik6IG9wdGlvbiBpcyBJbnRlcmFjdGl2ZVByb21wdE9wdGlvbiA9PiAhIW9wdGlvbik7XG5cbiAgY29uc3Qgc3VibWl0TWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbnMpIHtcbiAgICBzdWJtaXRNYXBbb3B0aW9uLm51bWJlcl0gPSBvcHRpb24ubnVtYmVyO1xuICB9XG5cbiAgY29uc3QgZmlyc3RPcHRpb25JbmRleCA9IG9wdGlvbkJsb2NrWzBdPy5pbmRleCA/PyAtMTtcbiAgY29uc3QgcHJvbXB0TGluZXMgPSBleHRyYWN0UHJvbXB0QmxvY2sobGluZXMsIGZpcnN0T3B0aW9uSW5kZXggLSAxKTtcbiAgY29uc3QgcHJvbXB0VGV4dCA9IHByb21wdExpbmVzLmxlbmd0aCA+IDAgPyBwcm9tcHRMaW5lcy5qb2luKCdcXG4nKSA6ICdTZWxlY3QgYW4gb3B0aW9uJztcblxuICByZXR1cm4ge1xuICAgIGtpbmQ6ICdudW1iZXJlZCcsXG4gICAgcHJvbXB0VGV4dCxcbiAgICBvcHRpb25zLFxuICAgIHN1Ym1pdE1hcCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmluZExhc3RNYXRjaGluZ0xpbmVJbmRleChsaW5lczogc3RyaW5nW10sIHByZWRpY2F0ZTogKGxpbmU6IHN0cmluZykgPT4gYm9vbGVhbik6IG51bWJlciB7XG4gIGZvciAobGV0IGluZGV4ID0gbGluZXMubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXggLT0gMSkge1xuICAgIGlmIChwcmVkaWNhdGUobGluZXNbaW5kZXhdKSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlT3B0aW9uTGluZShsaW5lOiBzdHJpbmcpOiBJbnRlcmFjdGl2ZVByb21wdE9wdGlvbiB8IG51bGwge1xuICBjb25zdCBtYXRjaCA9IGxpbmUubWF0Y2goL14oPzpbPuKAuuKdr+KWuOKWtuKenOKepCril49dXFxzKik/KFxcZCspXFwuXFxzKyguKikkLyk7XG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4ge1xuICAgIG51bWJlcjogbWF0Y2hbMV0sXG4gICAgdGV4dDogbWF0Y2hbMl0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGZpbmRUcmFpbGluZ09wdGlvbkJsb2NrKGxpbmVzOiBzdHJpbmdbXSk6IEFycmF5PHsgaW5kZXg6IG51bWJlcjsgbGluZTogc3RyaW5nIH0+IHtcbiAgY29uc3QgbWF0Y2hlcyA9IGxpbmVzXG4gICAgLm1hcCgobGluZSwgaW5kZXgpID0+ICh7IGluZGV4LCBsaW5lLCBwYXJzZWQ6IHBhcnNlT3B0aW9uTGluZShsaW5lKSB9KSlcbiAgICAuZmlsdGVyKChlbnRyeSkgPT4gISFlbnRyeS5wYXJzZWQpO1xuXG4gIGlmIChtYXRjaGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IGJsb2NrOiBBcnJheTx7IGluZGV4OiBudW1iZXI7IGxpbmU6IHN0cmluZyB9PiA9IFttYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV1dO1xuXG4gIGZvciAobGV0IGluZGV4ID0gbWF0Y2hlcy5sZW5ndGggLSAyOyBpbmRleCA+PSAwOyBpbmRleCAtPSAxKSB7XG4gICAgY29uc3QgY3VycmVudCA9IG1hdGNoZXNbaW5kZXhdO1xuICAgIGNvbnN0IG5leHQgPSBibG9ja1swXTtcbiAgICBpZiAoY3VycmVudC5pbmRleCAhPT0gbmV4dC5pbmRleCAtIDEpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBibG9jay51bnNoaWZ0KGN1cnJlbnQpO1xuICB9XG5cbiAgcmV0dXJuIGJsb2NrLm1hcCgoeyBpbmRleCwgbGluZSB9KSA9PiAoeyBpbmRleCwgbGluZSB9KSk7XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RQcm9tcHRCbG9jayhsaW5lczogc3RyaW5nW10sIGVuZEluZGV4OiBudW1iZXIpOiBzdHJpbmdbXSB7XG4gIGlmIChlbmRJbmRleCA8IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBsZXQgY3Vyc29yID0gc2tpcEJsYW5rTGluZXNVcChsaW5lcywgZW5kSW5kZXgpO1xuICBpZiAoY3Vyc29yIDwgMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHsgc3RhcnQ6IG1haW5CbG9ja1N0YXJ0LCBlbmQ6IGJsb2NrRW5kIH0gPSBmaW5kTm9uRW1wdHlCbG9ja0VuZGluZ0F0KGxpbmVzLCBjdXJzb3IpO1xuICBjb25zdCBtYWluQmxvY2sgPSBsaW5lcy5zbGljZShtYWluQmxvY2tTdGFydCwgYmxvY2tFbmQgKyAxKS5maWx0ZXIoQm9vbGVhbik7XG5cbiAgaWYgKGlzRGlmZlByZXZpZXdCbG9jayhtYWluQmxvY2spKSB7XG4gICAgY29uc3QgcmVjb3ZlcmVkUHJvbXB0ID0gY29sbGVjdFByb21wdEJsb2Nrc0Fib3ZlKGxpbmVzLCBtYWluQmxvY2tTdGFydCAtIDEpO1xuICAgIHJldHVybiByZWNvdmVyZWRQcm9tcHQubGVuZ3RoID4gMCA/IHJlY292ZXJlZFByb21wdCA6IG1haW5CbG9jaztcbiAgfVxuXG4gIGlmIChtYWluQmxvY2tTdGFydCA8PSAxKSB7XG4gICAgcmV0dXJuIG1haW5CbG9jaztcbiAgfVxuXG4gIGxldCBnYXBDdXJzb3IgPSBtYWluQmxvY2tTdGFydCAtIDE7XG4gIGdhcEN1cnNvciA9IHNraXBCbGFua0xpbmVzVXAobGluZXMsIGdhcEN1cnNvcik7XG5cbiAgaWYgKGdhcEN1cnNvciA8IDAgfHwgZ2FwQ3Vyc29yID09PSBtYWluQmxvY2tTdGFydCAtIDEpIHtcbiAgICByZXR1cm4gbWFpbkJsb2NrO1xuICB9XG5cbiAgY29uc3QgeyBzdGFydDogaGVhZGluZ0Jsb2NrU3RhcnQsIGVuZDogaGVhZGluZ0Jsb2NrRW5kIH0gPSBmaW5kTm9uRW1wdHlCbG9ja0VuZGluZ0F0KGxpbmVzLCBnYXBDdXJzb3IpO1xuICBjb25zdCBoZWFkaW5nQmxvY2sgPSBsaW5lcy5zbGljZShoZWFkaW5nQmxvY2tTdGFydCwgaGVhZGluZ0Jsb2NrRW5kICsgMSkuZmlsdGVyKEJvb2xlYW4pO1xuICBjb25zdCBoZWFkaW5nTWF0Y2hlZCA9IGhlYWRpbmdCbG9jay5zb21lKGlzUHJvbXB0SGVhZGluZ0xpbmUpO1xuXG4gIGlmICghaGVhZGluZ01hdGNoZWQpIHtcbiAgICByZXR1cm4gbWFpbkJsb2NrO1xuICB9XG5cbiAgcmV0dXJuIFsuLi5oZWFkaW5nQmxvY2ssIC4uLm1haW5CbG9ja107XG59XG5cbmZ1bmN0aW9uIGlzUHJvbXB0SGVhZGluZ0xpbmUobGluZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAvXig/OndvdWxkIHlvdSBsaWtlIHRvfGRvIHlvdSB3YW50IHRvfHRoZSBtb2RlbCB3b3VsZCBsaWtlIHRvfGFjdGlvbiByZXF1aXJlZHxjb25maXJtKVxcYi9pLnRlc3QobGluZSk7XG59XG5cbmZ1bmN0aW9uIGlzTGlrZWx5RmlsZVN1bW1hcnlMaW5lKGxpbmU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gL14uK1xcL1teL10rXFxzK1xcKFxcK1xcZCtcXHMrLVxcZCtcXCkkLy50ZXN0KGxpbmUpO1xufVxuXG5mdW5jdGlvbiBza2lwQmxhbmtMaW5lc1VwKGxpbmVzOiBzdHJpbmdbXSwgc3RhcnRJbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgbGV0IGN1cnNvciA9IHN0YXJ0SW5kZXg7XG4gIHdoaWxlIChjdXJzb3IgPj0gMCAmJiAhbGluZXNbY3Vyc29yXSkge1xuICAgIGN1cnNvciAtPSAxO1xuICB9XG4gIHJldHVybiBjdXJzb3I7XG59XG5cbmZ1bmN0aW9uIGZpbmROb25FbXB0eUJsb2NrRW5kaW5nQXQobGluZXM6IHN0cmluZ1tdLCBlbmRJbmRleDogbnVtYmVyKTogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9IHtcbiAgbGV0IGN1cnNvciA9IGVuZEluZGV4O1xuICB3aGlsZSAoY3Vyc29yID49IDAgJiYgbGluZXNbY3Vyc29yXSkge1xuICAgIGN1cnNvciAtPSAxO1xuICB9XG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IGN1cnNvciArIDEsXG4gICAgZW5kOiBlbmRJbmRleCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29sbGVjdFByb21wdEJsb2Nrc0Fib3ZlKGxpbmVzOiBzdHJpbmdbXSwgc3RhcnRJbmRleDogbnVtYmVyKTogc3RyaW5nW10ge1xuICBjb25zdCBibG9ja3M6IHN0cmluZ1tdW10gPSBbXTtcbiAgbGV0IGN1cnNvciA9IHN0YXJ0SW5kZXg7XG5cbiAgd2hpbGUgKGN1cnNvciA+PSAwICYmIGJsb2Nrcy5sZW5ndGggPCAyKSB7XG4gICAgY3Vyc29yID0gc2tpcEJsYW5rTGluZXNVcChsaW5lcywgY3Vyc29yKTtcbiAgICBpZiAoY3Vyc29yIDwgMCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgY29uc3QgeyBzdGFydCwgZW5kIH0gPSBmaW5kTm9uRW1wdHlCbG9ja0VuZGluZ0F0KGxpbmVzLCBjdXJzb3IpO1xuICAgIGNvbnN0IGJsb2NrID0gbGluZXMuc2xpY2Uoc3RhcnQsIGVuZCArIDEpLmZpbHRlcihCb29sZWFuKTtcbiAgICBpZiAoYmxvY2subGVuZ3RoID4gMCkge1xuICAgICAgYmxvY2tzLnVuc2hpZnQoYmxvY2spO1xuICAgIH1cblxuICAgIGN1cnNvciA9IHN0YXJ0IC0gMTtcbiAgfVxuXG4gIGlmIChibG9ja3MubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgaGVhZGluZ0Jsb2NrSW5kZXggPSBibG9ja3MuZmluZEluZGV4KGJsb2NrID0+IGJsb2NrLnNvbWUoaXNQcm9tcHRIZWFkaW5nTGluZSkpO1xuICBpZiAoaGVhZGluZ0Jsb2NrSW5kZXggPj0gMCkge1xuICAgIHJldHVybiBibG9ja3Muc2xpY2UoaGVhZGluZ0Jsb2NrSW5kZXgpLmZsYXQoKTtcbiAgfVxuXG4gIHJldHVybiBibG9ja3NbYmxvY2tzLmxlbmd0aCAtIDFdO1xufVxuXG5mdW5jdGlvbiBpc0RpZmZQcmV2aWV3QmxvY2sobGluZXM6IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gIGlmIChsaW5lcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgbGluZU51bWJlcmVkUm93cyA9IGxpbmVzLmZpbHRlcihpc0xpbmVOdW1iZXJlZERpZmZMaW5lKS5sZW5ndGg7XG4gIHJldHVybiBsaW5lTnVtYmVyZWRSb3dzID49IE1hdGgubWF4KDIsIE1hdGguY2VpbChsaW5lcy5sZW5ndGggLyAyKSk7XG59XG5cbmZ1bmN0aW9uIGlzTGluZU51bWJlcmVkRGlmZkxpbmUobGluZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAvXlxcZCtcXHMvLnRlc3QobGluZSk7XG59XG4iXX0=
@@ -1,2 +0,0 @@
1
- export { resumeOrCreateSession, prepareSessionEncryption } from './session-resume';
2
- export type { ResumeOrCreateSessionInput, ResumeOrCreateSessionResult } from './session-resume';
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.prepareSessionEncryption = exports.resumeOrCreateSession = void 0;
4
- var session_resume_1 = require("./session-resume");
5
- Object.defineProperty(exports, "resumeOrCreateSession", { enumerable: true, get: function () { return session_resume_1.resumeOrCreateSession; } });
6
- Object.defineProperty(exports, "prepareSessionEncryption", { enumerable: true, get: function () { return session_resume_1.prepareSessionEncryption; } });
7
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2Vzc2lvbi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtREFBbUY7QUFBMUUsdUhBQUEscUJBQXFCLE9BQUE7QUFBRSwwSEFBQSx3QkFBd0IsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IHJlc3VtZU9yQ3JlYXRlU2Vzc2lvbiwgcHJlcGFyZVNlc3Npb25FbmNyeXB0aW9uIH0gZnJvbSAnLi9zZXNzaW9uLXJlc3VtZSc7XG5leHBvcnQgdHlwZSB7IFJlc3VtZU9yQ3JlYXRlU2Vzc2lvbklucHV0LCBSZXN1bWVPckNyZWF0ZVNlc3Npb25SZXN1bHQgfSBmcm9tICcuL3Nlc3Npb24tcmVzdW1lJztcbiJdfQ==
@@ -1,55 +0,0 @@
1
- /**
2
- * Centralized session resume/create logic for all CodeVibe plugins.
3
- *
4
- * All three plugins (Claude, Codex, Gemini) need the same pattern:
5
- * 1. Check if session exists in backend (getSession)
6
- * 2. If exists: reactivate + restore E2E session key from encryptedKeys
7
- * 3. If not exists: generate encryption keys + create session
8
- *
9
- * This module eliminates the duplication across plugins.
10
- */
11
- import { AppSyncClient } from '../appsync';
12
- import { Logger } from '../logger';
13
- import { AgentType, EncryptedSessionKey } from '../types';
14
- export interface ResumeOrCreateSessionInput {
15
- sessionId: string;
16
- userId: string;
17
- agentType: AgentType;
18
- projectPath: string;
19
- metadata?: Record<string, any>;
20
- }
21
- export interface ResumeOrCreateSessionResult {
22
- /** Whether an existing session was found and reactivated */
23
- resumed: boolean;
24
- /** The E2E session key (for encrypting/decrypting events), or null if no encryption */
25
- sessionKey: string | null;
26
- }
27
- /**
28
- * Prepare E2E encryption for a new session.
29
- *
30
- * Generates a random session key and encrypts it for all registered devices.
31
- * Does NOT cache the session key — callers should cache only after the session
32
- * is successfully created in the backend.
33
- *
34
- * @returns Encryption data or null if no device keys found / error
35
- */
36
- export declare function prepareSessionEncryption(sessionId: string, appSyncClient: AppSyncClient, logger: Logger): Promise<{
37
- sessionKey: string;
38
- encryptedKeys: EncryptedSessionKey[];
39
- } | null>;
40
- /**
41
- * Resume an existing session or create a new one.
42
- *
43
- * Resume path (session exists in backend):
44
- * - Reactivates session (status → ACTIVE)
45
- * - Restores E2E session key from encryptedKeys
46
- *
47
- * Create path (session does not exist):
48
- * - Prepares E2E encryption (generates key, encrypts for all devices)
49
- * - Encrypts projectPath and metadata
50
- * - Creates session in backend
51
- * - Caches session key only after successful creation
52
- *
53
- * @throws Propagates createSession errors (e.g., SESSION_LIMIT_EXCEEDED)
54
- */
55
- export declare function resumeOrCreateSession(input: ResumeOrCreateSessionInput, appSyncClient: AppSyncClient, logger: Logger): Promise<ResumeOrCreateSessionResult>;
@@ -1,151 +0,0 @@
1
- "use strict";
2
- /**
3
- * Centralized session resume/create logic for all CodeVibe plugins.
4
- *
5
- * All three plugins (Claude, Codex, Gemini) need the same pattern:
6
- * 1. Check if session exists in backend (getSession)
7
- * 2. If exists: reactivate + restore E2E session key from encryptedKeys
8
- * 3. If not exists: generate encryption keys + create session
9
- *
10
- * This module eliminates the duplication across plugins.
11
- */
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.prepareSessionEncryption = prepareSessionEncryption;
14
- exports.resumeOrCreateSession = resumeOrCreateSession;
15
- const crypto_1 = require("../crypto");
16
- const keychain_1 = require("../keychain");
17
- const types_1 = require("../types");
18
- /**
19
- * Prepare E2E encryption for a new session.
20
- *
21
- * Generates a random session key and encrypts it for all registered devices.
22
- * Does NOT cache the session key — callers should cache only after the session
23
- * is successfully created in the backend.
24
- *
25
- * @returns Encryption data or null if no device keys found / error
26
- */
27
- async function prepareSessionEncryption(sessionId, appSyncClient, logger) {
28
- try {
29
- const deviceKeys = await appSyncClient.listUserDeviceKeys();
30
- if (deviceKeys.length === 0) {
31
- logger.info('No device keys found, session will not be encrypted');
32
- return null;
33
- }
34
- logger.info('Preparing session encryption', {
35
- sessionId,
36
- deviceCount: deviceKeys.length,
37
- });
38
- const { sessionKey, encryptedKeys } = keychain_1.keychainManager.createSessionKey(deviceKeys);
39
- logger.info('Session encryption prepared', {
40
- sessionId,
41
- deviceCount: encryptedKeys.length,
42
- });
43
- return { sessionKey, encryptedKeys };
44
- }
45
- catch (error) {
46
- logger.warn('Failed to prepare session encryption:', error);
47
- return null;
48
- }
49
- }
50
- /**
51
- * Resume an existing session or create a new one.
52
- *
53
- * Resume path (session exists in backend):
54
- * - Reactivates session (status → ACTIVE)
55
- * - Restores E2E session key from encryptedKeys
56
- *
57
- * Create path (session does not exist):
58
- * - Prepares E2E encryption (generates key, encrypts for all devices)
59
- * - Encrypts projectPath and metadata
60
- * - Creates session in backend
61
- * - Caches session key only after successful creation
62
- *
63
- * @throws Propagates createSession errors (e.g., SESSION_LIMIT_EXCEEDED)
64
- */
65
- async function resumeOrCreateSession(input, appSyncClient, logger) {
66
- const { sessionId, userId, agentType, projectPath, metadata } = input;
67
- // Check if session already exists in backend
68
- let existingSession = null;
69
- try {
70
- existingSession = await appSyncClient.getSession(sessionId);
71
- }
72
- catch (error) {
73
- logger.warn('Failed to get session (will attempt to create new)', { sessionId, error });
74
- }
75
- if (existingSession) {
76
- // RESUME PATH: reactivate existing session and restore session key
77
- logger.info('Session exists in backend - reactivating', {
78
- sessionId,
79
- previousStatus: existingSession.status,
80
- });
81
- try {
82
- await appSyncClient.updateSession({
83
- sessionId,
84
- status: types_1.SessionStatus.ACTIVE,
85
- });
86
- }
87
- catch (error) {
88
- logger.warn('Failed to reactivate existing session, will continue', { sessionId, error });
89
- }
90
- // Restore session key from encryptedKeys
91
- let sessionKey = null;
92
- const encryptedKeys = existingSession.encryptedKeys;
93
- if (existingSession.isEncrypted && encryptedKeys?.length) {
94
- try {
95
- const cachedKey = await keychain_1.keychainManager.getSessionKey(sessionId, encryptedKeys);
96
- if (cachedKey) {
97
- sessionKey = cachedKey;
98
- keychain_1.keychainManager.cacheSessionKey(sessionId, cachedKey);
99
- logger.info('Session key retrieved for resumed session', { sessionId });
100
- }
101
- else {
102
- logger.warn('No encrypted key for this device; proceeding without decryption', { sessionId });
103
- }
104
- }
105
- catch (error) {
106
- logger.warn('Failed to retrieve session key for resumed session', { sessionId, error });
107
- }
108
- }
109
- return { resumed: true, sessionKey };
110
- }
111
- // NEW SESSION PATH: prepare encryption and create
112
- const encryptionData = await prepareSessionEncryption(sessionId, appSyncClient, logger);
113
- let sessionProjectPath = projectPath;
114
- let sessionMetadata = metadata;
115
- if (encryptionData) {
116
- sessionProjectPath = crypto_1.cryptoService.encryptContent(projectPath, encryptionData.sessionKey);
117
- if (sessionMetadata && Object.keys(sessionMetadata).length > 0) {
118
- const encryptedMeta = crypto_1.cryptoService.encryptMetadata(sessionMetadata, encryptionData.sessionKey);
119
- sessionMetadata = { encrypted: encryptedMeta };
120
- }
121
- logger.info('Session data encrypted', { sessionId });
122
- }
123
- logger.info('Creating new session in backend', {
124
- sessionId,
125
- userId,
126
- agentType,
127
- isEncrypted: !!encryptionData,
128
- });
129
- // createSession errors propagate to caller (e.g., SESSION_LIMIT_EXCEEDED)
130
- await appSyncClient.createSession({
131
- sessionId,
132
- userId,
133
- agentType,
134
- projectPath: sessionProjectPath,
135
- status: types_1.SessionStatus.ACTIVE,
136
- metadata: sessionMetadata,
137
- // E2E encryption fields
138
- isEncrypted: encryptionData ? true : undefined,
139
- creatorDeviceId: encryptionData ? await keychain_1.keychainManager.getDeviceId() : undefined,
140
- encryptionVersion: encryptionData ? 1 : undefined,
141
- encryptedKeys: encryptionData?.encryptedKeys,
142
- });
143
- const sessionKey = encryptionData?.sessionKey || null;
144
- // Cache session key AFTER successful creation (avoids premature caching bug)
145
- if (encryptionData) {
146
- keychain_1.keychainManager.cacheSessionKey(sessionId, encryptionData.sessionKey);
147
- }
148
- logger.info('Session created', { sessionId, userId, isEncrypted: !!encryptionData });
149
- return { resumed: false, sessionKey };
150
- }
151
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi1yZXN1bWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2Vzc2lvbi9zZXNzaW9uLXJlc3VtZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7OztHQVNHOztBQW9DSCw0REE4QkM7QUFpQkQsc0RBbUdDO0FBbkxELHNDQUEwQztBQUMxQywwQ0FBOEM7QUFFOUMsb0NBSWtCO0FBaUJsQjs7Ozs7Ozs7R0FRRztBQUNJLEtBQUssVUFBVSx3QkFBd0IsQ0FDNUMsU0FBaUIsRUFDakIsYUFBNEIsRUFDNUIsTUFBYztJQUVkLElBQUksQ0FBQztRQUNILE1BQU0sVUFBVSxHQUFHLE1BQU0sYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFFNUQsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMscURBQXFELENBQUMsQ0FBQztZQUNuRSxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLDhCQUE4QixFQUFFO1lBQzFDLFNBQVM7WUFDVCxXQUFXLEVBQUUsVUFBVSxDQUFDLE1BQU07U0FDL0IsQ0FBQyxDQUFDO1FBRUgsTUFBTSxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsR0FBRywwQkFBZSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRW5GLE1BQU0sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLEVBQUU7WUFDekMsU0FBUztZQUNULFdBQVcsRUFBRSxhQUFhLENBQUMsTUFBTTtTQUNsQyxDQUFDLENBQUM7UUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxDQUFDO0lBQ3ZDLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsTUFBTSxDQUFDLElBQUksQ0FBQyx1Q0FBdUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM1RCxPQUFPLElBQUksQ0FBQztJQUNkLENB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QUMsaUJBQWlCLEVBQUUsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztJQUVyRixPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztBQUN4QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDZW50cmFsaXplZCBzZXNzaW9uIHJlc3VtZS9jcmVhdGUgbG9naWMgZm9yIGFsbCBDb2RlVmliZSBwbHVnaW5zLlxuICpcbiAqIEFsbCB0aHJlZSBwbHVnaW5zIChDbGF1ZGUsIENvZGV4LCBHZW1pbmkpIG5lZWQgdGhlIHNhbWUgcGF0dGVybjpcbiAqIDEuIENoZWNrIGlmIHNlc3Npb24gZXhpc3RzIGluIGJhY2tlbmQgKGdldFNlc3Npb24pXG4gKiAyLiBJZiBleGlzdHM6IHJlYWN0aXZhdGUgKyByZXN0b3JlIEUyRSBzZXNzaW9uIGtleSBmcm9tIGVuY3J5cHRlZEtleXNcbiAqIDMuIElmIG5vdCBleGlzdHM6IGdlbmVyYXRlIGVuY3J5cHRpb24ga2V5cyArIGNyZWF0ZSBzZXNzaW9uXG4gKlxuICogVGhpcyBtb2R1bGUgZWxpbWluYXRlcyB0aGUgZHVwbGljYXRpb24gYWNyb3NzIHBsdWdpbnMuXG4gKi9cblxuaW1wb3J0IHsgQXBwU3luY0NsaWVudCB9IGZyb20gJy4uL2FwcHN5bmMnO1xuaW1wb3J0IHsgY3J5cHRvU2VydmljZSB9IGZyb20gJy4uL2NyeXB0byc7XG5pbXBvcnQgeyBrZXljaGFpbk1hbmFnZXIgfSBmcm9tICcuLi9rZXljaGFpbic7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IHtcbiAgQWdlbnRUeXBlLFxuICBTZXNzaW9uU3RhdHVzLFxuICBFbmNyeXB0ZWRTZXNzaW9uS2V5LFxufSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdW1lT3JDcmVhdGVTZXNzaW9uSW5wdXQge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgdXNlcklkOiBzdHJpbmc7XG4gIGFnZW50VHlwZTogQWdlbnRUeXBlO1xuICBwcm9qZWN0UGF0aDogc3RyaW5nO1xuICBtZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIGFueT47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdW1lT3JDcmVhdGVTZXNzaW9uUmVzdWx0IHtcbiAgLyoqIFdoZXRoZXIgYW4gZXhpc3Rpbmcgc2Vzc2lvbiB3YXMgZm91bmQgYW5kIHJlYWN0aXZhdGVkICovXG4gIHJlc3VtZWQ6IGJvb2xlYW47XG4gIC8qKiBUaGUgRTJFIHNlc3Npb24ga2V5IChmb3IgZW5jcnlwdGluZy9kZWNyeXB0aW5nIGV2ZW50cyksIG9yIG51bGwgaWYgbm8gZW5jcnlwdGlvbiAqL1xuICBzZXNzaW9uS2V5OiBzdHJpbmcgfCBudWxsO1xufVxuXG4vKipcbiAqIFByZXBhcmUgRTJFIGVuY3J5cHRpb24gZm9yIGEgbmV3IHNlc3Npb24uXG4gKlxuICogR2VuZXJhdGVzIGEgcmFuZG9tIHNlc3Npb24ga2V5IGFuZCBlbmNyeXB0cyBpdCBmb3IgYWxsIHJlZ2lzdGVyZWQgZGV2aWNlcy5cbiAqIERvZXMgTk9UIGNhY2hlIHRoZSBzZXNzaW9uIGtleSDigJQgY2FsbGVycyBzaG91bGQgY2FjaGUgb25seSBhZnRlciB0aGUgc2Vzc2lvblxuICogaXMgc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgaW4gdGhlIGJhY2tlbmQuXG4gKlxuICogQHJldHVybnMgRW5jcnlwdGlvbiBkYXRhIG9yIG51bGwgaWYgbm8gZGV2aWNlIGtleXMgZm91bmQgLyBlcnJvclxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJlcGFyZVNlc3Npb25FbmNyeXB0aW9uKFxuICBzZXNzaW9uSWQ6IHN0cmluZyxcbiAgYXBwU3luY0NsaWVudDogQXBwU3luY0NsaWVudCxcbiAgbG9nZ2VyOiBMb2dnZXIsXG4pOiBQcm9taXNlPHsgc2Vzc2lvbktleTogc3RyaW5nOyBlbmNyeXB0ZWRLZXlzOiBFbmNyeXB0ZWRTZXNzaW9uS2V5W10gfSB8IG51bGw+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBkZXZpY2VLZXlzID0gYXdhaXQgYXBwU3luY0NsaWVudC5saXN0VXNlckRldmljZUtleXMoKTtcblxuICAgIGlmIChkZXZpY2VLZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgbG9nZ2VyLmluZm8oJ05vIGRldmljZSBrZXlzIGZvdW5kLCBzZXNzaW9uIHdpbGwgbm90IGJlIGVuY3J5cHRlZCcpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbG9nZ2VyLmluZm8oJ1ByZXBhcmluZyBzZXNzaW9uIGVuY3J5cHRpb24nLCB7XG4gICAgICBzZXNzaW9uSWQsXG4gICAgICBkZXZpY2VDb3VudDogZGV2aWNlS2V5cy5sZW5ndGgsXG4gICAgfSk7XG5cbiAgICBjb25zdCB7IHNlc3Npb25LZXksIGVuY3J5cHRlZEtleXMgfSA9IGtleWNoYWluTWFuYWdlci5jcmVhdGVTZXNzaW9uS2V5KGRldmljZUtleXMpO1xuXG4gICAgbG9nZ2VyLmluZm8oJ1Nlc3Npb24gZW5jcnlwdGlvbiBwcmVwYXJlZCcsIHtcbiAgICAgIHNlc3Npb25JZCxcbiAgICAgIGRldmljZUNvdW50OiBlbmNyeXB0ZWRLZXlzLmxlbmd0aCxcbiAgICB9KTtcblxuICAgIHJldHVybiB7IHNlc3Npb25LZXksIGVuY3J5cHRlZEtleXMgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIHByZXBhcmUgc2Vzc2lvbiBlbmNyeXB0aW9uOicsIGVycm9yKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vKipcbiAqIFJlc3VtZSBhbiBleGlzdGluZyBzZXNzaW9uIG9yIGNyZWF0ZSBhIG5ldyBvbmUuXG4gKlxuICogUmVzdW1lIHBhdGggKHNlc3Npb24gZXhpc3RzIGluIGJhY2tlbmQpOlxuICogICAtIFJlYWN0aXZhdGVzIHNlc3Npb24gKHN0YXR1cyDihpIgQUNUSVZFKVxuICogICAtIFJlc3RvcmVzIEUyRSBzZXNzaW9uIGtleSBmcm9tIGVuY3J5cHRlZEtleXNcbiAqXG4gKiBDcmVhdGUgcGF0aCAoc2Vzc2lvbiBkb2VzIG5vdCBleGlzdCk6XG4gKiAgIC0gUHJlcGFyZXMgRTJFIGVuY3J5cHRpb24gKGdlbmVyYXRlcyBrZXksIGVuY3J5cHRzIGZvciBhbGwgZGV2aWNlcylcbiAqICAgLSBFbmNyeXB0cyBwcm9qZWN0UGF0aCBhbmQgbWV0YWRhdGFcbiAqICAgLSBDcmVhdGVzIHNlc3Npb24gaW4gYmFja2VuZFxuICogICAtIENhY2hlcyBzZXNzaW9uIGtleSBvbmx5IGFmdGVyIHN1Y2Nlc3NmdWwgY3JlYXRpb25cbiAqXG4gKiBAdGhyb3dzIFByb3BhZ2F0ZXMgY3JlYXRlU2Vzc2lvbiBlcnJvcnMgKGUuZy4sIFNFU1NJT05fTElNSVRfRVhDRUVERUQpXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXN1bWVPckNyZWF0ZVNlc3Npb24oXG4gIGlucHV0OiBSZXN1bWVPckNyZWF0ZVNlc3Npb25JbnB1dCxcbiAgYXBwU3luY0NsaWVudDogQXBwU3luY0NsaWVudCxcbiAgbG9nZ2VyOiBMb2dnZXIsXG4pOiBQcm9taXNlPFJlc3VtZU9yQ3JlYXRlU2Vzc2lvblJlc3VsdD4ge1xuICBjb25zdCB7IHNlc3Npb25JZCwgdXNlcklkLCBhZ2VudFR5cGUsIHByb2plY3RQYXRoLCBtZXRhZGF0YSB9ID0gaW5wdXQ7XG5cbiAgLy8gQ2hlY2sgaWYgc2Vzc2lvbiBhbHJlYWR5IGV4aXN0cyBpbiBiYWNrZW5kXG4gIGxldCBleGlzdGluZ1Nlc3Npb24gPSBudWxsO1xuICB0cnkge1xuICAgIGV4aXN0aW5nU2Vzc2lvbiA9IGF3YWl0IGFwcFN5bmNDbGllbnQuZ2V0U2Vzc2lvbihzZXNzaW9uSWQpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gZ2V0IHNlc3Npb24gKHdpbGwgYXR0ZW1wdCB0byBjcmVhdGUgbmV3KScsIHsgc2Vzc2lvbklkLCBlcnJvciB9KTtcbiAgfVxuXG4gIGlmIChleGlzdGluZ1Nlc3Npb24pIHtcbiAgICAvLyBSRVNVTUUgUEFUSDogcmVhY3RpdmF0ZSBleGlzdGluZyBzZXNzaW9uIGFuZCByZXN0b3JlIHNlc3Npb24ga2V5XG4gICAgbG9nZ2VyLmluZm8oJ1Nlc3Npb24gZXhpc3RzIGluIGJhY2tlbmQgLSByZWFjdGl2YXRpbmcnLCB7XG4gICAgICBzZXNzaW9uSWQsXG4gICAgICBwcmV2aW91c1N0YXR1czogZXhpc3RpbmdTZXNzaW9uLnN0YXR1cyxcbiAgICB9KTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBhcHBTeW5jQ2xpZW50LnVwZGF0ZVNlc3Npb24oe1xuICAgICAgICBzZXNzaW9uSWQsXG4gICAgICAgIHN0YXR1czogU2Vzc2lvblN0YXR1cy5BQ1RJVkUsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byByZWFjdGl2YXRlIGV4aXN0aW5nIHNlc3Npb24sIHdpbGwgY29udGludWUnLCB7IHNlc3Npb25JZCwgZXJyb3IgfSk7XG4gICAgfVxuXG4gICAgLy8gUmVzdG9yZSBzZXNzaW9uIGtleSBmcm9tIGVuY3J5cHRlZEtleXNcbiAgICBsZXQgc2Vzc2lvbktleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3QgZW5jcnlwdGVkS2V5cyA9IGV4aXN0aW5nU2Vzc2lvbi5lbmNyeXB0ZWRLZXlzO1xuICAgIGlmIChleGlzdGluZ1Nlc3Npb24uaXNFbmNyeXB0ZWQgJiYgZW5jcnlwdGVkS2V5cz8ubGVuZ3RoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjYWNoZWRLZXkgPSBhd2FpdCBrZXljaGFpbk1hbmFnZXIuZ2V0U2Vzc2lvbktleShzZXNzaW9uSWQsIGVuY3J5cHRlZEtleXMpO1xuICAgICAgICBpZiAoY2FjaGVkS2V5KSB7XG4gICAgICAgICAgc2Vzc2lvbktleSA9IGNhY2hlZEtleTtcbiAgICAgICAgICBrZXljaGFpbk1hbmFnZXIuY2FjaGVTZXNzaW9uS2V5KHNlc3Npb25JZCwgY2FjaGVkS2V5KTtcbiAgICAgICAgICBsb2dnZXIuaW5mbygnU2Vzc2lvbiBrZXkgcmV0cmlldmVkIGZvciByZXN1bWVkIHNlc3Npb24nLCB7IHNlc3Npb25JZCB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsb2dnZXIud2FybignTm8gZW5jcnlwdGVkIGtleSBmb3IgdGhpcyBkZXZpY2U7IHByb2NlZWRpbmcgd2l0aG91dCBkZWNyeXB0aW9uJywgeyBzZXNzaW9uSWQgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gcmV0cmlldmUgc2Vzc2lvbiBrZXkgZm9yIHJlc3VtZWQgc2Vzc2lvbicsIHsgc2Vzc2lvbklkLCBlcnJvciB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyByZXN1bWVkOiB0cnVlLCBzZXNzaW9uS2V5IH07XG4gIH1cblxuICAvLyBORVcgU0VTU0lPTiBQQVRIOiBwcmVwYXJlIGVuY3J5cHRpb24gYW5kIGNyZWF0ZVxuICBjb25zdCBlbmNyeXB0aW9uRGF0YSA9IGF3YWl0IHByZXBhcmVTZXNzaW9uRW5jcnlwdGlvbihzZXNzaW9uSWQsIGFwcFN5bmNDbGllbnQsIGxvZ2dlcik7XG5cbiAgbGV0IHNlc3Npb25Qcm9qZWN0UGF0aCA9IHByb2plY3RQYXRoO1xuICBsZXQgc2Vzc2lvbk1ldGFkYXRhID0gbWV0YWRhdGE7XG5cbiAgaWYgKGVuY3J5cHRpb25EYXRhKSB7XG4gICAgc2Vzc2lvblByb2plY3RQYXRoID0gY3J5cHRvU2VydmljZS5lbmNyeXB0Q29udGVudChwcm9qZWN0UGF0aCwgZW5jcnlwdGlvbkRhdGEuc2Vzc2lvbktleSk7XG4gICAgaWYgKHNlc3Npb25NZXRhZGF0YSAmJiBPYmplY3Qua2V5cyhzZXNzaW9uTWV0YWRhdGEpLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGVuY3J5cHRlZE1ldGEgPSBjcnlwdG9TZXJ2aWNlLmVuY3J5cHRNZXRhZGF0YShzZXNzaW9uTWV0YWRhdGEsIGVuY3J5cHRpb25EYXRhLnNlc3Npb25LZXkpO1xuICAgICAgc2Vzc2lvbk1ldGFkYXRhID0geyBlbmNyeXB0ZWQ6IGVuY3J5cHRlZE1ldGEgfTtcbiAgICB9XG4gICAgbG9nZ2VyLmluZm8oJ1Nlc3Npb24gZGF0YSBlbmNyeXB0ZWQnLCB7IHNlc3Npb25JZCB9KTtcbiAgfVxuXG4gIGxvZ2dlci5pbmZvKCdDcmVhdGluZyBuZXcgc2Vzc2lvbiBpbiBiYWNrZW5kJywge1xuICAgIHNlc3Npb25JZCxcbiAgICB1c2VySWQsXG4gICAgYWdlbnRUeXBlLFxuICAgIGlzRW5jcnlwdGVkOiAhIWVuY3J5cHRpb25EYXRhLFxuICB9KTtcblxuICAvLyBjcmVhdGVTZXNzaW9uIGVycm9ycyBwcm9wYWdhdGUgdG8gY2FsbGVyIChlLmcuLCBTRVNTSU9OX0xJTUlUX0VYQ0VFREVEKVxuICBhd2FpdCBhcHBTeW5jQ2xpZW50LmNyZWF0ZVNlc3Npb24oe1xuICAgIHNlc3Npb25JZCxcbiAgICB1c2VySWQsXG4gICAgYWdlbnRUeXBlLFxuICAgIHByb2plY3RQYXRoOiBzZXNzaW9uUHJvamVjdFBhdGgsXG4gICAgc3RhdHVzOiBTZXNzaW9uU3RhdHVzLkFDVElWRSxcbiAgICBtZXRhZGF0YTogc2Vzc2lvbk1ldGFkYXRhLFxuICAgIC8vIEUyRSBlbmNyeXB0aW9uIGZpZWxkc1xuICAgIGlzRW5jcnlwdGVkOiBlbmNyeXB0aW9uRGF0YSA/IHRydWUgOiB1bmRlZmluZWQsXG4gICAgY3JlYXRvckRldmljZUlkOiBlbmNyeXB0aW9uRGF0YSA/IGF3YWl0IGtleWNoYWluTWFuYWdlci5nZXREZXZpY2VJZCgpIDogdW5kZWZpbmVkLFxuICAgIGVuY3J5cHRpb25WZXJzaW9uOiBlbmNyeXB0aW9uRGF0YSA/IDEgOiB1bmRlZmluZWQsXG4gICAgZW5jcnlwdGVkS2V5czogZW5jcnlwdGlvbkRhdGE/LmVuY3J5cHRlZEtleXMsXG4gIH0pO1xuXG4gIGNvbnN0IHNlc3Npb25LZXkgPSBlbmNyeXB0aW9uRGF0YT8uc2Vzc2lvbktleSB8fCBudWxsO1xuXG4gIC8vIENhY2hlIHNlc3Npb24ga2V5IEFGVEVSIHN1Y2Nlc3NmdWwgY3JlYXRpb24gKGF2b2lkcyBwcmVtYXR1cmUgY2FjaGluZyBidWcpXG4gIGlmIChlbmNyeXB0aW9uRGF0YSkge1xuICAgIGtleWNoYWluTWFuYWdlci5jYWNoZVNlc3Npb25LZXkoc2Vzc2lvbklkLCBlbmNyeXB0aW9uRGF0YS5zZXNzaW9uS2V5KTtcbiAgfVxuXG4gIGxvZ2dlci5pbmZvKCdTZXNzaW9uIGNyZWF0ZWQnLCB7IHNlc3Npb25JZCwgdXNlcklkLCBpc0VuY3J5cHRlZDogISFlbmNyeXB0aW9uRGF0YSB9KTtcblxuICByZXR1cm4geyByZXN1bWVkOiBmYWxzZSwgc2Vzc2lvbktleSB9O1xufVxuIl19
@@ -1,15 +0,0 @@
1
- /**
2
- * Stored OAuth tokens
3
- */
4
- export interface TokenData {
5
- accessToken: string;
6
- idToken: string;
7
- refreshToken: string;
8
- expiresAt: number;
9
- userId: string;
10
- email: string;
11
- }
12
- /**
13
- * Environment configuration
14
- */
15
- export type Environment = 'development' | 'production';
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy9hdXRoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFN0b3JlZCBPQXV0aCB0b2tlbnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUb2tlbkRhdGEge1xuICBhY2Nlc3NUb2tlbjogc3RyaW5nO1xuICBpZFRva2VuOiBzdHJpbmc7XG4gIHJlZnJlc2hUb2tlbjogc3RyaW5nO1xuICBleHBpcmVzQXQ6IG51bWJlcjtcbiAgdXNlcklkOiBzdHJpbmc7XG4gIGVtYWlsOiBzdHJpbmc7XG59XG5cbi8qKlxuICogRW52aXJvbm1lbnQgY29uZmlndXJhdGlvblxuICovXG5leHBvcnQgdHlwZSBFbnZpcm9ubWVudCA9ICdkZXZlbG9wbWVudCcgfCAncHJvZHVjdGlvbic7XG4iXX0=
@@ -1,54 +0,0 @@
1
- /**
2
- * Encrypted session key for E2E encryption
3
- */
4
- export interface EncryptedSessionKey {
5
- deviceId: string;
6
- encryptedKey: string;
7
- ephemeralPublicKey: string;
8
- }
9
- /**
10
- * Device key stored with backend
11
- */
12
- export interface DeviceKey {
13
- userId: string;
14
- deviceId: string;
15
- publicKey: string;
16
- platform: string;
17
- deviceName?: string;
18
- createdAt: string;
19
- lastUsedAt?: string;
20
- }
21
- /**
22
- * Key pair for ECDH
23
- */
24
- export interface KeyPair {
25
- privateKey: string;
26
- publicKey: string;
27
- }
28
- /**
29
- * Device identity stored in keychain
30
- */
31
- export interface DeviceIdentity {
32
- deviceId: string;
33
- privateKey: string;
34
- publicKey: string;
35
- createdAt: string;
36
- }
37
- /**
38
- * GraphQL input for registering device key
39
- */
40
- export interface RegisterDeviceKeyInput {
41
- deviceId: string;
42
- publicKey: string;
43
- platform: string;
44
- deviceName?: string;
45
- }
46
- /**
47
- * GraphQL input for granting session key
48
- */
49
- export interface GrantSessionKeyInput {
50
- sessionId: string;
51
- deviceId: string;
52
- encryptedKey: string;
53
- ephemeralPublicKey: string;
54
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jcnlwdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy9lbmNyeXB0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEVuY3J5cHRlZCBzZXNzaW9uIGtleSBmb3IgRTJFIGVuY3J5cHRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbmNyeXB0ZWRTZXNzaW9uS2V5IHtcbiAgZGV2aWNlSWQ6IHN0cmluZztcbiAgZW5jcnlwdGVkS2V5OiBzdHJpbmc7XG4gIGVwaGVtZXJhbFB1YmxpY0tleTogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldmljZSBrZXkgc3RvcmVkIHdpdGggYmFja2VuZFxuICovXG5leHBvcnQgaW50ZXJmYWNlIERldmljZUtleSB7XG4gIHVzZXJJZDogc3RyaW5nO1xuICBkZXZpY2VJZDogc3RyaW5nO1xuICBwdWJsaWNLZXk6IHN0cmluZztcbiAgcGxhdGZvcm06IHN0cmluZztcbiAgZGV2aWNlTmFtZT86IHN0cmluZztcbiAgY3JlYXRlZEF0OiBzdHJpbmc7XG4gIGxhc3RVc2VkQXQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogS2V5IHBhaXIgZm9yIEVDREhcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBLZXlQYWlyIHtcbiAgcHJpdmF0ZUtleTogc3RyaW5nO1xuICBwdWJsaWNLZXk6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXZpY2UgaWRlbnRpdHkgc3RvcmVkIGluIGtleWNoYWluXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGV2aWNlSWRlbnRpdHkge1xuICBkZXZpY2VJZDogc3RyaW5nO1xuICBwcml2YXRlS2V5OiBzdHJpbmc7XG4gIHB1YmxpY0tleTogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBHcmFwaFFMIGlucHV0IGZvciByZWdpc3RlcmluZyBkZXZpY2Uga2V5XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVnaXN0ZXJEZXZpY2VLZXlJbnB1dCB7XG4gIGRldmljZUlkOiBzdHJpbmc7XG4gIHB1YmxpY0tleTogc3RyaW5nO1xuICBwbGF0Zm9ybTogc3RyaW5nO1xuICBkZXZpY2VOYW1lPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEdyYXBoUUwgaW5wdXQgZm9yIGdyYW50aW5nIHNlc3Npb24ga2V5XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR3JhbnRTZXNzaW9uS2V5SW5wdXQge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgZGV2aWNlSWQ6IHN0cmluZztcbiAgZW5jcnlwdGVkS2V5OiBzdHJpbmc7XG4gIGVwaGVtZXJhbFB1YmxpY0tleTogc3RyaW5nO1xufVxuIl19