@quantiya/codevibe-codex-plugin 1.0.6 → 1.0.8
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/README.md +59 -106
- package/dist/server.js +22 -1051
- package/package.json +10 -12
- package/dist/approval-detector.d.ts +0 -38
- package/dist/approval-detector.d.ts.map +0 -1
- package/dist/approval-detector.js +0 -174
- package/dist/approval-detector.js.map +0 -1
- package/dist/appsync-client.d.ts +0 -69
- package/dist/appsync-client.d.ts.map +0 -1
- package/dist/appsync-client.js +0 -937
- package/dist/appsync-client.js.map +0 -1
- package/dist/auth-cli.d.ts +0 -11
- package/dist/auth-cli.d.ts.map +0 -1
- package/dist/auth-cli.js +0 -241
- package/dist/auth-cli.js.map +0 -1
- package/dist/config.d.ts +0 -29
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -116
- package/dist/config.js.map +0 -1
- package/dist/crypto-service.d.ts +0 -115
- package/dist/crypto-service.d.ts.map +0 -1
- package/dist/crypto-service.js +0 -278
- package/dist/crypto-service.js.map +0 -1
- package/dist/event-mapper.d.ts +0 -39
- package/dist/event-mapper.d.ts.map +0 -1
- package/dist/event-mapper.js +0 -302
- package/dist/event-mapper.js.map +0 -1
- package/dist/key-manager.d.ts +0 -87
- package/dist/key-manager.d.ts.map +0 -1
- package/dist/key-manager.js +0 -287
- package/dist/key-manager.js.map +0 -1
- package/dist/logger.d.ts +0 -2
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -18
- package/dist/logger.js.map +0 -1
- package/dist/prompt-parser.d.ts +0 -3
- package/dist/prompt-parser.d.ts.map +0 -1
- package/dist/prompt-parser.js +0 -8
- package/dist/prompt-parser.js.map +0 -1
- package/dist/prompt-responder.d.ts +0 -18
- package/dist/prompt-responder.d.ts.map +0 -1
- package/dist/prompt-responder.js +0 -78
- package/dist/prompt-responder.js.map +0 -1
- package/dist/server.d.ts +0 -8
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/session-id-cache.d.ts +0 -16
- package/dist/session-id-cache.d.ts.map +0 -1
- package/dist/session-id-cache.js +0 -90
- package/dist/session-id-cache.js.map +0 -1
- package/dist/session-log-watcher.d.ts +0 -61
- package/dist/session-log-watcher.d.ts.map +0 -1
- package/dist/session-log-watcher.js +0 -372
- package/dist/session-log-watcher.js.map +0 -1
- package/dist/tmux-pane-observer.d.ts +0 -39
- package/dist/tmux-pane-observer.d.ts.map +0 -1
- package/dist/tmux-pane-observer.js +0 -255
- package/dist/tmux-pane-observer.js.map +0 -1
- package/dist/token-storage.d.ts +0 -39
- package/dist/token-storage.d.ts.map +0 -1
- package/dist/token-storage.js +0 -169
- package/dist/token-storage.js.map +0 -1
- package/dist/types.d.ts +0 -158
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -17
- package/dist/types.js.map +0 -1
package/dist/session-id-cache.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
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.sessionIdCache = void 0;
|
|
37
|
-
const fs = __importStar(require("fs"));
|
|
38
|
-
const path = __importStar(require("path"));
|
|
39
|
-
const os = __importStar(require("os"));
|
|
40
|
-
const logger_1 = require("./logger");
|
|
41
|
-
/**
|
|
42
|
-
* Persists a mapping of Codex log filenames to backend session IDs.
|
|
43
|
-
* This ensures resumes (which reuse the same log file) attach to the same backend session.
|
|
44
|
-
*/
|
|
45
|
-
class SessionIdCache {
|
|
46
|
-
constructor() {
|
|
47
|
-
this.map = {};
|
|
48
|
-
const configDir = path.join(os.homedir(), '.codevibe-codex');
|
|
49
|
-
if (!fs.existsSync(configDir)) {
|
|
50
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
51
|
-
}
|
|
52
|
-
this.cachePath = path.join(configDir, 'session-id-map.json');
|
|
53
|
-
this.load();
|
|
54
|
-
}
|
|
55
|
-
load() {
|
|
56
|
-
try {
|
|
57
|
-
if (fs.existsSync(this.cachePath)) {
|
|
58
|
-
const raw = fs.readFileSync(this.cachePath, 'utf-8');
|
|
59
|
-
this.map = JSON.parse(raw);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
logger_1.logger.warn('Failed to load session ID cache', { cachePath: this.cachePath, error });
|
|
64
|
-
this.map = {};
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
save() {
|
|
68
|
-
try {
|
|
69
|
-
fs.writeFileSync(this.cachePath, JSON.stringify(this.map, null, 2), 'utf-8');
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
logger_1.logger.warn('Failed to write session ID cache', { cachePath: this.cachePath, error });
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
get(logFilePath) {
|
|
76
|
-
if (!logFilePath)
|
|
77
|
-
return null;
|
|
78
|
-
const key = path.basename(logFilePath);
|
|
79
|
-
return this.map[key] || null;
|
|
80
|
-
}
|
|
81
|
-
set(logFilePath, sessionId) {
|
|
82
|
-
if (!logFilePath)
|
|
83
|
-
return;
|
|
84
|
-
const key = path.basename(logFilePath);
|
|
85
|
-
this.map[key] = sessionId;
|
|
86
|
-
this.save();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
exports.sessionIdCache = new SessionIdCache();
|
|
90
|
-
//# sourceMappingURL=session-id-cache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-id-cache.js","sourceRoot":"","sources":["../src/session-id-cache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AACzB,qCAAkC;AAElC;;;GAGG;AACH,MAAM,cAAc;IAIlB;QAFQ,QAAG,GAA2B,EAAE,CAAC;QAGvC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAC;QAC7D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAEO,IAAI;QACV,IAAI,CAAC;YACH,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAClC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBACrD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YACrF,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAEO,IAAI;QACV,IAAI,CAAC;YACH,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,eAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,GAAG,CAAC,WAA0B;QAC5B,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,WAA0B,EAAE,SAAiB;QAC/C,IAAI,CAAC,WAAW;YAAE,OAAO;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;QAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;CACF;AAEY,QAAA,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from 'events';
|
|
2
|
-
/**
|
|
3
|
-
* Watches Codex CLI session log files for new entries
|
|
4
|
-
*
|
|
5
|
-
* Codex writes JSONL logs to: ~/.codex/sessions/YYYY/MM/DD/rollout-{timestamp}-{uuid}.jsonl
|
|
6
|
-
*
|
|
7
|
-
* Events emitted:
|
|
8
|
-
* - 'session-started': New session detected (CodexSessionMeta)
|
|
9
|
-
* - 'log-entry': New log entry (CodexLogEntry)
|
|
10
|
-
* - 'error': Error occurred
|
|
11
|
-
*/
|
|
12
|
-
export declare class SessionLogWatcher extends EventEmitter {
|
|
13
|
-
private watcher;
|
|
14
|
-
private filePositions;
|
|
15
|
-
private activeLogFile;
|
|
16
|
-
private sessionId;
|
|
17
|
-
private isWatching;
|
|
18
|
-
private startTime;
|
|
19
|
-
private sessionsDir;
|
|
20
|
-
constructor();
|
|
21
|
-
/**
|
|
22
|
-
* Start watching for Codex session logs
|
|
23
|
-
*/
|
|
24
|
-
start(): void;
|
|
25
|
-
/**
|
|
26
|
-
* Stop watching for session logs
|
|
27
|
-
*/
|
|
28
|
-
stop(): void;
|
|
29
|
-
/**
|
|
30
|
-
* Get the current active session ID
|
|
31
|
-
*/
|
|
32
|
-
getSessionId(): string | null;
|
|
33
|
-
/**
|
|
34
|
-
* Get the current active log file
|
|
35
|
-
*/
|
|
36
|
-
getActiveLogFile(): string | null;
|
|
37
|
-
/**
|
|
38
|
-
* Handle new log file detected
|
|
39
|
-
*/
|
|
40
|
-
private onFileAdded;
|
|
41
|
-
/**
|
|
42
|
-
* Handle log file changes
|
|
43
|
-
*/
|
|
44
|
-
private onFileChanged;
|
|
45
|
-
/**
|
|
46
|
-
* Backfill any very recent session file that was created while chokidar was
|
|
47
|
-
* still performing its initial scan. This avoids missing the first log file
|
|
48
|
-
* for a newly started server instance.
|
|
49
|
-
*/
|
|
50
|
-
private bindRecentSessionFile;
|
|
51
|
-
private collectRecentSessionFiles;
|
|
52
|
-
/**
|
|
53
|
-
* Read new lines from the log file and emit events
|
|
54
|
-
*/
|
|
55
|
-
private readNewLines;
|
|
56
|
-
/**
|
|
57
|
-
* Process a single log entry
|
|
58
|
-
*/
|
|
59
|
-
private processLogEntry;
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=session-log-watcher.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-log-watcher.d.ts","sourceRoot":"","sources":["../src/session-log-watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAStC;;;;;;;;;GASG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,WAAW,CAAuB;;IAM1C;;OAEG;IACI,KAAK,IAAI,IAAI;IA+DpB;;OAEG;IACI,IAAI,IAAI,IAAI;IAanB;;OAEG;IACI,YAAY,IAAI,MAAM,GAAG,IAAI;IAIpC;;OAEG;IACI,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIxC;;OAEG;IACH,OAAO,CAAC,WAAW;IAsCnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAyCrB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,yBAAyB;IA8CjC;;OAEG;YACW,YAAY;IAgD1B;;OAEG;IACH,OAAO,CAAC,eAAe;CA0BxB"}
|
|
@@ -1,372 +0,0 @@
|
|
|
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.SessionLogWatcher = void 0;
|
|
37
|
-
const events_1 = require("events");
|
|
38
|
-
const fs = __importStar(require("fs"));
|
|
39
|
-
const path = __importStar(require("path"));
|
|
40
|
-
const readline = __importStar(require("readline"));
|
|
41
|
-
const chokidar_1 = require("chokidar");
|
|
42
|
-
const codevibe_core_1 = require("@quantiya/codevibe-core");
|
|
43
|
-
const logger_1 = require("./logger");
|
|
44
|
-
/**
|
|
45
|
-
* Watches Codex CLI session log files for new entries
|
|
46
|
-
*
|
|
47
|
-
* Codex writes JSONL logs to: ~/.codex/sessions/YYYY/MM/DD/rollout-{timestamp}-{uuid}.jsonl
|
|
48
|
-
*
|
|
49
|
-
* Events emitted:
|
|
50
|
-
* - 'session-started': New session detected (CodexSessionMeta)
|
|
51
|
-
* - 'log-entry': New log entry (CodexLogEntry)
|
|
52
|
-
* - 'error': Error occurred
|
|
53
|
-
*/
|
|
54
|
-
class SessionLogWatcher extends events_1.EventEmitter {
|
|
55
|
-
constructor() {
|
|
56
|
-
super();
|
|
57
|
-
this.watcher = null;
|
|
58
|
-
this.filePositions = new Map();
|
|
59
|
-
this.activeLogFile = null;
|
|
60
|
-
this.sessionId = null;
|
|
61
|
-
this.isWatching = false;
|
|
62
|
-
this.startTime = 0; // Track when watcher started
|
|
63
|
-
this.sessionsDir = null;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Start watching for Codex session logs
|
|
67
|
-
*/
|
|
68
|
-
start() {
|
|
69
|
-
if (this.isWatching) {
|
|
70
|
-
logger_1.logger.warn('Session log watcher already running');
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
const sessionsDir = (0, codevibe_core_1.getConfig)().codex.sessionsDir;
|
|
74
|
-
this.sessionsDir = sessionsDir;
|
|
75
|
-
logger_1.logger.info('Starting Codex session log watcher', { sessionsDir });
|
|
76
|
-
// Ensure sessions directory exists
|
|
77
|
-
if (!fs.existsSync(sessionsDir)) {
|
|
78
|
-
logger_1.logger.info('Codex sessions directory does not exist yet, creating...', { sessionsDir });
|
|
79
|
-
fs.mkdirSync(sessionsDir, { recursive: true });
|
|
80
|
-
}
|
|
81
|
-
// Record start time to filter out pre-existing files
|
|
82
|
-
this.startTime = Date.now();
|
|
83
|
-
// Watch the entire sessions directory recursively
|
|
84
|
-
// Chokidar glob patterns don't work well on macOS, so watch the directory
|
|
85
|
-
// and filter for .jsonl files in the event handlers
|
|
86
|
-
// Use ignoreInitial: true to avoid processing old session files
|
|
87
|
-
this.watcher = (0, chokidar_1.watch)(sessionsDir, {
|
|
88
|
-
persistent: true,
|
|
89
|
-
ignoreInitial: true, // Only watch for NEW files, not existing ones
|
|
90
|
-
awaitWriteFinish: {
|
|
91
|
-
stabilityThreshold: 100,
|
|
92
|
-
pollInterval: 50,
|
|
93
|
-
},
|
|
94
|
-
depth: 4, // YYYY/MM/DD depth
|
|
95
|
-
ignored: (filePath) => {
|
|
96
|
-
// Only watch .jsonl files that match the rollout pattern
|
|
97
|
-
const basename = path.basename(filePath);
|
|
98
|
-
const isDir = fs.existsSync(filePath) && fs.statSync(filePath).isDirectory();
|
|
99
|
-
if (isDir)
|
|
100
|
-
return false; // Don't ignore directories
|
|
101
|
-
return !basename.startsWith('rollout-') || !basename.endsWith('.jsonl');
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
this.watcher.on('add', (filePath) => {
|
|
105
|
-
if (filePath.endsWith('.jsonl')) {
|
|
106
|
-
this.onFileAdded(filePath);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
this.watcher.on('change', (filePath) => {
|
|
110
|
-
if (filePath.endsWith('.jsonl')) {
|
|
111
|
-
this.onFileChanged(filePath);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
this.watcher.on('error', (error) => {
|
|
115
|
-
logger_1.logger.error('Watcher error:', error);
|
|
116
|
-
this.emit('error', error);
|
|
117
|
-
});
|
|
118
|
-
this.watcher.on('ready', () => {
|
|
119
|
-
logger_1.logger.info('Session log watcher ready');
|
|
120
|
-
this.bindRecentSessionFile();
|
|
121
|
-
});
|
|
122
|
-
this.isWatching = true;
|
|
123
|
-
logger_1.logger.info('Session log watcher started');
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Stop watching for session logs
|
|
127
|
-
*/
|
|
128
|
-
stop() {
|
|
129
|
-
if (this.watcher) {
|
|
130
|
-
this.watcher.close();
|
|
131
|
-
this.watcher = null;
|
|
132
|
-
}
|
|
133
|
-
this.isWatching = false;
|
|
134
|
-
this.filePositions.clear();
|
|
135
|
-
this.activeLogFile = null;
|
|
136
|
-
this.sessionId = null;
|
|
137
|
-
this.sessionsDir = null;
|
|
138
|
-
logger_1.logger.info('Session log watcher stopped');
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Get the current active session ID
|
|
142
|
-
*/
|
|
143
|
-
getSessionId() {
|
|
144
|
-
return this.sessionId;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Get the current active log file
|
|
148
|
-
*/
|
|
149
|
-
getActiveLogFile() {
|
|
150
|
-
return this.activeLogFile;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Handle new log file detected
|
|
154
|
-
*/
|
|
155
|
-
onFileAdded(filePath) {
|
|
156
|
-
// Safety check: only process files created after watcher started
|
|
157
|
-
// This prevents processing old sessions if ignoreInitial doesn't work
|
|
158
|
-
try {
|
|
159
|
-
const stat = fs.statSync(filePath);
|
|
160
|
-
const fileCreatedAt = stat.birthtimeMs || stat.ctimeMs;
|
|
161
|
-
// Allow 5 second buffer for timing differences
|
|
162
|
-
if (fileCreatedAt < this.startTime - 5000) {
|
|
163
|
-
logger_1.logger.debug('Ignoring old session file', {
|
|
164
|
-
filePath,
|
|
165
|
-
fileCreatedAt: new Date(fileCreatedAt).toISOString(),
|
|
166
|
-
startTime: new Date(this.startTime).toISOString()
|
|
167
|
-
});
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
logger_1.logger.warn('Could not check file creation time', { filePath, error });
|
|
173
|
-
}
|
|
174
|
-
if (this.activeLogFile) {
|
|
175
|
-
logger_1.logger.debug('Ignoring additional Codex session log for this server instance', {
|
|
176
|
-
activeLogFile: this.activeLogFile,
|
|
177
|
-
ignoredFile: filePath,
|
|
178
|
-
});
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
logger_1.logger.info('New Codex session log detected', { filePath });
|
|
182
|
-
// This is now the active session
|
|
183
|
-
this.activeLogFile = filePath;
|
|
184
|
-
this.filePositions.set(filePath, 0);
|
|
185
|
-
// Read all existing content
|
|
186
|
-
this.readNewLines(filePath);
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Handle log file changes
|
|
190
|
-
*/
|
|
191
|
-
onFileChanged(filePath) {
|
|
192
|
-
// Each server instance must stay pinned to the first session log it binds to.
|
|
193
|
-
// Otherwise a second Codex session can hijack the first server instance.
|
|
194
|
-
if (this.activeLogFile && filePath !== this.activeLogFile) {
|
|
195
|
-
logger_1.logger.debug('Ignoring change for non-active session log', {
|
|
196
|
-
activeLogFile: this.activeLogFile,
|
|
197
|
-
ignoredFile: filePath,
|
|
198
|
-
});
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
if (!this.activeLogFile) {
|
|
202
|
-
// Only bind to files created or modified after this watcher started.
|
|
203
|
-
// Without this check, a second server instance can accidentally bind to
|
|
204
|
-
// the first server's Codex log file when Codex 1 writes new content,
|
|
205
|
-
// causing Codex 2's events to be lost entirely.
|
|
206
|
-
try {
|
|
207
|
-
const stat = fs.statSync(filePath);
|
|
208
|
-
const fileCreatedAt = stat.birthtimeMs || stat.ctimeMs;
|
|
209
|
-
const fileModifiedAt = stat.mtimeMs;
|
|
210
|
-
// Allow files that were created recently OR modified recently (resumed sessions)
|
|
211
|
-
if (fileCreatedAt < this.startTime - 5000 && fileModifiedAt < this.startTime - 5000) {
|
|
212
|
-
logger_1.logger.debug('Ignoring change for pre-existing session file', {
|
|
213
|
-
filePath,
|
|
214
|
-
fileCreatedAt: new Date(fileCreatedAt).toISOString(),
|
|
215
|
-
fileModifiedAt: new Date(fileModifiedAt).toISOString(),
|
|
216
|
-
startTime: new Date(this.startTime).toISOString(),
|
|
217
|
-
});
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
catch (error) {
|
|
222
|
-
logger_1.logger.warn('Could not check file creation time during change event', { filePath, error });
|
|
223
|
-
}
|
|
224
|
-
this.activeLogFile = filePath;
|
|
225
|
-
this.filePositions.set(filePath, 0);
|
|
226
|
-
}
|
|
227
|
-
this.readNewLines(filePath);
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Backfill any very recent session file that was created while chokidar was
|
|
231
|
-
* still performing its initial scan. This avoids missing the first log file
|
|
232
|
-
* for a newly started server instance.
|
|
233
|
-
*/
|
|
234
|
-
bindRecentSessionFile() {
|
|
235
|
-
if (this.activeLogFile || !this.sessionsDir) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
try {
|
|
239
|
-
const candidates = this.collectRecentSessionFiles(this.sessionsDir)
|
|
240
|
-
.sort((left, right) => right.modifiedAt - left.modifiedAt);
|
|
241
|
-
const recent = candidates[0];
|
|
242
|
-
if (!recent) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
logger_1.logger.info('Binding recent session file missed during initial watch scan', {
|
|
246
|
-
filePath: recent.filePath,
|
|
247
|
-
fileCreatedAt: new Date(recent.createdAt).toISOString(),
|
|
248
|
-
fileModifiedAt: new Date(recent.modifiedAt).toISOString(),
|
|
249
|
-
watcherStartTime: new Date(this.startTime).toISOString(),
|
|
250
|
-
});
|
|
251
|
-
this.activeLogFile = recent.filePath;
|
|
252
|
-
this.filePositions.set(recent.filePath, 0);
|
|
253
|
-
this.readNewLines(recent.filePath);
|
|
254
|
-
}
|
|
255
|
-
catch (error) {
|
|
256
|
-
logger_1.logger.warn('Failed to backfill recent session file', { error });
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
collectRecentSessionFiles(rootDir) {
|
|
260
|
-
const results = [];
|
|
261
|
-
const stack = [rootDir];
|
|
262
|
-
while (stack.length > 0) {
|
|
263
|
-
const currentDir = stack.pop();
|
|
264
|
-
if (!currentDir) {
|
|
265
|
-
continue;
|
|
266
|
-
}
|
|
267
|
-
let entries;
|
|
268
|
-
try {
|
|
269
|
-
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
270
|
-
}
|
|
271
|
-
catch {
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
for (const entry of entries) {
|
|
275
|
-
const fullPath = path.join(currentDir, entry.name);
|
|
276
|
-
if (entry.isDirectory()) {
|
|
277
|
-
stack.push(fullPath);
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
if (!entry.isFile() || !entry.name.startsWith('rollout-') || !entry.name.endsWith('.jsonl')) {
|
|
281
|
-
continue;
|
|
282
|
-
}
|
|
283
|
-
try {
|
|
284
|
-
const stat = fs.statSync(fullPath);
|
|
285
|
-
const createdAt = stat.birthtimeMs || stat.ctimeMs;
|
|
286
|
-
const modifiedAt = stat.mtimeMs;
|
|
287
|
-
// Include files that were created OR modified recently
|
|
288
|
-
if (createdAt >= this.startTime || modifiedAt >= this.startTime - 5000) {
|
|
289
|
-
results.push({ filePath: fullPath, createdAt, modifiedAt });
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
catch {
|
|
293
|
-
// Ignore files that disappear between readdir and stat
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
return results;
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Read new lines from the log file and emit events
|
|
301
|
-
*/
|
|
302
|
-
async readNewLines(filePath) {
|
|
303
|
-
const position = this.filePositions.get(filePath) || 0;
|
|
304
|
-
try {
|
|
305
|
-
const stat = fs.statSync(filePath);
|
|
306
|
-
if (stat.size <= position) {
|
|
307
|
-
return; // No new content
|
|
308
|
-
}
|
|
309
|
-
// Create read stream starting from last position
|
|
310
|
-
const stream = fs.createReadStream(filePath, {
|
|
311
|
-
start: position,
|
|
312
|
-
encoding: 'utf-8',
|
|
313
|
-
});
|
|
314
|
-
const rl = readline.createInterface({
|
|
315
|
-
input: stream,
|
|
316
|
-
crlfDelay: Infinity,
|
|
317
|
-
});
|
|
318
|
-
let bytesRead = position;
|
|
319
|
-
for await (const line of rl) {
|
|
320
|
-
bytesRead += Buffer.byteLength(line, 'utf-8') + 1; // +1 for newline
|
|
321
|
-
if (!line.trim())
|
|
322
|
-
continue;
|
|
323
|
-
try {
|
|
324
|
-
const entry = JSON.parse(line);
|
|
325
|
-
this.processLogEntry(entry);
|
|
326
|
-
}
|
|
327
|
-
catch (parseError) {
|
|
328
|
-
logger_1.logger.warn('Failed to parse log line', {
|
|
329
|
-
filePath,
|
|
330
|
-
line: line.substring(0, 100),
|
|
331
|
-
error: parseError
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
// Update position
|
|
336
|
-
this.filePositions.set(filePath, bytesRead);
|
|
337
|
-
}
|
|
338
|
-
catch (error) {
|
|
339
|
-
logger_1.logger.error('Error reading log file', { filePath, error });
|
|
340
|
-
this.emit('error', error);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Process a single log entry
|
|
345
|
-
*/
|
|
346
|
-
processLogEntry(entry) {
|
|
347
|
-
logger_1.logger.debug('Processing log entry', { type: entry.type });
|
|
348
|
-
// Handle session metadata (first entry in file)
|
|
349
|
-
if (entry.type === 'session_meta') {
|
|
350
|
-
const meta = entry.payload;
|
|
351
|
-
this.sessionId = meta.id;
|
|
352
|
-
logger_1.logger.info('Codex session started', {
|
|
353
|
-
sessionId: meta.id,
|
|
354
|
-
cwd: meta.cwd,
|
|
355
|
-
cliVersion: meta.cli_version,
|
|
356
|
-
});
|
|
357
|
-
this.emit('session-started', meta);
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
// Emit all other entries
|
|
361
|
-
this.emit('log-entry', entry);
|
|
362
|
-
// Also emit specific events for convenience
|
|
363
|
-
if (entry.type === 'event_msg' && entry.payload?.type) {
|
|
364
|
-
this.emit(`event:${entry.payload.type}`, entry);
|
|
365
|
-
}
|
|
366
|
-
else if (entry.type === 'response_item' && entry.payload?.type) {
|
|
367
|
-
this.emit(`response:${entry.payload.type}`, entry);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
exports.SessionLogWatcher = SessionLogWatcher;
|
|
372
|
-
//# sourceMappingURL=session-log-watcher.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-log-watcher.js","sourceRoot":"","sources":["../src/session-log-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,39 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|