pi-harness-runtime 1.1.136 → 1.1.138
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/harness/langchain/daemon.ts +128 -25
- package/harness/langchain/run.ts +1 -1
- package/index.ts +41 -2
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/dist/src/index.d.ts +42 -0
- package/packages/codex-watcher/dist/src/index.d.ts.map +1 -0
- package/packages/codex-watcher/dist/src/index.js +198 -0
- package/packages/codex-watcher/dist/src/index.js.map +1 -0
- package/packages/codex-watcher/dist/src/parser.d.ts +36 -0
- package/packages/codex-watcher/dist/src/parser.d.ts.map +1 -0
- package/packages/codex-watcher/dist/src/parser.js +151 -0
- package/packages/codex-watcher/dist/src/parser.js.map +1 -0
- package/packages/codex-watcher/dist/src/session.d.ts +9 -0
- package/packages/codex-watcher/dist/src/session.d.ts.map +1 -0
- package/packages/codex-watcher/dist/src/session.js +131 -0
- package/packages/codex-watcher/dist/src/session.js.map +1 -0
- package/packages/codex-watcher/dist/src/types.d.ts +63 -0
- package/packages/codex-watcher/dist/src/types.d.ts.map +1 -0
- package/packages/codex-watcher/dist/src/types.js +17 -0
- package/packages/codex-watcher/dist/src/types.js.map +1 -0
- package/packages/codex-watcher/package.json +26 -0
- package/packages/codex-watcher/src/index.ts +244 -0
- package/packages/codex-watcher/src/parser.ts +210 -0
- package/packages/codex-watcher/src/session.ts +151 -0
- package/packages/codex-watcher/src/types.ts +67 -0
- package/packages/codex-watcher/test/watch.test.ts +150 -0
- package/packages/config-capture/package.json +1 -1
- package/packages/config-capture/src/index.ts +5 -16
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/dist/harness-header.d.ts +18 -14
- package/packages/tui/dist/harness-header.d.ts.map +1 -1
- package/packages/tui/dist/harness-header.js +110 -64
- package/packages/tui/dist/harness-header.js.map +1 -1
- package/packages/tui/dist/index.d.ts +1 -2
- package/packages/tui/dist/index.d.ts.map +1 -1
- package/packages/tui/dist/index.js +1 -2
- package/packages/tui/dist/index.js.map +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/tui/src/harness-header.ts +156 -77
- package/packages/tui/src/index.ts +6 -2
- package/packages/tui/test/harness-header.test.ts +380 -100
- package/packages/types/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Session Watcher — Main API
|
|
3
|
+
*
|
|
4
|
+
* Watches the active Codex CLI session and emits visible messages (user + assistant)
|
|
5
|
+
* so the harness PING-PONG middleware can feed them to pi.dev.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { startWatcher, getLatestSession, getVisibleMessages } from "@pi-harness/codex-watcher";
|
|
9
|
+
*
|
|
10
|
+
* // One-shot: get latest messages from the current session
|
|
11
|
+
* const session = getLatestSession();
|
|
12
|
+
* const messages = await getVisibleMessages(session.rolloutPath, { fromOrdinal: 0 });
|
|
13
|
+
*
|
|
14
|
+
* // Continuous: poll the active session and emit messages
|
|
15
|
+
* const handle = startWatcher({
|
|
16
|
+
* onMessages: (msgs) => console.log(msgs),
|
|
17
|
+
* });
|
|
18
|
+
* // later: handle.stop();
|
|
19
|
+
*/
|
|
20
|
+
import { existsSync, openSync, readFileSync, statSync } from "node:fs";
|
|
21
|
+
import { homedir } from "node:os";
|
|
22
|
+
import { join } from "node:path";
|
|
23
|
+
import { classifyMessage, parseNewMessages } from "./parser.js";
|
|
24
|
+
import { getAllSessions, getLatestSession } from "./session.js";
|
|
25
|
+
export { classifyMessage, getAllSessions, getLatestSession };
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// One-shot API
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/** Read all visible messages from a rollout file, starting from a given ordinal. */
|
|
30
|
+
export async function getVisibleMessages(rolloutPath, options = {}) {
|
|
31
|
+
const { fromOrdinal = 0, limit } = options;
|
|
32
|
+
if (!existsSync(rolloutPath))
|
|
33
|
+
return [];
|
|
34
|
+
const content = readFileSync(rolloutPath, "utf8");
|
|
35
|
+
const lines = content.split("\n").filter((l) => l.trim());
|
|
36
|
+
let messages = parseNewMessages(lines, fromOrdinal);
|
|
37
|
+
if (limit)
|
|
38
|
+
messages = messages.slice(-limit);
|
|
39
|
+
if (messages.length > 0) {
|
|
40
|
+
messages[messages.length - 1] = {
|
|
41
|
+
...messages[messages.length - 1],
|
|
42
|
+
isLatest: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return messages;
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Streaming watcher API
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
/**
|
|
51
|
+
* Start watching the active Codex session and call `onMessages` whenever
|
|
52
|
+
* new visible messages appear in the rollout file.
|
|
53
|
+
*
|
|
54
|
+
* @returns WatcherHandle — call handle.stop() to stop watching
|
|
55
|
+
*
|
|
56
|
+
* The watcher:
|
|
57
|
+
* 1. Polls session_index.jsonl to detect active session changes
|
|
58
|
+
* 2. Tracks file position so it only reads new lines (no re-read of full file)
|
|
59
|
+
* 3. Calls onMessages with incremental messages each poll cycle
|
|
60
|
+
*/
|
|
61
|
+
export function startWatcher(options = {}) {
|
|
62
|
+
const { pollIntervalMs = 2000, codexDir, onMessages, onSessionChange, } = options;
|
|
63
|
+
const home = codexDir ?? join(homedir(), ".codex");
|
|
64
|
+
let stopped = false;
|
|
65
|
+
let currentFd = null;
|
|
66
|
+
let currentPath = null;
|
|
67
|
+
let currentOrdinal = 0;
|
|
68
|
+
let pollCount = 0;
|
|
69
|
+
const maxIdlePolls = options.maxIdlePolls ?? Infinity;
|
|
70
|
+
// Track last known session to detect changes
|
|
71
|
+
let lastSessionId = null;
|
|
72
|
+
function stop() {
|
|
73
|
+
stopped = true;
|
|
74
|
+
if (currentFd !== null) {
|
|
75
|
+
try {
|
|
76
|
+
const { closeSync } = require("node:fs");
|
|
77
|
+
closeSync(currentFd);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// ignore
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function isRunning() {
|
|
85
|
+
return !stopped;
|
|
86
|
+
}
|
|
87
|
+
function latestSession() {
|
|
88
|
+
return getLatestSession(home);
|
|
89
|
+
}
|
|
90
|
+
function latestOrdinal() {
|
|
91
|
+
return currentOrdinal;
|
|
92
|
+
}
|
|
93
|
+
function openRollout(path) {
|
|
94
|
+
if (currentFd !== null && currentPath !== path) {
|
|
95
|
+
try {
|
|
96
|
+
const { closeSync } = require("node:fs");
|
|
97
|
+
closeSync(currentFd);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// ignore
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// stat to get current size
|
|
104
|
+
const stat = statSync(path);
|
|
105
|
+
currentFd = openSync(path, "r");
|
|
106
|
+
currentPath = path;
|
|
107
|
+
currentOrdinal = 0;
|
|
108
|
+
return { fd: currentFd, size: stat.size };
|
|
109
|
+
}
|
|
110
|
+
function readNewLines(fd, knownSize) {
|
|
111
|
+
const { readSync, fstatSync } = require("node:fs");
|
|
112
|
+
const stat = fstatSync(fd);
|
|
113
|
+
const newSize = stat.size;
|
|
114
|
+
if (newSize <= knownSize) {
|
|
115
|
+
return { lines: [], newSize: knownSize };
|
|
116
|
+
}
|
|
117
|
+
const buf = Buffer.alloc(newSize - knownSize);
|
|
118
|
+
const bytesRead = readSync(fd, buf, 0, buf.length, knownSize);
|
|
119
|
+
const text = buf.subarray(0, bytesRead).toString("utf8");
|
|
120
|
+
const lines = text.split("\n").filter((l) => l.trim());
|
|
121
|
+
return { lines, newSize };
|
|
122
|
+
}
|
|
123
|
+
async function poll() {
|
|
124
|
+
if (stopped)
|
|
125
|
+
return;
|
|
126
|
+
try {
|
|
127
|
+
// Check for session change
|
|
128
|
+
const session = getLatestSession(home);
|
|
129
|
+
const sessionId = session?.id ?? null;
|
|
130
|
+
if (sessionId !== lastSessionId) {
|
|
131
|
+
// New session or session ended
|
|
132
|
+
if (session) {
|
|
133
|
+
// Open new rollout
|
|
134
|
+
openRollout(session.rolloutPath);
|
|
135
|
+
currentOrdinal = 0;
|
|
136
|
+
// Read all existing lines as "historical"
|
|
137
|
+
const existing = await getVisibleMessages(session.rolloutPath, {
|
|
138
|
+
fromOrdinal: 0,
|
|
139
|
+
});
|
|
140
|
+
if (existing.length > 0) {
|
|
141
|
+
currentOrdinal = existing[existing.length - 1].ordinal;
|
|
142
|
+
}
|
|
143
|
+
onSessionChange?.(session);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
onSessionChange?.(null);
|
|
147
|
+
}
|
|
148
|
+
lastSessionId = sessionId;
|
|
149
|
+
pollCount = 0;
|
|
150
|
+
}
|
|
151
|
+
if (!session || !currentFd || currentPath !== session.rolloutPath) {
|
|
152
|
+
if (!stopped) {
|
|
153
|
+
await sleep(pollIntervalMs);
|
|
154
|
+
poll();
|
|
155
|
+
}
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const stat = statSync(session.rolloutPath);
|
|
159
|
+
const { lines } = readNewLines(currentFd, stat.size);
|
|
160
|
+
if (lines.length > 0) {
|
|
161
|
+
pollCount = 0;
|
|
162
|
+
const messages = parseNewMessages(lines, currentOrdinal);
|
|
163
|
+
if (messages.length > 0) {
|
|
164
|
+
currentOrdinal = messages[messages.length - 1].ordinal;
|
|
165
|
+
messages[messages.length - 1] = {
|
|
166
|
+
...messages[messages.length - 1],
|
|
167
|
+
isLatest: true,
|
|
168
|
+
};
|
|
169
|
+
onMessages?.(messages);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
pollCount++;
|
|
174
|
+
if (pollCount > maxIdlePolls) {
|
|
175
|
+
stop();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch (_err) {
|
|
181
|
+
// Session file may not exist yet; just wait
|
|
182
|
+
}
|
|
183
|
+
if (!stopped) {
|
|
184
|
+
await sleep(pollIntervalMs);
|
|
185
|
+
poll();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Start polling
|
|
189
|
+
poll();
|
|
190
|
+
return { stop, isRunning, latestSession, latestOrdinal };
|
|
191
|
+
}
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// Helpers
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
function sleep(ms) {
|
|
196
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser — extracts visible messages from Codex JSONL rollout lines.
|
|
3
|
+
*
|
|
4
|
+
* Safe subset (no developer/reasoning):
|
|
5
|
+
* type == "response_item" && payload.role == "user" → input_text content
|
|
6
|
+
* type == "event_msg" && payload.type == "item_completed"
|
|
7
|
+
* && payload.item.type == "AgentMessage"
|
|
8
|
+
* && payload.item.content[].type == "Text" → visible assistant text
|
|
9
|
+
*/
|
|
10
|
+
import type { CodexMessage } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Parse a single JSONL line from a Codex rollout file.
|
|
13
|
+
* Returns null if the line is not a visible message or is malformed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseRolloutLine(line: string): CodexMessage | null;
|
|
16
|
+
/**
|
|
17
|
+
* Parse all visible messages from a JSONL file.
|
|
18
|
+
* Reads from a given byte offset so callers can do incremental reads.
|
|
19
|
+
*
|
|
20
|
+
* @param lines Lines to parse (typically newly read lines)
|
|
21
|
+
* @param latestOrdinal The last ordinal already known (messages with ordinal ≤ this are skipped)
|
|
22
|
+
* @returns Messages with ordinal > latestOrdinal
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseNewMessages(lines: string[], latestOrdinal?: number): CodexMessage[];
|
|
25
|
+
/**
|
|
26
|
+
* Extract code blocks from assistant message text.
|
|
27
|
+
* Useful for detecting "plan" vs "code" in the Codex output.
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractCodeBlocks(text: string): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Detect whether the message is a plan (markdown outline) vs code output.
|
|
32
|
+
* Returns "plan" if it looks like a planning document, "code" if mostly code,
|
|
33
|
+
* "mixed" if both, "unknown" otherwise.
|
|
34
|
+
*/
|
|
35
|
+
export declare function classifyMessage(text: string): "plan" | "code" | "mixed" | "unknown";
|
|
36
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAiD/C;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAuBlE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,SAAI,GACf,YAAY,EAAE,CAWhB;AAqED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMxD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,MAAM,GACV,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAWvC"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser — extracts visible messages from Codex JSONL rollout lines.
|
|
3
|
+
*
|
|
4
|
+
* Safe subset (no developer/reasoning):
|
|
5
|
+
* type == "response_item" && payload.role == "user" → input_text content
|
|
6
|
+
* type == "event_msg" && payload.type == "item_completed"
|
|
7
|
+
* && payload.item.type == "AgentMessage"
|
|
8
|
+
* && payload.item.content[].type == "Text" → visible assistant text
|
|
9
|
+
*/
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Parse a single JSONL line into a CodexMessage
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
/**
|
|
14
|
+
* Parse a single JSONL line from a Codex rollout file.
|
|
15
|
+
* Returns null if the line is not a visible message or is malformed.
|
|
16
|
+
*/
|
|
17
|
+
export function parseRolloutLine(line) {
|
|
18
|
+
if (!line.trim())
|
|
19
|
+
return null;
|
|
20
|
+
let raw;
|
|
21
|
+
try {
|
|
22
|
+
raw = JSON.parse(line);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
// Assistant: visible text from AgentMessage item_completed events
|
|
28
|
+
if (isEventMsg(raw)) {
|
|
29
|
+
const msg = parseAssistantMessage(raw);
|
|
30
|
+
if (msg)
|
|
31
|
+
return msg;
|
|
32
|
+
}
|
|
33
|
+
// User: input_text from response_item events
|
|
34
|
+
if (isResponseItem(raw)) {
|
|
35
|
+
const msg = parseUserMessage(raw);
|
|
36
|
+
if (msg)
|
|
37
|
+
return msg;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parse all visible messages from a JSONL file.
|
|
43
|
+
* Reads from a given byte offset so callers can do incremental reads.
|
|
44
|
+
*
|
|
45
|
+
* @param lines Lines to parse (typically newly read lines)
|
|
46
|
+
* @param latestOrdinal The last ordinal already known (messages with ordinal ≤ this are skipped)
|
|
47
|
+
* @returns Messages with ordinal > latestOrdinal
|
|
48
|
+
*/
|
|
49
|
+
export function parseNewMessages(lines, latestOrdinal = 0) {
|
|
50
|
+
const messages = [];
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
const msg = parseRolloutLine(line);
|
|
53
|
+
if (msg && msg.ordinal > latestOrdinal) {
|
|
54
|
+
messages.push(msg);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Sort by ordinal (ascending) to preserve order
|
|
58
|
+
messages.sort((a, b) => a.ordinal - b.ordinal);
|
|
59
|
+
return messages;
|
|
60
|
+
}
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Type guards
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
function isEventMsg(raw) {
|
|
65
|
+
return raw.type === "event_msg";
|
|
66
|
+
}
|
|
67
|
+
function isResponseItem(raw) {
|
|
68
|
+
return raw.type === "response_item";
|
|
69
|
+
}
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Parse specific message types
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
function parseAssistantMessage(raw) {
|
|
74
|
+
const p = raw.payload;
|
|
75
|
+
if (p.type !== "item_completed")
|
|
76
|
+
return null;
|
|
77
|
+
if (p.item?.type !== "AgentMessage")
|
|
78
|
+
return null;
|
|
79
|
+
// Collect all Text content blocks
|
|
80
|
+
const texts = [];
|
|
81
|
+
for (const content of p.item.content ?? []) {
|
|
82
|
+
if (content.type === "Text" && content.text) {
|
|
83
|
+
texts.push(content.text);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (texts.length === 0)
|
|
87
|
+
return null;
|
|
88
|
+
return {
|
|
89
|
+
ordinal: raw.ordinal,
|
|
90
|
+
timestamp: raw.timestamp,
|
|
91
|
+
role: "assistant",
|
|
92
|
+
text: texts.join("\n"),
|
|
93
|
+
isLatest: false,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function parseUserMessage(raw) {
|
|
97
|
+
const p = raw.payload;
|
|
98
|
+
if (p.type !== "message")
|
|
99
|
+
return null;
|
|
100
|
+
if (p.role !== "user")
|
|
101
|
+
return null;
|
|
102
|
+
const texts = [];
|
|
103
|
+
for (const content of p.content ?? []) {
|
|
104
|
+
if (content.type === "input_text" && content.text) {
|
|
105
|
+
texts.push(content.text);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (texts.length === 0)
|
|
109
|
+
return null;
|
|
110
|
+
return {
|
|
111
|
+
ordinal: raw.ordinal,
|
|
112
|
+
timestamp: raw.timestamp,
|
|
113
|
+
role: "user",
|
|
114
|
+
text: texts.join("\n"),
|
|
115
|
+
isLatest: false,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// Text extraction utilities
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
/**
|
|
122
|
+
* Extract code blocks from assistant message text.
|
|
123
|
+
* Useful for detecting "plan" vs "code" in the Codex output.
|
|
124
|
+
*/
|
|
125
|
+
export function extractCodeBlocks(text) {
|
|
126
|
+
const blocks = [];
|
|
127
|
+
for (const match of text.matchAll(/```[\w]*\n?([\s\S]*?)```/g)) {
|
|
128
|
+
blocks.push(match[1]?.trim() ?? "");
|
|
129
|
+
}
|
|
130
|
+
return blocks;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Detect whether the message is a plan (markdown outline) vs code output.
|
|
134
|
+
* Returns "plan" if it looks like a planning document, "code" if mostly code,
|
|
135
|
+
* "mixed" if both, "unknown" otherwise.
|
|
136
|
+
*/
|
|
137
|
+
export function classifyMessage(text) {
|
|
138
|
+
const codeBlocks = extractCodeBlocks(text);
|
|
139
|
+
const codeCharCount = codeBlocks.join("").replace(/\s/g, "").length;
|
|
140
|
+
const nonCodeCharCount = text
|
|
141
|
+
.replace(/```[\s\S]*?```/g, "")
|
|
142
|
+
.replace(/\s/g, "").length;
|
|
143
|
+
if (codeCharCount === 0 && nonCodeCharCount > 0)
|
|
144
|
+
return "plan";
|
|
145
|
+
if (nonCodeCharCount === 0 && codeCharCount > 0)
|
|
146
|
+
return "code";
|
|
147
|
+
if (codeCharCount > 0 && nonCodeCharCount > 0)
|
|
148
|
+
return "mixed";
|
|
149
|
+
return "unknown";
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session discovery — reads ~/.codex/session_index.jsonl to find active sessions.
|
|
3
|
+
*/
|
|
4
|
+
import type { CodexSession } from "./types.js";
|
|
5
|
+
/** Find the most recently active Codex session. */
|
|
6
|
+
export declare function getLatestSession(codexDir?: string): CodexSession | null;
|
|
7
|
+
/** Get all sessions sorted by most recent first. */
|
|
8
|
+
export declare function getAllSessions(codexDir?: string): CodexSession[];
|
|
9
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAsBvE;AAED,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAkBhE"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session discovery — reads ~/.codex/session_index.jsonl to find active sessions.
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
/** Find the most recently active Codex session. */
|
|
8
|
+
export function getLatestSession(codexDir) {
|
|
9
|
+
const indexPath = getSessionIndexPath(codexDir);
|
|
10
|
+
if (!existsSync(indexPath))
|
|
11
|
+
return null;
|
|
12
|
+
let latest = null;
|
|
13
|
+
for (const line of readLines(indexPath)) {
|
|
14
|
+
const entry = parseSessionIndexLine(line);
|
|
15
|
+
if (!entry)
|
|
16
|
+
continue;
|
|
17
|
+
if (!latest || entry.updated_at > latest.updated_at) {
|
|
18
|
+
latest = entry;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (!latest)
|
|
22
|
+
return null;
|
|
23
|
+
return {
|
|
24
|
+
id: latest.id,
|
|
25
|
+
threadName: latest.thread_name,
|
|
26
|
+
updatedAt: latest.updated_at,
|
|
27
|
+
rolloutPath: findRolloutPath(latest.id, codexDir),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Get all sessions sorted by most recent first. */
|
|
31
|
+
export function getAllSessions(codexDir) {
|
|
32
|
+
const indexPath = getSessionIndexPath(codexDir);
|
|
33
|
+
if (!existsSync(indexPath))
|
|
34
|
+
return [];
|
|
35
|
+
const sessions = [];
|
|
36
|
+
for (const line of readLines(indexPath)) {
|
|
37
|
+
const entry = parseSessionIndexLine(line);
|
|
38
|
+
if (entry)
|
|
39
|
+
sessions.push(entry);
|
|
40
|
+
}
|
|
41
|
+
return sessions
|
|
42
|
+
.sort((a, b) => b.updated_at.localeCompare(a.updated_at))
|
|
43
|
+
.map((e) => ({
|
|
44
|
+
id: e.id,
|
|
45
|
+
threadName: e.thread_name,
|
|
46
|
+
updatedAt: e.updated_at,
|
|
47
|
+
rolloutPath: findRolloutPath(e.id, codexDir),
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Internal helpers
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
function getSessionIndexPath(codexDir) {
|
|
54
|
+
const home = codexDir ?? join(homedir(), ".codex");
|
|
55
|
+
return join(home, "session_index.jsonl");
|
|
56
|
+
}
|
|
57
|
+
function findRolloutPath(sessionId, codexDir) {
|
|
58
|
+
const home = codexDir ?? join(homedir(), ".codex");
|
|
59
|
+
const sessionsDir = join(home, "sessions");
|
|
60
|
+
// The rollout path follows: sessions/YYYY/MM/DD/rollout-YYYY-MM-DDTHH-MM-SS-<sessionId>.jsonl
|
|
61
|
+
// We need to find the file whose name ends with <sessionId>.jsonl
|
|
62
|
+
// Since there can be multiple sessions per day, iterate all files.
|
|
63
|
+
try {
|
|
64
|
+
const { readdirSync } = require("node:fs");
|
|
65
|
+
for (const dirPath of walkDirs(sessionsDir)) {
|
|
66
|
+
for (const file of readdirSync(dirPath)) {
|
|
67
|
+
if (file.endsWith(`${sessionId}.jsonl`)) {
|
|
68
|
+
return join(dirPath, file);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// walkSync may not be available on all Node versions; fall back to find
|
|
75
|
+
}
|
|
76
|
+
return findRolloutPathFallback(sessionId, sessionsDir);
|
|
77
|
+
}
|
|
78
|
+
function findRolloutPathFallback(sessionId, sessionsDir) {
|
|
79
|
+
const found = walkForSession(sessionsDir, sessionId);
|
|
80
|
+
return found ?? join(sessionsDir, "unknown", `${sessionId}.jsonl`);
|
|
81
|
+
}
|
|
82
|
+
/** Recursively walk all subdirectories, yielding each directory path. */
|
|
83
|
+
function* walkDirs(dir) {
|
|
84
|
+
const { readdirSync, statSync } = require("node:fs");
|
|
85
|
+
for (const entry of readdirSync(dir)) {
|
|
86
|
+
const full = join(dir, entry);
|
|
87
|
+
const stat = statSync(full);
|
|
88
|
+
if (stat.isDirectory()) {
|
|
89
|
+
yield full;
|
|
90
|
+
yield* walkDirs(full);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** Find the rollout file for a given session ID by walking directories. */
|
|
95
|
+
function walkForSession(sessionsDir, sessionId) {
|
|
96
|
+
const { readdirSync } = require("node:fs");
|
|
97
|
+
for (const dirPath of walkDirs(sessionsDir)) {
|
|
98
|
+
for (const file of readdirSync(dirPath)) {
|
|
99
|
+
if (file.startsWith("rollout-") && file.endsWith(`${sessionId}.jsonl`)) {
|
|
100
|
+
return join(dirPath, file);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
function parseSessionIndexLine(line) {
|
|
107
|
+
try {
|
|
108
|
+
const obj = JSON.parse(line);
|
|
109
|
+
if (typeof obj.id !== "string" || typeof obj.thread_name !== "string") {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
id: obj.id,
|
|
114
|
+
thread_name: obj.thread_name,
|
|
115
|
+
updated_at: String(obj.updated_at ?? ""),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function readLines(filePath) {
|
|
123
|
+
try {
|
|
124
|
+
const content = readFileSync(filePath, "utf8");
|
|
125
|
+
return content.split("\n").filter((l) => l.trim().length > 0);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Session Watcher — types
|
|
3
|
+
*
|
|
4
|
+
* Watches ~/.codex/ for active Codex CLI sessions and parses visible
|
|
5
|
+
* communication between the user and Codex (Planner role in PING-PONG).
|
|
6
|
+
*
|
|
7
|
+
* Key file locations:
|
|
8
|
+
* ~/.codex/session_index.jsonl — session registry
|
|
9
|
+
* ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl — session transcripts
|
|
10
|
+
*
|
|
11
|
+
* Visible message schema (safe subset — no developer/reasoning):
|
|
12
|
+
* type == "event_msg" && payload.type == "item_completed"
|
|
13
|
+
* && payload.item.type == "AgentMessage"
|
|
14
|
+
* && payload.item.content[].type == "Text"
|
|
15
|
+
*/
|
|
16
|
+
export interface CodexSession {
|
|
17
|
+
/** Codex session ID (UUID) */
|
|
18
|
+
id: string;
|
|
19
|
+
/** Human-readable session name */
|
|
20
|
+
threadName: string;
|
|
21
|
+
/** ISO-8601 when session was last active */
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
/** Absolute path to the rollout transcript file */
|
|
24
|
+
rolloutPath: string;
|
|
25
|
+
}
|
|
26
|
+
export interface CodexMessage {
|
|
27
|
+
/** Unique ordinal within the session (monotonically increasing) */
|
|
28
|
+
ordinal: number;
|
|
29
|
+
/** ISO-8601 timestamp */
|
|
30
|
+
timestamp: string;
|
|
31
|
+
/** Role: "user" (human) or "assistant" (Codex) */
|
|
32
|
+
role: "user" | "assistant";
|
|
33
|
+
/** Raw text content (markdown, code blocks, etc.) */
|
|
34
|
+
text: string;
|
|
35
|
+
/** Whether this message is the latest known message */
|
|
36
|
+
isLatest: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface CodexEvent {
|
|
39
|
+
/** Monotonically increasing ordinal within the session */
|
|
40
|
+
ordinal: number;
|
|
41
|
+
timestamp: string;
|
|
42
|
+
/** Raw JSON payload from the JSONL line */
|
|
43
|
+
raw: unknown;
|
|
44
|
+
}
|
|
45
|
+
export interface WatcherOptions {
|
|
46
|
+
/** How often to poll session_index.jsonl and active rollout file (ms). Default: 2000 */
|
|
47
|
+
pollIntervalMs?: number;
|
|
48
|
+
/** Absolute path to Codex home. Default: ~/.codex */
|
|
49
|
+
codexDir?: string;
|
|
50
|
+
/** Called with new visible messages each poll cycle */
|
|
51
|
+
onMessages?: (messages: CodexMessage[]) => void;
|
|
52
|
+
/** Called when a new session becomes active */
|
|
53
|
+
onSessionChange?: (session: CodexSession | null) => void;
|
|
54
|
+
/** Stop watching after N polls with no new lines. Default: Infinity */
|
|
55
|
+
maxIdlePolls?: number;
|
|
56
|
+
}
|
|
57
|
+
export interface WatcherHandle {
|
|
58
|
+
stop: () => void;
|
|
59
|
+
isRunning: () => boolean;
|
|
60
|
+
latestSession: () => CodexSession | null;
|
|
61
|
+
latestOrdinal: () => number;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,YAAY;IAC5B,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC5B,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IAC1B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,GAAG,EAAE,OAAO,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC9B,wFAAwF;IACxF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAChD,+CAA+C;IAC/C,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,KAAK,IAAI,CAAC;IACzD,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,YAAY,GAAG,IAAI,CAAC;IACzC,aAAa,EAAE,MAAM,MAAM,CAAC;CAC5B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Session Watcher — types
|
|
3
|
+
*
|
|
4
|
+
* Watches ~/.codex/ for active Codex CLI sessions and parses visible
|
|
5
|
+
* communication between the user and Codex (Planner role in PING-PONG).
|
|
6
|
+
*
|
|
7
|
+
* Key file locations:
|
|
8
|
+
* ~/.codex/session_index.jsonl — session registry
|
|
9
|
+
* ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl — session transcripts
|
|
10
|
+
*
|
|
11
|
+
* Visible message schema (safe subset — no developer/reasoning):
|
|
12
|
+
* type == "event_msg" && payload.type == "item_completed"
|
|
13
|
+
* && payload.item.type == "AgentMessage"
|
|
14
|
+
* && payload.item.content[].type == "Text"
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|