pi-harness-runtime 1.1.252 → 1.1.254
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/index.ts +41 -23
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/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 +1 -0
- package/packages/codex-watcher/dist/src/index.d.ts.map +1 -1
- package/packages/codex-watcher/dist/src/index.js +41 -17
- package/packages/codex-watcher/dist/src/index.js.map +1 -1
- package/packages/codex-watcher/dist/src/session.js +23 -29
- package/packages/codex-watcher/dist/src/session.js.map +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/codex-watcher/src/index.ts +45 -19
- package/packages/codex-watcher/src/session.ts +20 -33
- package/packages/config-capture/package.json +1 -1
- 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/e2e-tester/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/paperclip-integration/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/telegram/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/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/webmcp-tester/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
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* // later: handle.stop();
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import { existsSync, openSync, readFileSync,
|
|
21
|
+
import { existsSync, openSync, readFileSync, readSync, fstatSync, closeSync } from "node:fs";
|
|
22
22
|
import { homedir } from "node:os";
|
|
23
23
|
import { join } from "node:path";
|
|
24
24
|
import { classifyMessage, parseNewMessages } from "./parser.js";
|
|
@@ -75,6 +75,7 @@ export async function getVisibleMessages(
|
|
|
75
75
|
* 1. Polls session_index.jsonl to detect active session changes
|
|
76
76
|
* 2. Tracks file position so it only reads new lines (no re-read of full file)
|
|
77
77
|
* 3. Calls onMessages with incremental messages each poll cycle
|
|
78
|
+
* 4. Preserves incomplete JSON lines until a complete newline-delimited record arrives
|
|
78
79
|
*/
|
|
79
80
|
export function startWatcher(options: WatcherOptions = {}): WatcherHandle {
|
|
80
81
|
const {
|
|
@@ -89,6 +90,8 @@ export function startWatcher(options: WatcherOptions = {}): WatcherHandle {
|
|
|
89
90
|
let currentFd: ReturnType<typeof openSync> | null = null;
|
|
90
91
|
let currentPath: string | null = null;
|
|
91
92
|
let currentOrdinal = 0;
|
|
93
|
+
let currentBytePos = 0; // Track byte position we're at in the file
|
|
94
|
+
let pendingText = ""; // Preserve incomplete lines across reads
|
|
92
95
|
let pollCount = 0;
|
|
93
96
|
const maxIdlePolls = options.maxIdlePolls ?? Infinity;
|
|
94
97
|
|
|
@@ -99,11 +102,11 @@ export function startWatcher(options: WatcherOptions = {}): WatcherHandle {
|
|
|
99
102
|
stopped = true;
|
|
100
103
|
if (currentFd !== null) {
|
|
101
104
|
try {
|
|
102
|
-
const { closeSync } = require("node:fs") as typeof import("node:fs");
|
|
103
105
|
closeSync(currentFd);
|
|
104
106
|
} catch {
|
|
105
107
|
// ignore
|
|
106
108
|
}
|
|
109
|
+
currentFd = null;
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
112
|
|
|
@@ -122,43 +125,65 @@ export function startWatcher(options: WatcherOptions = {}): WatcherHandle {
|
|
|
122
125
|
function openRollout(path: string) {
|
|
123
126
|
if (currentFd !== null && currentPath !== path) {
|
|
124
127
|
try {
|
|
125
|
-
const { closeSync } = require("node:fs") as typeof import("node:fs");
|
|
126
128
|
closeSync(currentFd);
|
|
127
129
|
} catch {
|
|
128
130
|
// ignore
|
|
129
131
|
}
|
|
132
|
+
currentFd = null;
|
|
130
133
|
}
|
|
131
134
|
|
|
132
|
-
//
|
|
133
|
-
const stat = statSync(path);
|
|
135
|
+
// Open the file for reading
|
|
134
136
|
currentFd = openSync(path, "r");
|
|
135
137
|
currentPath = path;
|
|
136
138
|
currentOrdinal = 0;
|
|
137
|
-
|
|
139
|
+
currentBytePos = 0;
|
|
140
|
+
pendingText = ""; // Reset pending text for new file
|
|
141
|
+
return currentFd;
|
|
138
142
|
}
|
|
139
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Read new lines from the file, preserving incomplete records.
|
|
146
|
+
* Returns complete lines only; incomplete trailing data is kept for next read.
|
|
147
|
+
*/
|
|
140
148
|
function readNewLines(
|
|
141
149
|
fd: number,
|
|
142
|
-
knownSize: number,
|
|
143
150
|
): {
|
|
144
151
|
lines: string[];
|
|
145
|
-
|
|
152
|
+
newBytePos: number;
|
|
146
153
|
} {
|
|
147
|
-
const { readSync, fstatSync } =
|
|
148
|
-
require("node:fs") as typeof import("node:fs");
|
|
149
154
|
const stat = fstatSync(fd);
|
|
150
|
-
const
|
|
155
|
+
const fileSize = stat.size;
|
|
151
156
|
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
// Read from our tracked position to current end of file
|
|
158
|
+
const bytesToRead = fileSize - currentBytePos;
|
|
159
|
+
if (bytesToRead <= 0) {
|
|
160
|
+
return { lines: [], newBytePos: currentBytePos };
|
|
154
161
|
}
|
|
155
162
|
|
|
156
|
-
const buf = Buffer.alloc(
|
|
157
|
-
const bytesRead = readSync(fd, buf, 0, buf.length,
|
|
163
|
+
const buf = Buffer.alloc(bytesToRead);
|
|
164
|
+
const bytesRead = readSync(fd, buf, 0, buf.length, currentBytePos);
|
|
158
165
|
const text = buf.subarray(0, bytesRead).toString("utf8");
|
|
159
|
-
const lines = text.split("\n").filter((l) => l.trim());
|
|
160
166
|
|
|
161
|
-
|
|
167
|
+
// Prepend any pending text from previous incomplete read
|
|
168
|
+
const fullText = pendingText + text;
|
|
169
|
+
|
|
170
|
+
// Split by newline, keeping track of whether we ended with a complete line
|
|
171
|
+
const lines = fullText.split("\n");
|
|
172
|
+
|
|
173
|
+
// If text doesn't end with newline, last element is incomplete - save it
|
|
174
|
+
if (!text.endsWith("\n")) {
|
|
175
|
+
pendingText = lines.pop() ?? "";
|
|
176
|
+
} else {
|
|
177
|
+
pendingText = "";
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Filter out empty lines
|
|
181
|
+
const completeLines = lines.filter((l) => l.trim());
|
|
182
|
+
|
|
183
|
+
// Update our tracked position by bytes actually read
|
|
184
|
+
const newBytePos = currentBytePos + bytesRead;
|
|
185
|
+
|
|
186
|
+
return { lines: completeLines, newBytePos };
|
|
162
187
|
}
|
|
163
188
|
|
|
164
189
|
async function poll() {
|
|
@@ -198,8 +223,9 @@ export function startWatcher(options: WatcherOptions = {}): WatcherHandle {
|
|
|
198
223
|
return;
|
|
199
224
|
}
|
|
200
225
|
|
|
201
|
-
|
|
202
|
-
const { lines } = readNewLines(currentFd
|
|
226
|
+
// Read new lines from our tracked byte position
|
|
227
|
+
const { lines, newBytePos } = readNewLines(currentFd!);
|
|
228
|
+
currentBytePos = newBytePos; // Update tracked position
|
|
203
229
|
|
|
204
230
|
if (lines.length > 0) {
|
|
205
231
|
pollCount = 0;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Session discovery — reads ~/.codex/session_index.jsonl to find active sessions.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
import { join } from "node:path";
|
|
8
8
|
import type { CodexSession } from "./types.js";
|
|
@@ -69,51 +69,38 @@ function findRolloutPath(sessionId: string, codexDir?: string): string {
|
|
|
69
69
|
// The rollout path follows: sessions/YYYY/MM/DD/rollout-YYYY-MM-DDTHH-MM-SS-<sessionId>.jsonl
|
|
70
70
|
// We need to find the file whose name ends with <sessionId>.jsonl
|
|
71
71
|
// Since there can be multiple sessions per day, iterate all files.
|
|
72
|
-
try {
|
|
73
|
-
const { readdirSync } = require("node:fs") as typeof import("node:fs");
|
|
74
|
-
for (const dirPath of walkDirs(sessionsDir)) {
|
|
75
|
-
for (const file of readdirSync(dirPath)) {
|
|
76
|
-
if (file.endsWith(`${sessionId}.jsonl`)) {
|
|
77
|
-
return join(dirPath, file);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
} catch {
|
|
82
|
-
// walkSync may not be available on all Node versions; fall back to find
|
|
83
|
-
}
|
|
84
|
-
return findRolloutPathFallback(sessionId, sessionsDir);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function findRolloutPathFallback(
|
|
88
|
-
sessionId: string,
|
|
89
|
-
sessionsDir: string,
|
|
90
|
-
): string {
|
|
91
72
|
const found = walkForSession(sessionsDir, sessionId);
|
|
92
|
-
|
|
73
|
+
if (found) return found;
|
|
74
|
+
return join(sessionsDir, "unknown", `${sessionId}.jsonl`);
|
|
93
75
|
}
|
|
94
76
|
|
|
95
77
|
/** Recursively walk all subdirectories, yielding each directory path. */
|
|
96
78
|
function* walkDirs(dir: string): Generator<string> {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
79
|
+
try {
|
|
80
|
+
for (const entry of readdirSync(dir)) {
|
|
81
|
+
const full = join(dir, entry);
|
|
82
|
+
const stat = statSync(full);
|
|
83
|
+
if (stat.isDirectory()) {
|
|
84
|
+
yield full;
|
|
85
|
+
yield* walkDirs(full);
|
|
86
|
+
}
|
|
105
87
|
}
|
|
88
|
+
} catch {
|
|
89
|
+
// Directory may not exist or be readable
|
|
106
90
|
}
|
|
107
91
|
}
|
|
108
92
|
|
|
109
93
|
/** Find the rollout file for a given session ID by walking directories. */
|
|
110
94
|
function walkForSession(sessionsDir: string, sessionId: string): string | null {
|
|
111
|
-
const { readdirSync } = require("node:fs") as typeof import("node:fs");
|
|
112
95
|
for (const dirPath of walkDirs(sessionsDir)) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
96
|
+
try {
|
|
97
|
+
for (const file of readdirSync(dirPath)) {
|
|
98
|
+
if (file.startsWith("rollout-") && file.endsWith(`${sessionId}.jsonl`)) {
|
|
99
|
+
return join(dirPath, file);
|
|
100
|
+
}
|
|
116
101
|
}
|
|
102
|
+
} catch {
|
|
103
|
+
// Skip unreadable directories
|
|
117
104
|
}
|
|
118
105
|
}
|
|
119
106
|
return null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/provider-router",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.254",
|
|
4
4
|
"description": "Enhanced Provider Router for pi-harness-runtime — intelligent routing with capabilities, costs, and quotas",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/provider-router.js",
|