pi-harness-runtime 1.1.135 → 1.1.136

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.
Files changed (100) hide show
  1. package/package.json +1 -1
  2. package/packages/a2a-adapter/package.json +1 -1
  3. package/packages/architecture-generator/package.json +1 -1
  4. package/packages/auth/package.json +1 -1
  5. package/packages/autonomous-refactor/package.json +1 -1
  6. package/packages/autonomous-runtime/package.json +1 -1
  7. package/packages/cache-strategy/package.json +1 -1
  8. package/packages/capability-registry/package.json +1 -1
  9. package/packages/checkpoint/package.json +1 -1
  10. package/packages/cli-plugin-sdk/package.json +1 -1
  11. package/packages/clipboard/package.json +1 -1
  12. package/packages/clipboard-plugin/package.json +1 -1
  13. package/packages/code-generation/package.json +1 -1
  14. package/packages/code-review/package.json +1 -1
  15. package/packages/codex-adapter/package.json +1 -1
  16. package/packages/config-capture/package.json +1 -1
  17. package/packages/context-compiler/package.json +1 -1
  18. package/packages/context-discovery/package.json +1 -1
  19. package/packages/context-manager/package.json +1 -1
  20. package/packages/cookie-sanitizer/package.json +1 -1
  21. package/packages/cost-optimizer/package.json +1 -1
  22. package/packages/dependency-analyzer/package.json +1 -1
  23. package/packages/django-plugin/package.json +1 -1
  24. package/packages/doc-generator/package.json +1 -1
  25. package/packages/evaluation-engine/package.json +1 -1
  26. package/packages/evaluation-runner/package.json +1 -1
  27. package/packages/event-bus/package.json +1 -1
  28. package/packages/event-store/package.json +1 -1
  29. package/packages/experience-replay/package.json +1 -1
  30. package/packages/feedback-collector/package.json +1 -1
  31. package/packages/file-copy-helper/package.json +1 -1
  32. package/packages/framework-detector/package.json +1 -1
  33. package/packages/framework-plugin-sdk/package.json +1 -1
  34. package/packages/frappe-plugin/package.json +1 -1
  35. package/packages/generic-web-plugin/package.json +1 -1
  36. package/packages/health-monitor/package.json +1 -1
  37. package/packages/intent-analyzer/package.json +1 -1
  38. package/packages/jev-judge/package.json +1 -1
  39. package/packages/knowledge-graph/package.json +1 -1
  40. package/packages/knowledge-retrieval/package.json +1 -1
  41. package/packages/laravel-plugin/package.json +1 -1
  42. package/packages/learning-engine/package.json +1 -1
  43. package/packages/mcp-adapter/package.json +1 -1
  44. package/packages/memory-engine/package.json +1 -1
  45. package/packages/milestone-manager/package.json +1 -1
  46. package/packages/model-registry/package.json +1 -1
  47. package/packages/nextjs-plugin/package.json +1 -1
  48. package/packages/notification/package.json +1 -1
  49. package/packages/observability/package.json +1 -1
  50. package/packages/okf-indexer/package.json +1 -1
  51. package/packages/performance-optimizer/package.json +1 -1
  52. package/packages/privilege-broker/package.json +1 -1
  53. package/packages/project-analyzer/package.json +1 -1
  54. package/packages/project-bootstrap/package.json +1 -1
  55. package/packages/projection-engine/package.json +1 -1
  56. package/packages/prompt-compiler/package.json +1 -1
  57. package/packages/prompt-versioning/package.json +1 -1
  58. package/packages/provider-adapter-sdk/package.json +1 -1
  59. package/packages/provider-router/package.json +1 -1
  60. package/packages/provider-selector/package.json +1 -1
  61. package/packages/providers/package.json +1 -1
  62. package/packages/qdrant-skills/package.json +1 -1
  63. package/packages/quota-manager/package.json +1 -1
  64. package/packages/rate-limiter/package.json +1 -1
  65. package/packages/react-vite-plugin/package.json +1 -1
  66. package/packages/release-manager/package.json +1 -1
  67. package/packages/requirement-compiler/package.json +1 -1
  68. package/packages/runtime/package.json +1 -1
  69. package/packages/scheduler/package.json +1 -1
  70. package/packages/scheduler-adapter/package.json +1 -1
  71. package/packages/session/package.json +1 -1
  72. package/packages/session-api/package.json +1 -1
  73. package/packages/session-export/package.json +1 -1
  74. package/packages/shared-context/package.json +1 -1
  75. package/packages/skill-mcp-client/package.json +1 -1
  76. package/packages/skill-registry/package.json +1 -1
  77. package/packages/skills/package.json +1 -1
  78. package/packages/sprint-planner/package.json +1 -1
  79. package/packages/subscription-engine/package.json +1 -1
  80. package/packages/task-compiler/package.json +1 -1
  81. package/packages/tencentdb-memory/package.json +1 -1
  82. package/packages/tencentdb-sync/package.json +1 -1
  83. package/packages/test-data-generator/package.json +1 -1
  84. package/packages/test-generator/package.json +1 -1
  85. package/packages/todo-bd-sync/package.json +1 -1
  86. package/packages/token-estimation/package.json +1 -1
  87. package/packages/token-optimizer/package.json +1 -1
  88. package/packages/trajectory/package.json +1 -1
  89. package/packages/tui/dist/harness-header.d.ts +1 -1
  90. package/packages/tui/dist/harness-header.d.ts.map +1 -1
  91. package/packages/tui/dist/harness-header.js +2 -2
  92. package/packages/tui/dist/harness-header.js.map +1 -1
  93. package/packages/tui/package.json +1 -1
  94. package/packages/tui/src/harness-header.ts +2 -2
  95. package/packages/tui/test/harness-header.test.ts +310 -0
  96. package/packages/types/package.json +1 -1
  97. package/packages/workflow-events/package.json +1 -1
  98. package/packages/workspace-scanner/package.json +1 -1
  99. package/packages/worktree/package.json +1 -1
  100. package/packages/write-review/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/runtime",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "pi-harness-runtime — runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/scheduler",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "pi-harness-runtime — scheduler",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/scheduler-adapter",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Scheduler Adapter — cron, systemd, launchd, internal adapters for autonomous runtime (RFC-0101 §6)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/session",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Session management system for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/session-api",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/session-export",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/shared-context",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "pi-harness-runtime — shared-context",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/skill-mcp-client",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "MCP client for Skills SaaS backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/skill-registry",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Skill Registry for pi-harness-runtime — dynamic skill discovery and invocation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/skills",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "File-based skill system with pi.dev compatibility and Hermes self-improvement",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/sprint-planner",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "type": "module",
