pi-harness-runtime 1.1.39 → 1.1.42
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 +7 -3
- package/harness/langchain/graph.ts +133 -9
- package/harness/langchain/scoreboard.test.ts +222 -0
- package/harness/langchain/widget.test.ts +25 -18
- package/harness/langchain/widget.ts +61 -44
- 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/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/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/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/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/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/tui/package.json +1 -1
- 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
- package/packages/write-review/src/blackboard.ts +56 -12
|
@@ -33,11 +33,14 @@ function visibleWidth(s: string): number {
|
|
|
33
33
|
// Skip CSI sequences: \x1b[ <params> <final>
|
|
34
34
|
// Valid final bytes: m (SGR), H (CUP), J (ED), A/B/C/D (CUU/CUD/CUF/CUB)
|
|
35
35
|
i++;
|
|
36
|
-
|
|
36
|
+
while (i < s.length && !/[a-zA-Z@]/.test(s[i])) i++;
|
|
37
37
|
if (i < s.length) i++; // skip final byte
|
|
38
38
|
continue;
|
|
39
39
|
}
|
|
40
|
-
if (cp <= 0x1f || cp === 0x7f) {
|
|
40
|
+
if (cp <= 0x1f || cp === 0x7f) {
|
|
41
|
+
i++;
|
|
42
|
+
continue;
|
|
43
|
+
} // C0 + DEL = 0
|
|
41
44
|
w += cp > 0xffff ? 2 : 1;
|
|
42
45
|
i += cp > 0xffff ? 2 : 1; // advance by code point, not UTF-16 code unit
|
|
43
46
|
}
|
|
@@ -170,7 +173,7 @@ export class LoopWidget {
|
|
|
170
173
|
const labels = {
|
|
171
174
|
approved: "✓ loop complete",
|
|
172
175
|
rejected: "✗ loop rejected",
|
|
173
|
-
|
|
176
|
+
max_iterations: `⚠ max iterations (${this.maxIterations})`,
|
|
174
177
|
};
|
|
175
178
|
this.stepLabel = labels[verdict];
|
|
176
179
|
this.render();
|
|
@@ -197,7 +200,10 @@ export class LoopWidget {
|
|
|
197
200
|
* Line 2: ` surge pause — resets 19:17` — surge detail (when applicable)
|
|
198
201
|
* Line 3: ` ●surge.ts ✍2 🔍3 !1` — file rows (up to 5)
|
|
199
202
|
*/
|
|
200
|
-
renderWidget(
|
|
203
|
+
renderWidget(
|
|
204
|
+
width: number,
|
|
205
|
+
theme: { fg: (color: ColorKey, s: string) => string },
|
|
206
|
+
): string[] {
|
|
201
207
|
const dim = (s: string) => theme.fg("dim", s);
|
|
202
208
|
const red = (s: string) => theme.fg("error", s);
|
|
203
209
|
const yellow = (s: string) => theme.fg("warning", s);
|
|
@@ -208,21 +214,18 @@ export class LoopWidget {
|
|
|
208
214
|
const lines: string[] = [];
|
|
209
215
|
|
|
210
216
|
// ── Header ──────────────────────────────────────────────────────────────
|
|
211
|
-
const iterStr =
|
|
212
|
-
|
|
213
|
-
|
|
217
|
+
const iterStr =
|
|
218
|
+
this.iteration > 0
|
|
219
|
+
? dim(`iter ${this.iteration}/${this.maxIterations}`)
|
|
220
|
+
: "";
|
|
214
221
|
// Use stepLabel if set (custom phase label, surge detail, error message)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
222
|
+
const phaseStr = this.stepLabel
|
|
223
|
+
? this.phaseIcon(this.phase) + " " + this.stepLabel
|
|
224
|
+
: this.phaseIcon(this.phase) + " " + this.phaseLabel(this.phase);
|
|
218
225
|
|
|
219
226
|
// Summary chunks (matches pi-lens style: !NW ●ME)
|
|
220
|
-
const errorChunk = this.errors > 0
|
|
221
|
-
|
|
222
|
-
: "";
|
|
223
|
-
const warningChunk = this.warnings > 0
|
|
224
|
-
? yellow(`!${this.warnings}W`)
|
|
225
|
-
: "";
|
|
227
|
+
const errorChunk = this.errors > 0 ? red(`●${this.errors}E`) : "";
|
|
228
|
+
const warningChunk = this.warnings > 0 ? yellow(`!${this.warnings}W`) : "";
|
|
226
229
|
const summary = errorChunk
|
|
227
230
|
? errorChunk + (warningChunk ? " " + warningChunk : "")
|
|
228
231
|
: warningChunk
|
|
@@ -231,12 +234,9 @@ export class LoopWidget {
|
|
|
231
234
|
? green("✓")
|
|
232
235
|
: dim("…");
|
|
233
236
|
|
|
234
|
-
const parts = [
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
phaseStr,
|
|
238
|
-
summary,
|
|
239
|
-
].filter(Boolean).join(" ");
|
|
237
|
+
const parts = [cyan("harness"), iterStr, phaseStr, summary]
|
|
238
|
+
.filter(Boolean)
|
|
239
|
+
.join(" ");
|
|
240
240
|
|
|
241
241
|
lines.push(this.fitLine(` ${parts}`, w));
|
|
242
242
|
|
|
@@ -257,11 +257,12 @@ export class LoopWidget {
|
|
|
257
257
|
|
|
258
258
|
for (const rec of sorted) {
|
|
259
259
|
const tier = this.classifyFileTier(rec);
|
|
260
|
-
const dot =
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
260
|
+
const dot =
|
|
261
|
+
tier === "blocking"
|
|
262
|
+
? red("●")
|
|
263
|
+
: tier === "warning"
|
|
264
|
+
? yellow("!")
|
|
265
|
+
: dim("·");
|
|
265
266
|
const base = this.fileBasename(rec.filePath);
|
|
266
267
|
const steps = rec.writeSteps > 0 ? dim(` ✍${rec.writeSteps}`) : "";
|
|
267
268
|
const reviews = rec.reviewsPassed > 0 ? dim(` 🔍${rec.reviewsPassed}`) : "";
|
|
@@ -276,25 +277,24 @@ export class LoopWidget {
|
|
|
276
277
|
/** Console fallback (standalone mode). */
|
|
277
278
|
toConsoleString(): string {
|
|
278
279
|
const phase = this.phaseIcon(this.phase) + " " + this.stepLabel;
|
|
279
|
-
const iter =
|
|
280
|
+
const iter =
|
|
281
|
+
this.iteration > 0 ? ` [iter ${this.iteration}/${this.maxIterations}]` : "";
|
|
280
282
|
const err = this.errors > 0 ? ` ●${this.errors}E` : "";
|
|
281
283
|
const warn = this.warnings > 0 ? ` !${this.warnings}W` : "";
|
|
282
284
|
const files = [...this.files.values()]
|
|
283
|
-
.filter(r => r.writeSteps > 0 || r.blockers > 0)
|
|
285
|
+
.filter((r) => r.writeSteps > 0 || r.blockers > 0)
|
|
284
286
|
.sort((a, b) => b.touchedAt - a.touchedAt)
|
|
285
287
|
.slice(0, 3)
|
|
286
|
-
.map(
|
|
288
|
+
.map(
|
|
289
|
+
(r) => `${this.fileBasename(r.filePath)}(${r.writeSteps}w/${r.blockers}b)`,
|
|
290
|
+
)
|
|
287
291
|
.join(", ");
|
|
288
292
|
|
|
289
|
-
const parts = [
|
|
290
|
-
`harness${iter}`,
|
|
291
|
-
phase,
|
|
292
|
-
].filter(Boolean).join(" ");
|
|
293
|
+
const parts = [`harness${iter}`, phase].filter(Boolean).join(" ");
|
|
293
294
|
|
|
294
|
-
return [
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
].filter(Boolean).join("\n");
|
|
295
|
+
return [parts + err + warn, files ? ` files: ${files}` : ""]
|
|
296
|
+
.filter(Boolean)
|
|
297
|
+
.join("\n");
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
// ─── Pi host widget factory (used by index.ts / ExtensionUIContext) ────────
|
|
@@ -315,7 +315,10 @@ export class LoopWidget {
|
|
|
315
315
|
* on every frame; `invalidate` is called by the harness to trigger a re-render.
|
|
316
316
|
*/
|
|
317
317
|
makeRenderer(): {
|
|
318
|
-
factory: (
|
|
318
|
+
factory: (
|
|
319
|
+
tui: TUI,
|
|
320
|
+
theme: Theme,
|
|
321
|
+
) => {
|
|
319
322
|
render: (width: number) => string[];
|
|
320
323
|
invalidate: () => void;
|
|
321
324
|
dispose: () => void;
|
|
@@ -323,7 +326,9 @@ export class LoopWidget {
|
|
|
323
326
|
invalidate: () => void;
|
|
324
327
|
} {
|
|
325
328
|
// Shared invalidate trigger — both the harness and the pi-tui component call this
|
|
326
|
-
const invalidate = () => {
|
|
329
|
+
const invalidate = () => {
|
|
330
|
+
/* mark dirty for next frame */
|
|
331
|
+
};
|
|
327
332
|
|
|
328
333
|
const factory = (_tui: TUI, theme: Theme) => {
|
|
329
334
|
type ColorKey = "dim" | "error" | "warning" | "success" | "accent";
|
|
@@ -334,12 +339,16 @@ export class LoopWidget {
|
|
|
334
339
|
};
|
|
335
340
|
|
|
336
341
|
// Called by harness to signal the widget needs to re-render
|
|
337
|
-
const widgetInvalidate = () => {
|
|
342
|
+
const widgetInvalidate = () => {
|
|
343
|
+
/* trigger invalidate */
|
|
344
|
+
};
|
|
338
345
|
|
|
339
346
|
return {
|
|
340
347
|
render,
|
|
341
348
|
invalidate: widgetInvalidate,
|
|
342
|
-
dispose: () => {
|
|
349
|
+
dispose: () => {
|
|
350
|
+
/* clean up */
|
|
351
|
+
},
|
|
343
352
|
};
|
|
344
353
|
};
|
|
345
354
|
|
|
@@ -371,7 +380,9 @@ export class LoopWidget {
|
|
|
371
380
|
return segs[segs.length - 1] ?? filePath;
|
|
372
381
|
}
|
|
373
382
|
|
|
374
|
-
private classifyFileTier(
|
|
383
|
+
private classifyFileTier(
|
|
384
|
+
rec: FileStepRecord,
|
|
385
|
+
): "blocking" | "warning" | "clean" {
|
|
375
386
|
if (rec.blockers > 0) return "blocking";
|
|
376
387
|
if (rec.writeSteps > 0 || rec.reviewsPassed > 0) return "warning";
|
|
377
388
|
return "clean";
|
|
@@ -434,7 +445,13 @@ export class LoopWidget {
|
|
|
434
445
|
const cp = line.codePointAt(i)!;
|
|
435
446
|
if (cp === 0x1b) {
|
|
436
447
|
// Skip ANSI sequences (don't count toward width)
|
|
437
|
-
while (
|
|
448
|
+
while (
|
|
449
|
+
i < line.length &&
|
|
450
|
+
line[i] !== "m" &&
|
|
451
|
+
line[i] !== "H" &&
|
|
452
|
+
line[i] !== "J"
|
|
453
|
+
)
|
|
454
|
+
i++;
|
|
438
455
|
continue;
|
|
439
456
|
}
|
|
440
457
|
const charW = cp > 0xffff ? 2 : 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/capability-registry",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.42",
|
|
4
4
|
"description": "Capability Registry for pi-harness-runtime — tracks model capabilities and enables capability-based routing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|