@quantiya/codevibe-codex-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +29 -0
- package/README.md +155 -0
- package/bin/codevibe-codex +187 -0
- package/dist/approval-detector.d.ts +38 -0
- package/dist/approval-detector.d.ts.map +1 -0
- package/dist/approval-detector.js +174 -0
- package/dist/approval-detector.js.map +1 -0
- package/dist/appsync-client.d.ts +69 -0
- package/dist/appsync-client.d.ts.map +1 -0
- package/dist/appsync-client.js +937 -0
- package/dist/appsync-client.js.map +1 -0
- package/dist/auth-cli.d.ts +11 -0
- package/dist/auth-cli.d.ts.map +1 -0
- package/dist/auth-cli.js +241 -0
- package/dist/auth-cli.js.map +1 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +116 -0
- package/dist/config.js.map +1 -0
- package/dist/crypto-service.d.ts +115 -0
- package/dist/crypto-service.d.ts.map +1 -0
- package/dist/crypto-service.js +278 -0
- package/dist/crypto-service.js.map +1 -0
- package/dist/event-mapper.d.ts +24 -0
- package/dist/event-mapper.d.ts.map +1 -0
- package/dist/event-mapper.js +268 -0
- package/dist/event-mapper.js.map +1 -0
- package/dist/key-manager.d.ts +87 -0
- package/dist/key-manager.d.ts.map +1 -0
- package/dist/key-manager.js +287 -0
- package/dist/key-manager.js.map +1 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +18 -0
- package/dist/logger.js.map +1 -0
- package/dist/prompt-parser.d.ts +3 -0
- package/dist/prompt-parser.d.ts.map +1 -0
- package/dist/prompt-parser.js +8 -0
- package/dist/prompt-parser.js.map +1 -0
- package/dist/prompt-responder.d.ts +18 -0
- package/dist/prompt-responder.d.ts.map +1 -0
- package/dist/prompt-responder.js +78 -0
- package/dist/prompt-responder.js.map +1 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1045 -0
- package/dist/server.js.map +1 -0
- package/dist/session-id-cache.d.ts +16 -0
- package/dist/session-id-cache.d.ts.map +1 -0
- package/dist/session-id-cache.js +90 -0
- package/dist/session-id-cache.js.map +1 -0
- package/dist/session-log-watcher.d.ts +61 -0
- package/dist/session-log-watcher.d.ts.map +1 -0
- package/dist/session-log-watcher.js +372 -0
- package/dist/session-log-watcher.js.map +1 -0
- package/dist/tmux-pane-observer.d.ts +39 -0
- package/dist/tmux-pane-observer.d.ts.map +1 -0
- package/dist/tmux-pane-observer.js +255 -0
- package/dist/tmux-pane-observer.js.map +1 -0
- package/dist/token-storage.d.ts +39 -0
- package/dist/token-storage.d.ts.map +1 -0
- package/dist/token-storage.js +169 -0
- package/dist/token-storage.js.map +1 -0
- package/dist/types.d.ts +158 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export interface TmuxPromptCandidate {
|
|
3
|
+
rawDelta: string;
|
|
4
|
+
snapshot: string;
|
|
5
|
+
detectedAt: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Foundation for tmux-based prompt detection.
|
|
9
|
+
*
|
|
10
|
+
* This first pass intentionally keeps the surface area small:
|
|
11
|
+
* - manage the active tmux session name
|
|
12
|
+
* - capture a clean pane snapshot on demand
|
|
13
|
+
* - provide an evented type that server.ts can wire into later
|
|
14
|
+
*
|
|
15
|
+
* Real-time pipe-pane streaming will be added in a follow-up patch.
|
|
16
|
+
*/
|
|
17
|
+
export declare class TmuxPaneObserver extends EventEmitter {
|
|
18
|
+
private sessionName;
|
|
19
|
+
private started;
|
|
20
|
+
private pipeFilePath;
|
|
21
|
+
private filePosition;
|
|
22
|
+
private watcher;
|
|
23
|
+
private processing;
|
|
24
|
+
private pendingRead;
|
|
25
|
+
private lastPromptHash;
|
|
26
|
+
start(sessionName: string): Promise<void>;
|
|
27
|
+
stop(): Promise<void>;
|
|
28
|
+
captureSnapshot(lines?: number): Promise<string>;
|
|
29
|
+
private escapeShellArg;
|
|
30
|
+
private enablePipePane;
|
|
31
|
+
private disablePipePane;
|
|
32
|
+
private startFileWatcher;
|
|
33
|
+
private processFileChanges;
|
|
34
|
+
private readAppendedChunk;
|
|
35
|
+
private looksLikePromptDelta;
|
|
36
|
+
private looksLikePromptSnapshot;
|
|
37
|
+
private hashPromptSnapshot;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=tmux-pane-observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-pane-observer.d.ts","sourceRoot":"","sources":["../src/tmux-pane-observer.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAMtC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAuB;IAEhC,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBzC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAqCrB,eAAe,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB1D,OAAO,CAAC,cAAc;YAIR,cAAc;YAgBd,eAAe;IAU7B,OAAO,CAAC,gBAAgB;YAaV,kBAAkB;IAiDhC,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,kBAAkB;CAQ3B"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.TmuxPaneObserver = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const os = __importStar(require("os"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const crypto_1 = require("crypto");
|
|
41
|
+
const child_process_1 = require("child_process");
|
|
42
|
+
const events_1 = require("events");
|
|
43
|
+
const util_1 = require("util");
|
|
44
|
+
const logger_1 = require("./logger");
|
|
45
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
46
|
+
/**
|
|
47
|
+
* Foundation for tmux-based prompt detection.
|
|
48
|
+
*
|
|
49
|
+
* This first pass intentionally keeps the surface area small:
|
|
50
|
+
* - manage the active tmux session name
|
|
51
|
+
* - capture a clean pane snapshot on demand
|
|
52
|
+
* - provide an evented type that server.ts can wire into later
|
|
53
|
+
*
|
|
54
|
+
* Real-time pipe-pane streaming will be added in a follow-up patch.
|
|
55
|
+
*/
|
|
56
|
+
class TmuxPaneObserver extends events_1.EventEmitter {
|
|
57
|
+
constructor() {
|
|
58
|
+
super(...arguments);
|
|
59
|
+
this.sessionName = null;
|
|
60
|
+
this.started = false;
|
|
61
|
+
this.pipeFilePath = null;
|
|
62
|
+
this.filePosition = 0;
|
|
63
|
+
this.watcher = null;
|
|
64
|
+
this.processing = false;
|
|
65
|
+
this.pendingRead = false;
|
|
66
|
+
this.lastPromptHash = null;
|
|
67
|
+
}
|
|
68
|
+
async start(sessionName) {
|
|
69
|
+
if (this.started && this.sessionName === sessionName) {
|
|
70
|
+
logger_1.logger.debug('Tmux pane observer already started', { sessionName });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (this.started) {
|
|
74
|
+
await this.stop();
|
|
75
|
+
}
|
|
76
|
+
this.sessionName = sessionName;
|
|
77
|
+
this.started = true;
|
|
78
|
+
this.filePosition = 0;
|
|
79
|
+
this.lastPromptHash = null;
|
|
80
|
+
this.pipeFilePath = path.join(os.tmpdir(), `codevibe-codex-pane-${process.pid}.log`);
|
|
81
|
+
fs.mkdirSync(path.dirname(this.pipeFilePath), { recursive: true });
|
|
82
|
+
fs.writeFileSync(this.pipeFilePath, '');
|
|
83
|
+
await this.enablePipePane();
|
|
84
|
+
this.startFileWatcher();
|
|
85
|
+
logger_1.logger.info('Tmux pane observer started', { sessionName });
|
|
86
|
+
}
|
|
87
|
+
async stop() {
|
|
88
|
+
if (!this.started) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
await this.disablePipePane();
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
logger_1.logger.debug('Failed to disable tmux pipe-pane cleanly', { error });
|
|
96
|
+
}
|
|
97
|
+
if (this.watcher) {
|
|
98
|
+
this.watcher.close();
|
|
99
|
+
this.watcher = null;
|
|
100
|
+
}
|
|
101
|
+
if (this.pipeFilePath) {
|
|
102
|
+
try {
|
|
103
|
+
fs.unlinkSync(this.pipeFilePath);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Ignore cleanup failure
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
logger_1.logger.info('Tmux pane observer stopped', { sessionName: this.sessionName });
|
|
110
|
+
this.started = false;
|
|
111
|
+
this.sessionName = null;
|
|
112
|
+
this.pipeFilePath = null;
|
|
113
|
+
this.filePosition = 0;
|
|
114
|
+
this.processing = false;
|
|
115
|
+
this.pendingRead = false;
|
|
116
|
+
this.lastPromptHash = null;
|
|
117
|
+
this.removeAllListeners('prompt-candidate');
|
|
118
|
+
this.removeAllListeners('observer-error');
|
|
119
|
+
}
|
|
120
|
+
async captureSnapshot(lines = 120) {
|
|
121
|
+
if (!this.sessionName) {
|
|
122
|
+
throw new Error('Tmux pane observer is not started');
|
|
123
|
+
}
|
|
124
|
+
const safeLines = Math.max(1, Math.floor(lines));
|
|
125
|
+
const escapedSession = this.escapeShellArg(this.sessionName);
|
|
126
|
+
const cmd = `tmux capture-pane -p -e -S -${safeLines} -t '${escapedSession}'`;
|
|
127
|
+
try {
|
|
128
|
+
const { stdout } = await execAsync(cmd);
|
|
129
|
+
return stdout;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
logger_1.logger.error('Failed to capture tmux pane snapshot', {
|
|
133
|
+
sessionName: this.sessionName,
|
|
134
|
+
error,
|
|
135
|
+
});
|
|
136
|
+
this.emit('observer-error', error);
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
escapeShellArg(value) {
|
|
141
|
+
return value.replace(/'/g, `'\\''`);
|
|
142
|
+
}
|
|
143
|
+
async enablePipePane() {
|
|
144
|
+
if (!this.sessionName || !this.pipeFilePath) {
|
|
145
|
+
throw new Error('Tmux pane observer is not initialized');
|
|
146
|
+
}
|
|
147
|
+
const escapedSession = this.escapeShellArg(this.sessionName);
|
|
148
|
+
const escapedFile = this.escapeShellArg(this.pipeFilePath);
|
|
149
|
+
const cmd = `tmux pipe-pane -O -t '${escapedSession}' "cat >> '${escapedFile}'"`;
|
|
150
|
+
await execAsync(cmd);
|
|
151
|
+
logger_1.logger.debug('Enabled tmux pipe-pane mirroring', {
|
|
152
|
+
sessionName: this.sessionName,
|
|
153
|
+
pipeFilePath: this.pipeFilePath,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
async disablePipePane() {
|
|
157
|
+
if (!this.sessionName) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const escapedSession = this.escapeShellArg(this.sessionName);
|
|
161
|
+
const cmd = `tmux pipe-pane -t '${escapedSession}'`;
|
|
162
|
+
await execAsync(cmd);
|
|
163
|
+
}
|
|
164
|
+
startFileWatcher() {
|
|
165
|
+
if (!this.pipeFilePath) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
this.watcher = fs.watch(this.pipeFilePath, (eventType) => {
|
|
169
|
+
if (eventType !== 'change') {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
void this.processFileChanges();
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
async processFileChanges() {
|
|
176
|
+
if (!this.pipeFilePath) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (this.processing) {
|
|
180
|
+
this.pendingRead = true;
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
this.processing = true;
|
|
184
|
+
try {
|
|
185
|
+
do {
|
|
186
|
+
this.pendingRead = false;
|
|
187
|
+
const chunk = this.readAppendedChunk();
|
|
188
|
+
if (!chunk) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (!this.looksLikePromptDelta(chunk)) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
const snapshot = await this.captureSnapshot();
|
|
195
|
+
if (!snapshot || !this.looksLikePromptSnapshot(snapshot)) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const promptHash = this.hashPromptSnapshot(snapshot);
|
|
199
|
+
if (promptHash === this.lastPromptHash) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
this.lastPromptHash = promptHash;
|
|
203
|
+
this.emit('prompt-candidate', {
|
|
204
|
+
rawDelta: chunk,
|
|
205
|
+
snapshot,
|
|
206
|
+
detectedAt: Date.now(),
|
|
207
|
+
});
|
|
208
|
+
} while (this.pendingRead);
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
logger_1.logger.error('Failed to process tmux pane changes', { error });
|
|
212
|
+
this.emit('observer-error', error);
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
this.processing = false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
readAppendedChunk() {
|
|
219
|
+
if (!this.pipeFilePath) {
|
|
220
|
+
return '';
|
|
221
|
+
}
|
|
222
|
+
const stat = fs.statSync(this.pipeFilePath);
|
|
223
|
+
if (stat.size <= this.filePosition) {
|
|
224
|
+
return '';
|
|
225
|
+
}
|
|
226
|
+
const fd = fs.openSync(this.pipeFilePath, 'r');
|
|
227
|
+
try {
|
|
228
|
+
const length = stat.size - this.filePosition;
|
|
229
|
+
const buffer = Buffer.alloc(length);
|
|
230
|
+
fs.readSync(fd, buffer, 0, length, this.filePosition);
|
|
231
|
+
this.filePosition = stat.size;
|
|
232
|
+
return buffer.toString('utf-8');
|
|
233
|
+
}
|
|
234
|
+
finally {
|
|
235
|
+
fs.closeSync(fd);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
looksLikePromptDelta(chunk) {
|
|
239
|
+
return /\[(?:y\/n|Y\/n|y\/N)\]|\b(?:apply|approve|allow|reject|deny|continue)\b/i.test(chunk);
|
|
240
|
+
}
|
|
241
|
+
looksLikePromptSnapshot(snapshot) {
|
|
242
|
+
const recentText = snapshot.split('\n').slice(-20).join('\n');
|
|
243
|
+
return /\[(?:y\/n|Y\/n|y\/N)\]|^\s*\d+\.\s+/im.test(recentText);
|
|
244
|
+
}
|
|
245
|
+
hashPromptSnapshot(snapshot) {
|
|
246
|
+
const normalized = snapshot
|
|
247
|
+
.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, '')
|
|
248
|
+
.replace(/\r/g, '\n')
|
|
249
|
+
.replace(/[ \t]+\n/g, '\n')
|
|
250
|
+
.trim();
|
|
251
|
+
return (0, crypto_1.createHash)('sha256').update(normalized).digest('hex');
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
exports.TmuxPaneObserver = TmuxPaneObserver;
|
|
255
|
+
//# sourceMappingURL=tmux-pane-observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-pane-observer.js","sourceRoot":"","sources":["../src/tmux-pane-observer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface StoredTokens {
|
|
2
|
+
accessToken: string;
|
|
3
|
+
idToken: string;
|
|
4
|
+
refreshToken: string;
|
|
5
|
+
expiresAt: number;
|
|
6
|
+
userId: string;
|
|
7
|
+
email: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Save tokens to secure file storage
|
|
11
|
+
*/
|
|
12
|
+
export declare function saveTokens(tokens: StoredTokens): void;
|
|
13
|
+
/**
|
|
14
|
+
* Load tokens from secure file storage
|
|
15
|
+
* Returns null if no tokens are stored or if they're invalid
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadTokens(): StoredTokens | null;
|
|
18
|
+
/**
|
|
19
|
+
* Delete stored tokens (logout)
|
|
20
|
+
*/
|
|
21
|
+
export declare function deleteTokens(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check if the access token is expired or about to expire
|
|
24
|
+
* Considers token expired if less than 5 minutes remaining
|
|
25
|
+
*/
|
|
26
|
+
export declare function isTokenExpired(tokens: StoredTokens): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Check if user is authenticated (has valid, non-expired tokens)
|
|
29
|
+
*/
|
|
30
|
+
export declare function isAuthenticated(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Get the token file path (for display purposes)
|
|
33
|
+
*/
|
|
34
|
+
export declare function getTokenFilePath(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Get token expiration date
|
|
37
|
+
*/
|
|
38
|
+
export declare function getTokenExpiration(): Date | null;
|
|
39
|
+
//# sourceMappingURL=token-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-storage.d.ts","sourceRoot":"","sources":["../src/token-storage.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAYD;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAkBrD;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,YAAY,GAAG,IAAI,CA6BhD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CActC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAG5D;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAOzC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,GAAG,IAAI,CAMhD"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.saveTokens = saveTokens;
|
|
37
|
+
exports.loadTokens = loadTokens;
|
|
38
|
+
exports.deleteTokens = deleteTokens;
|
|
39
|
+
exports.isTokenExpired = isTokenExpired;
|
|
40
|
+
exports.isAuthenticated = isAuthenticated;
|
|
41
|
+
exports.getTokenFilePath = getTokenFilePath;
|
|
42
|
+
exports.getTokenExpiration = getTokenExpiration;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const os = __importStar(require("os"));
|
|
46
|
+
const logger_1 = require("./logger");
|
|
47
|
+
// Token storage location - environment-specific
|
|
48
|
+
const TOKEN_DIR = path.join(os.homedir(), '.codevibe-codex');
|
|
49
|
+
// Get environment-specific token file
|
|
50
|
+
function getTokenFile() {
|
|
51
|
+
const environment = process.env.ENVIRONMENT || 'production';
|
|
52
|
+
return path.join(TOKEN_DIR, `tokens-${environment}.json`);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Ensure the token directory exists with proper permissions
|
|
56
|
+
*/
|
|
57
|
+
function ensureTokenDir() {
|
|
58
|
+
if (!fs.existsSync(TOKEN_DIR)) {
|
|
59
|
+
fs.mkdirSync(TOKEN_DIR, { mode: 0o700 }); // rwx------
|
|
60
|
+
logger_1.logger.debug('Created token directory', { path: TOKEN_DIR });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Save tokens to secure file storage
|
|
65
|
+
*/
|
|
66
|
+
function saveTokens(tokens) {
|
|
67
|
+
try {
|
|
68
|
+
ensureTokenDir();
|
|
69
|
+
const tokenFile = getTokenFile();
|
|
70
|
+
const content = JSON.stringify(tokens, null, 2);
|
|
71
|
+
fs.writeFileSync(tokenFile, content, { mode: 0o600 }); // rw-------
|
|
72
|
+
logger_1.logger.info('Tokens saved successfully', {
|
|
73
|
+
userId: tokens.userId,
|
|
74
|
+
email: tokens.email,
|
|
75
|
+
expiresAt: new Date(tokens.expiresAt).toISOString(),
|
|
76
|
+
environment: process.env.ENVIRONMENT || 'production',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
logger_1.logger.error('Failed to save tokens:', error);
|
|
81
|
+
throw new Error(`Failed to save tokens: ${error}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Load tokens from secure file storage
|
|
86
|
+
* Returns null if no tokens are stored or if they're invalid
|
|
87
|
+
*/
|
|
88
|
+
function loadTokens() {
|
|
89
|
+
try {
|
|
90
|
+
const tokenFile = getTokenFile();
|
|
91
|
+
if (!fs.existsSync(tokenFile)) {
|
|
92
|
+
logger_1.logger.debug('No tokens file found', { environment: process.env.ENVIRONMENT || 'production' });
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const content = fs.readFileSync(tokenFile, 'utf-8');
|
|
96
|
+
const tokens = JSON.parse(content);
|
|
97
|
+
// Validate required fields
|
|
98
|
+
if (!tokens.accessToken || !tokens.refreshToken || !tokens.expiresAt) {
|
|
99
|
+
logger_1.logger.warn('Invalid tokens file - missing required fields');
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
logger_1.logger.debug('Tokens loaded', {
|
|
103
|
+
userId: tokens.userId,
|
|
104
|
+
email: tokens.email,
|
|
105
|
+
expiresAt: new Date(tokens.expiresAt).toISOString(),
|
|
106
|
+
isExpired: isTokenExpired(tokens),
|
|
107
|
+
});
|
|
108
|
+
return tokens;
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
logger_1.logger.error('Failed to load tokens:', error);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Delete stored tokens (logout)
|
|
117
|
+
*/
|
|
118
|
+
function deleteTokens() {
|
|
119
|
+
try {
|
|
120
|
+
const tokenFile = getTokenFile();
|
|
121
|
+
if (fs.existsSync(tokenFile)) {
|
|
122
|
+
fs.unlinkSync(tokenFile);
|
|
123
|
+
logger_1.logger.info('Tokens deleted successfully', { environment: process.env.ENVIRONMENT || 'production' });
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
logger_1.logger.debug('No tokens file to delete', { environment: process.env.ENVIRONMENT || 'production' });
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
logger_1.logger.error('Failed to delete tokens:', error);
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if the access token is expired or about to expire
|
|
136
|
+
* Considers token expired if less than 5 minutes remaining
|
|
137
|
+
*/
|
|
138
|
+
function isTokenExpired(tokens) {
|
|
139
|
+
const bufferMs = 5 * 60 * 1000; // 5 minutes buffer
|
|
140
|
+
return Date.now() >= (tokens.expiresAt - bufferMs);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check if user is authenticated (has valid, non-expired tokens)
|
|
144
|
+
*/
|
|
145
|
+
function isAuthenticated() {
|
|
146
|
+
const tokens = loadTokens();
|
|
147
|
+
if (!tokens) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
// Even if access token is expired, we can refresh if we have a refresh token
|
|
151
|
+
return !!tokens.refreshToken;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get the token file path (for display purposes)
|
|
155
|
+
*/
|
|
156
|
+
function getTokenFilePath() {
|
|
157
|
+
return getTokenFile();
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get token expiration date
|
|
161
|
+
*/
|
|
162
|
+
function getTokenExpiration() {
|
|
163
|
+
const tokens = loadTokens();
|
|
164
|
+
if (!tokens) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
return new Date(tokens.expiresAt);
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=token-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-storage.js","sourceRoot":"","sources":["../src/token-storage.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export { EventType, EventSource, DeliveryStatus, Attachment, Event, CreateEventInput, UpdateEventStatusInput, SessionStatus, AgentType, Session, CreateSessionInput, UpdateSessionInput, EncryptedSessionKey, DeviceKey, KeyPair, DeviceIdentity, RegisterDeviceKeyInput, GrantSessionKeyInput, TokenData, } from '@quantiya/codevibe-core';
|
|
2
|
+
/**
|
|
3
|
+
* Top-level entry in Codex session log
|
|
4
|
+
*/
|
|
5
|
+
export interface CodexLogEntry {
|
|
6
|
+
timestamp: string;
|
|
7
|
+
type: 'session_meta' | 'event_msg' | 'response_item' | 'turn_context';
|
|
8
|
+
payload: any;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Session metadata (first entry in JSONL)
|
|
12
|
+
*/
|
|
13
|
+
export interface CodexSessionMeta {
|
|
14
|
+
id: string;
|
|
15
|
+
timestamp: string;
|
|
16
|
+
cwd: string;
|
|
17
|
+
originator: string;
|
|
18
|
+
cli_version: string;
|
|
19
|
+
instructions: string | null;
|
|
20
|
+
source: string;
|
|
21
|
+
model_provider: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Event message types
|
|
25
|
+
*/
|
|
26
|
+
export interface CodexEventMsg {
|
|
27
|
+
type: 'user_message' | 'agent_message' | 'agent_reasoning' | 'token_count';
|
|
28
|
+
message?: string;
|
|
29
|
+
text?: string;
|
|
30
|
+
images?: string[];
|
|
31
|
+
info?: any;
|
|
32
|
+
rate_limits?: any;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Response item - function calls
|
|
36
|
+
*/
|
|
37
|
+
export interface CodexFunctionCall {
|
|
38
|
+
type: 'function_call';
|
|
39
|
+
name: string;
|
|
40
|
+
arguments: string;
|
|
41
|
+
call_id: string;
|
|
42
|
+
}
|
|
43
|
+
export interface CodexFunctionCallOutput {
|
|
44
|
+
type: 'function_call_output';
|
|
45
|
+
call_id: string;
|
|
46
|
+
output: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Response item - custom tool calls (file edits)
|
|
50
|
+
*/
|
|
51
|
+
export interface CodexCustomToolCall {
|
|
52
|
+
type: 'custom_tool_call';
|
|
53
|
+
status: string;
|
|
54
|
+
name: string;
|
|
55
|
+
call_id: string;
|
|
56
|
+
input: string;
|
|
57
|
+
}
|
|
58
|
+
export interface CodexCustomToolCallOutput {
|
|
59
|
+
type: 'custom_tool_call_output';
|
|
60
|
+
call_id: string;
|
|
61
|
+
output: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Turn context
|
|
65
|
+
*/
|
|
66
|
+
export interface CodexTurnContext {
|
|
67
|
+
cwd: string;
|
|
68
|
+
approval_policy: string;
|
|
69
|
+
sandbox_policy: {
|
|
70
|
+
type: string;
|
|
71
|
+
};
|
|
72
|
+
model: string;
|
|
73
|
+
summary: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Session state (in-memory tracking)
|
|
77
|
+
*/
|
|
78
|
+
export interface SessionState {
|
|
79
|
+
sessionId: string;
|
|
80
|
+
userId: string;
|
|
81
|
+
projectPath: string;
|
|
82
|
+
cwd: string;
|
|
83
|
+
createdAt: Date;
|
|
84
|
+
subscriptionActive: boolean;
|
|
85
|
+
metadata: Record<string, any>;
|
|
86
|
+
codexSessionId?: string;
|
|
87
|
+
codexLogFile?: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Pending tool call (for approval detection)
|
|
91
|
+
*/
|
|
92
|
+
export interface PendingToolCall {
|
|
93
|
+
callId: string;
|
|
94
|
+
name: string;
|
|
95
|
+
input: string;
|
|
96
|
+
filePath?: string;
|
|
97
|
+
diff?: string;
|
|
98
|
+
parsedInput?: any;
|
|
99
|
+
timestamp: number;
|
|
100
|
+
notificationSent: boolean;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Active interactive prompt detected from tmux or the timeout heuristic.
|
|
104
|
+
*/
|
|
105
|
+
export interface PendingInteractivePrompt {
|
|
106
|
+
promptId: string;
|
|
107
|
+
callId?: string;
|
|
108
|
+
kind: 'yes_no' | 'numbered' | 'text';
|
|
109
|
+
options: Array<{
|
|
110
|
+
number: string;
|
|
111
|
+
text: string;
|
|
112
|
+
}>;
|
|
113
|
+
submitMap: Record<string, string>;
|
|
114
|
+
promptText: string;
|
|
115
|
+
createdAt: number;
|
|
116
|
+
source: 'tmux' | 'heuristic';
|
|
117
|
+
requiresFollowUpText?: boolean;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Command execution result
|
|
121
|
+
*/
|
|
122
|
+
export interface CommandResult {
|
|
123
|
+
success: boolean;
|
|
124
|
+
output?: string;
|
|
125
|
+
error?: string;
|
|
126
|
+
exitCode?: number;
|
|
127
|
+
timedOut?: boolean;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* FileChange type
|
|
131
|
+
*/
|
|
132
|
+
export interface FileChange {
|
|
133
|
+
changeId: string;
|
|
134
|
+
sessionId: string;
|
|
135
|
+
filePath: string;
|
|
136
|
+
action: string;
|
|
137
|
+
diff?: string;
|
|
138
|
+
timestamp: string;
|
|
139
|
+
metadata?: Record<string, any>;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* GraphQL input for creating file changes
|
|
143
|
+
*/
|
|
144
|
+
export interface CreateFileChangeInput {
|
|
145
|
+
sessionId: string;
|
|
146
|
+
filePath: string;
|
|
147
|
+
action: string;
|
|
148
|
+
diff?: string;
|
|
149
|
+
metadata?: Record<string, any>;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Pre-signed URL response for downloading attachments
|
|
153
|
+
*/
|
|
154
|
+
export interface DownloadUrlResponse {
|
|
155
|
+
downloadUrl: string;
|
|
156
|
+
expiresAt: string;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=types.d.ts.map
|