5
5
  "description": "Sprint planning engine for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/subscription-engine",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/task-compiler",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Task Compiler for pi-harness-runtime — produces deterministic task DAG from CompiledRequirement",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/tencentdb-memory",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "TencentDB Agent Memory client - sync skills to centralized knowledge base",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/tencentdb-sync",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Sync SKILL.md skills to TencentDB-Agent-Memory server (RFC-0105/0106)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/test-data-generator",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Test data generation for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/test-generator",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Auto-Test Generator — generate unit and E2E tests from source code (RFC-0013)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/todo-bd-sync",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Two-way sync between rpiv-todo overlay and bd issue tracker",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/token-estimation",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "pi-harness-runtime — token-estimation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/token-optimizer",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Token Budget Optimizer — maximize prompt value within token limits (RFC-0011)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/trajectory",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Trajectory capture for the write-review loop — persists cycle records for learning",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -19,7 +19,7 @@ export interface HarnessHeaderOptions {
19
19
  productName?: string;
20
20
  onboardingText?: string;
21
21
  }
22
- export declare function createHarnessHeader(_tui: TUI, theme: Theme, options: HarnessHeaderOptions): HarnessHeaderComponent;
22
+ export declare function createHarnessHeader(_tui: TUI, _theme: Theme, options: HarnessHeaderOptions): HarnessHeaderComponent;
23
23
  declare class HarnessHeaderComponent implements Component {
24
24
  private readonly theme;
25
25
  private readonly options;
@@ -1 +1 @@
1
- {"version":3,"file":"harness-header.d.ts","sourceRoot":"","sources":["../src/harness-header.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAI7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAC;AAwE7D,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,GAAG,EACT,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,oBAAoB,GAC3B,sBAAsB,CAExB;AAED,cAAM,sBAAuB,YAAW,SAAS;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,kBAAkB,CAAQ;IAElC,YAAY,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAQtD;IAID,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB/B;IAED,OAAO,CAAC,aAAa;IAoCrB,OAAO,CAAC,cAAc;IA4CtB,UAAU,IAAI,IAAI,CAGjB;IAID,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAInC;IAID,OAAO,IAAI,IAAI,CAEd;CACD;AAMD,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C"}
1
+ {"version":3,"file":"harness-header.d.ts","sourceRoot":"","sources":["../src/harness-header.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAI7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAC;AAwE7D,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,KAAK,EACb,OAAO,EAAE,oBAAoB,GAC3B,sBAAsB,CAExB;AAED,cAAM,sBAAuB,YAAW,SAAS;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,kBAAkB,CAAQ;IAElC,YAAY,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAQtD;IAID,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB/B;IAED,OAAO,CAAC,aAAa;IAoCrB,OAAO,CAAC,cAAc;IA4CtB,UAAU,IAAI,IAAI,CAGjB;IAID,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAInC;IAID,OAAO,IAAI,IAAI,CAEd;CACD;AAMD,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C"}
@@ -70,8 +70,8 @@ function logoLines(theme) {
70
70
  // ---------------------------------------------------------------------------
71
71
  const FALLBACK_LOGO_LINE0 = "Harness";
72
72
  const FALLBACK_LOGO_LINE1 = "";
73
- export function createHarnessHeader(_tui, theme, options) {
74
- return new HarnessHeaderComponent(theme, options);
73
+ export function createHarnessHeader(_tui, _theme, options) {
74
+ return new HarnessHeaderComponent(_theme, options);
75
75
  }
76
76
  class HarnessHeaderComponent {
77
77
  theme;
@@ -1 +1 @@
1
- {"version":3,"file":"harness-header.js","sourceRoot":"","sources":["../src/harness-header.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"harness-header.js","sourceRoot":"","sources":["../src/harness-header.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/tui",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "pi-harness-runtime — tui",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -97,10 +97,10 @@ export interface HarnessHeaderOptions {
97
97
 
98
98
  export function createHarnessHeader(
99
99
  _tui: TUI,
100
- theme: Theme,
100
+ _theme: Theme,
101
101
  options: HarnessHeaderOptions,
102
102
  ): HarnessHeaderComponent {
103
- return new HarnessHeaderComponent(theme, options);
103
+ return new HarnessHeaderComponent(_theme, options);
104
104
  }
105
105
 
106
106
  class HarnessHeaderComponent implements Component {
@@ -0,0 +1,310 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Unit tests for harness-header.ts
4
+ *
5
+ * Tests cover:
6
+ * - ANSI reset after every colored logo segment
7
+ * - Visible logo width (4 cells)
8
+ * - Compact/expanded expansion
9
+ * - Narrow-width rendering (no escape corruption)
10
+ * - No emoji in output
11
+ *
12
+ * Run with: bun test packages/tui/test/harness-header.test.ts
13
+ */
14
+
15
+ import { describe, it, expect, beforeAll } from "bun:test";
16
+ import { createHarnessHeader, stripAnsi, visibleWidth, type HarnessHeaderOptions } from "../src/harness-header.js";
17
+ import { initTheme, type Theme } from "@earendil-works/pi-coding-agent";
18
+
19
+ // ---------------------------------------------------------------------------
20
+ // Initialize pi-coding-agent theme (required for keyText/keyHint)
21
+ // ---------------------------------------------------------------------------
22
+
23
+ let testTheme: Theme;
24
+
25
+ beforeAll(() => {
26
+ // Initialize with dark theme so the global theme proxy works for keyText/keyHint
27
+ initTheme("dark");
28
+
29
+ // Create a minimal mock Theme for the harness header's logo rendering.
30
+ // This satisfies Theme.fg() without needing a real terminal.
31
+ // The global theme from initTheme() is used by keyText/keyHint internally.
32
+ testTheme = {
33
+ fg(color, text) {
34
+ // Return text with ANSI codes matching dark theme colors
35
+ const codes: Record<string, string> = {
36
+ accent: "\x1b[36m", // cyan for dark theme accent
37
+ success: "\x1b[32m", // green
38
+ muted: "\x1b[90m", // bright black (gray)
39
+ dim: "\x1b[90m",
40
+ text: "\x1b[37m", // white
41
+ };
42
+ return `${codes[color] ?? ""}${text}\x1b[39m`;
43
+ },
44
+ bg() { return ""; },
45
+ style() { return ""; },
46
+ bold() { return ""; },
47
+ italic() { return ""; },
48
+ underline() { return ""; },
49
+ inverse() { return ""; },
50
+ strikethrough() { return ""; },
51
+ getFgAnsi() { return ""; },
52
+ getBgAnsi() { return ""; },
53
+ getColorMode() { return "truecolor"; },
54
+ getThinkingBorderColor() { return () => ""; },
55
+ getBashModeBorderColor() { return () => ""; },
56
+ get appearance() { return "dark"; },
57
+ get colors() { return {}; },
58
+ } as unknown as Theme;
59
+ });
60
+
61
+ // ---------------------------------------------------------------------------
62
+ // Test data
63
+ // ---------------------------------------------------------------------------
64
+
65
+ const TEST_OPTIONS: HarnessHeaderOptions = {
66
+ version: "1.0.0",
67
+ productName: "Harness",
68
+ onboardingText: "Test onboarding.",
69
+ };
70
+
71
+ function createMockTui() {
72
+ return {} as object;
73
+ }
74
+
75
+ // ---------------------------------------------------------------------------
76
+ // Tests
77
+ // ---------------------------------------------------------------------------
78
+
79
+ describe("visibleWidth", () => {
80
+ it("returns 0 for empty string", () => {
81
+ expect(visibleWidth("")).toBe(0);
82
+ });
83
+
84
+ it("returns correct length for plain text", () => {
85
+ expect(visibleWidth("hello")).toBe(5);
86
+ });
87
+
88
+ it("subtracts ANSI escape sequences from length", () => {
89
+ const colored = "\x1b[31mhello\x1b[39m";
90
+ expect(visibleWidth(colored)).toBe(5);
91
+ });
92
+
93
+ it("handles multiple escape sequences", () => {
94
+ const colored = "\x1b[1m\x1b[31mbold red\x1b[39m\x1b[22m";
95
+ // "bold red" = 9 chars visible, minus 1 = 8 (the space in "bold red")
96
+ expect(visibleWidth(colored)).toBe(8);
97
+ });
98
+ });
99
+
100
+ describe("stripAnsi", () => {
101
+ it("returns empty string for empty input", () => {
102
+ expect(stripAnsi("")).toBe("");
103
+ });
104
+
105
+ it("returns original string if no escapes", () => {
106
+ expect(stripAnsi("hello world")).toBe("hello world");
107
+ });
108
+
109
+ it("strips all ANSI escapes", () => {
110
+ const colored = "\x1b[1m\x1b[31mbold red\x1b[39m\x1b[22m";
111
+ expect(stripAnsi(colored)).toBe("bold red");
112
+ });
113
+ });
114
+
115
+ describe("logo segment ANSI resets", () => {
116
+ it("all ANSI sequences in output are complete (balanced opens/closes)", () => {
117
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
118
+ const lines = header.render(80);
119
+
120
+ for (const line of lines) {
121
+ const csiStarts = (line.match(/\x1b\[/g) || []).length;
122
+ const completeSeqs = (line.match(/\x1b\[[0-9;]*[a-zA-Z]/g) || []).length;
123
+ expect(completeSeqs).toBe(csiStarts);
124
+ }
125
+ });
126
+ });
127
+
128
+ describe("logo visible width", () => {
129
+ it("logo occupies exactly 4 visible cells per row", () => {
130
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
131
+ const lines = header.render(80);
132
+
133
+ const logoLine = lines.find((l) => stripAnsi(l).includes("▀") || stripAnsi(l).includes("█"));
134
+ expect(logoLine).toBeDefined();
135
+
136
+ const plain = stripAnsi(logoLine!);
137
+ const logoMatch = plain.match(/^([▀▄█]+)/);
138
+ expect(logoMatch).not.toBeNull();
139
+ expect(logoMatch[1].length).toBe(4);
140
+ });
141
+
142
+ it("logo renders on exactly 2 rows", () => {
143
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
144
+ const lines = header.render(80);
145
+
146
+ const logoLines = lines.filter((l) => stripAnsi(l).includes("▀") || stripAnsi(l).includes("█"));
147
+ expect(logoLines.length).toBe(2);
148
+ });
149
+ });
150
+
151
+ describe("setExpanded", () => {
152
+ it("starts in compact mode", () => {
153
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
154
+ const compactLines = header.render(80);
155
+
156
+ const compactText = stripAnsi(compactLines.join("\n"));
157
+ // keyHint returns key name + description; check for the interrupt key (escape)
158
+ expect(compactText.toLowerCase()).toContain("interrupt");
159
+ });
160
+
161
+ it("switches to expanded mode when setExpanded(true)", () => {
162
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
163
+
164
+ header.setExpanded(true);
165
+ const expandedLines = header.render(80);
166
+ const expandedText = stripAnsi(expandedLines.join("\n"));
167
+
168
+ expect(expandedText.toLowerCase()).toContain("abort");
169
+ expect(expandedText.toLowerCase()).toContain("clear");
170
+ expect(expandedText.toLowerCase()).toContain("slash");
171
+ });
172
+
173
+ it("switches back to compact when setExpanded(false)", () => {
174
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
175
+
176
+ header.setExpanded(true);
177
+ header.setExpanded(false);
178
+ const collapsedLines = header.render(80);
179
+
180
+ const hasDotSeparator = collapsedLines.some((l) => stripAnsi(l).includes(" · "));
181
+ expect(hasDotSeparator).toBe(true);
182
+ });
183
+
184
+ it("idempotent when setting same state twice", () => {
185
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
186
+
187
+ header.setExpanded(true);
188
+ const lines1 = header.render(80);
189
+ header.setExpanded(true);
190
+ const lines2 = header.render(80);
191
+
192
+ expect(lines1).toEqual(lines2);
193
+ });
194
+ });
195
+
196
+ describe("narrow width rendering", () => {
197
+ it("does not split ANSI escape sequences", () => {
198
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
199
+
200
+ const widths = [20, 40, 60, 80, 120];
201
+
202
+ for (const width of widths) {
203
+ const lines = header.render(width);
204
+ for (const line of lines) {
205
+ const incompletePattern = /\x1b\[[0-9;]*[^\x1b\x5bm]?$/;
206
+ expect(incompletePattern.test(line)).toBe(false);
207
+ }
208
+ }
209
+ });
210
+
211
+ it("renders without error at width 1", () => {
212
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
213
+
214
+ expect(() => header.render(1)).not.toThrow();
215
+ });
216
+ });
217
+
218
+ describe("no emoji", () => {
219
+ it("output contains no emoji code points", () => {
220
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
221
+ const lines = header.render(80);
222
+
223
+ const allText = lines.join("\n");
224
+
225
+ const emojiRanges = [
226
+ /[\u{1F300}-\u{1F9FF}]/u,
227
+ /[\u{2600}-\u{26FF}]/u,
228
+ /[\u{2700}-\u{27BF}]/u,
229
+ /[\u{1F600}-\u{1F64F}]/u,
230
+ /[\u{1F680}-\u{1F6FF}]/u,
231
+ ];
232
+
233
+ for (const range of emojiRanges) {
234
+ const matches = allText.match(range);
235
+ expect(matches).toBeNull();
236
+ }
237
+ });
238
+
239
+ it("uses only allowed Unicode block characters", () => {
240
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
241
+ const lines = header.render(80);
242
+
243
+ for (const line of lines) {
244
+ const plain = stripAnsi(line);
245
+
246
+ for (const char of plain) {
247
+ const code = char.charCodeAt(0);
248
+
249
+ if (code >= 0x20 && code <= 0x7e) continue;
250
+ if (code === 0x20) continue;
251
+ if (char === "▀" || char === "▄" || char === "█") continue;
252
+ if (char === "\n") continue;
253
+ if (char === "·") continue; // middle dot U+00B7 used in shortcuts
254
+
255
+ expect(`Unexpected character: ${char} (U+${code.toString(16).padStart(4, "0")})`).toBe("");
256
+ }
257
+ }
258
+ });
259
+ });
260
+
261
+ describe("version display", () => {
262
+ it("displays correct version from options", () => {
263
+ const customOptions: HarnessHeaderOptions = {
264
+ ...TEST_OPTIONS,
265
+ version: "2.5.10-test",
266
+ };
267
+ const header = createHarnessHeader(createMockTui(), testTheme, customOptions);
268
+ const lines = header.render(80);
269
+
270
+ const text = stripAnsi(lines.join("\n"));
271
+ expect(text).toContain("v2.5.10-test");
272
+ });
273
+
274
+ it("defaults product name to 'Harness'", () => {
275
+ const optionsWithoutName: HarnessHeaderOptions = {
276
+ version: "1.0.0",
277
+ };
278
+ const header = createHarnessHeader(createMockTui(), testTheme, optionsWithoutName);
279
+ const lines = header.render(80);
280
+
281
+ const text = stripAnsi(lines.join("\n"));
282
+ expect(text).toContain("Harness");
283
+ });
284
+ });
285
+
286
+ describe("dynamic key hints", () => {
287
+ it("renders hint text for shortcuts", () => {
288
+ const header = createHarnessHeader(createMockTui(), testTheme, TEST_OPTIONS);
289
+ const lines = header.render(80);
290
+
291
+ const text = stripAnsi(lines.join("\n"));
292
+
293
+ expect(text.toLowerCase()).toContain("interrupt");
294
+ expect(text.toLowerCase()).toContain("command");
295
+ });
296
+ });
297
+
298
+ describe("onboarding text", () => {
299
+ it("displays custom onboarding text", () => {
300
+ const customOptions: HarnessHeaderOptions = {
301
+ ...TEST_OPTIONS,
302
+ onboardingText: "Custom onboarding message.",
303
+ };
304
+ const header = createHarnessHeader(createMockTui(), testTheme, customOptions);
305
+ const lines = header.render(80);
306
+
307
+ const text = stripAnsi(lines.join("\n"));
308
+ expect(text).toContain("Custom onboarding message.");
309
+ });
310
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/types",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Shared TypeScript types for pi-harness-runtime packages",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/workflow-events",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/workspace-scanner",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/worktree",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "pi-harness-runtime — worktree",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/write-review",
3
- "version": "1.1.135",
3
+ "version": "1.1.136",
4
4
  "description": "Two-agent write-review loop with blackboard coordination",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",