pi-harness-runtime 1.1.50 → 1.1.77

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 (202) hide show
  1. package/CHANGELOG.md +30 -9
  2. package/README.md +119 -0
  3. package/harness/langchain/agents.d.ts +143 -0
  4. package/harness/langchain/agents.test.d.ts +2 -0
  5. package/harness/langchain/agents.ts +196 -13
  6. package/harness/langchain/checkpointer.d.ts +48 -0
  7. package/harness/langchain/checkpointer.test.d.ts +8 -0
  8. package/harness/langchain/cron-cli.d.ts +12 -0
  9. package/harness/langchain/cron-cli.ts +169 -0
  10. package/harness/langchain/daemon.d.ts +161 -0
  11. package/harness/langchain/daemon.test.d.ts +11 -0
  12. package/harness/langchain/daemon.test.ts +3 -1
  13. package/harness/langchain/daemon.ts +230 -12
  14. package/harness/langchain/file-tools.d.ts +97 -0
  15. package/harness/langchain/file-tools.ts +14 -6
  16. package/harness/langchain/graph.d.ts +706 -0
  17. package/harness/langchain/graph.ts +158 -25
  18. package/harness/langchain/model-router.d.ts +63 -0
  19. package/harness/langchain/model-router.test.d.ts +2 -0
  20. package/harness/langchain/model-router.test.ts +191 -0
  21. package/harness/langchain/model-router.ts +188 -0
  22. package/harness/langchain/models.d.ts +72 -0
  23. package/harness/langchain/models.ts +111 -49
  24. package/harness/langchain/ping-pong-middleware.d.ts +28 -0
  25. package/harness/langchain/ping-pong-middleware.test.d.ts +2 -0
  26. package/harness/langchain/ping-pong-middleware.test.ts +69 -0
  27. package/harness/langchain/ping-pong-middleware.ts +204 -0
  28. package/harness/langchain/run.d.ts +15 -0
  29. package/harness/langchain/run.ts +15 -3
  30. package/harness/langchain/scoreboard.test.d.ts +13 -0
  31. package/harness/langchain/scoreboard.test.ts +23 -1
  32. package/harness/langchain/status-line.d.ts +91 -0
  33. package/harness/langchain/status-line.test.d.ts +8 -0
  34. package/harness/langchain/surge.d.ts +103 -0
  35. package/harness/langchain/surge.test.d.ts +10 -0
  36. package/harness/langchain/surge.test.ts +179 -0
  37. package/harness/langchain/surge.ts +188 -19
  38. package/harness/langchain/widget.d.ts +105 -0
  39. package/harness/langchain/widget.test.d.ts +8 -0
  40. package/harness/ssh-detach-interceptor.test.ts +263 -0
  41. package/harness/ssh-detach-interceptor.ts +438 -0
  42. package/index.ts +212 -47
  43. package/package.json +4 -2
  44. package/packages/a2a-adapter/package.json +1 -1
  45. package/packages/architecture-generator/package.json +1 -1
  46. package/packages/auth/package.json +1 -1
  47. package/packages/autonomous-refactor/package.json +1 -1
  48. package/packages/autonomous-runtime/package.json +1 -1
  49. package/packages/cache-strategy/package.json +1 -1
  50. package/packages/capability-registry/package.json +1 -1
  51. package/packages/checkpoint/package.json +1 -1
  52. package/packages/cli-plugin-sdk/package.json +1 -1
  53. package/packages/clipboard/package.json +1 -1
  54. package/packages/clipboard-plugin/package.json +1 -1
  55. package/packages/code-generation/package.json +1 -1
  56. package/packages/code-review/package.json +1 -1
  57. package/packages/codex-adapter/package.json +1 -1
  58. package/packages/config-capture/package.json +1 -1
  59. package/packages/context-compiler/package.json +1 -1
  60. package/packages/context-discovery/package.json +1 -1
  61. package/packages/context-manager/package.json +1 -1
  62. package/packages/cookie-sanitizer/package.json +1 -1
  63. package/packages/cost-optimizer/package.json +1 -1
  64. package/packages/dependency-analyzer/package.json +1 -1
  65. package/packages/django-plugin/package.json +1 -1
  66. package/packages/doc-generator/package.json +1 -1
  67. package/packages/evaluation-engine/package.json +1 -1
  68. package/packages/evaluation-runner/package.json +1 -1
  69. package/packages/event-bus/package.json +1 -1
  70. package/packages/event-store/package.json +1 -1
  71. package/packages/experience-replay/package.json +1 -1
  72. package/packages/feedback-collector/package.json +1 -1
  73. package/packages/file-copy-helper/package.json +1 -1
  74. package/packages/framework-detector/package.json +1 -1
  75. package/packages/framework-plugin-sdk/package.json +1 -1
  76. package/packages/frappe-plugin/package.json +1 -1
  77. package/packages/generic-web-plugin/package.json +1 -1
  78. package/packages/health-monitor/package.json +1 -1
  79. package/packages/intent-analyzer/dist/src/index.d.ts +2 -0
  80. package/packages/intent-analyzer/dist/src/index.d.ts.map +1 -1
  81. package/packages/intent-analyzer/dist/src/index.js +1 -0
  82. package/packages/intent-analyzer/dist/src/index.js.map +1 -1
  83. package/packages/intent-analyzer/dist/src/ping-pong.d.ts +56 -0
  84. package/packages/intent-analyzer/dist/src/ping-pong.d.ts.map +1 -0
  85. package/packages/intent-analyzer/dist/src/ping-pong.js +286 -0
  86. package/packages/intent-analyzer/dist/src/ping-pong.js.map +1 -0
  87. package/packages/intent-analyzer/package.json +1 -1
  88. package/packages/intent-analyzer/src/index.ts +13 -0
  89. package/packages/intent-analyzer/src/ping-pong.ts +387 -0
  90. package/packages/intent-analyzer/test/ping-pong.test.ts +96 -0
  91. package/packages/jev-judge/README.md +234 -0
  92. package/packages/jev-judge/dist/decision-engine.d.ts +100 -0
  93. package/packages/jev-judge/dist/decision-engine.d.ts.map +1 -0
  94. package/packages/jev-judge/dist/decision-engine.js +151 -0
  95. package/packages/jev-judge/dist/decision-engine.js.map +1 -0
  96. package/packages/jev-judge/dist/e2e-judge.d.ts +61 -0
  97. package/packages/jev-judge/dist/e2e-judge.d.ts.map +1 -0
  98. package/packages/jev-judge/dist/e2e-judge.js +268 -0
  99. package/packages/jev-judge/dist/e2e-judge.js.map +1 -0
  100. package/packages/jev-judge/dist/flaky-detector.d.ts +34 -0
  101. package/packages/jev-judge/dist/flaky-detector.d.ts.map +1 -0
  102. package/packages/jev-judge/dist/flaky-detector.js +154 -0
  103. package/packages/jev-judge/dist/flaky-detector.js.map +1 -0
  104. package/packages/jev-judge/dist/index.d.ts +77 -0
  105. package/packages/jev-judge/dist/index.d.ts.map +1 -0
  106. package/packages/jev-judge/dist/index.js +271 -0
  107. package/packages/jev-judge/dist/index.js.map +1 -0
  108. package/packages/jev-judge/dist/types.d.ts +97 -0
  109. package/packages/jev-judge/dist/types.d.ts.map +1 -0
  110. package/packages/jev-judge/dist/types.js +8 -0
  111. package/packages/jev-judge/dist/types.js.map +1 -0
  112. package/packages/jev-judge/package.json +46 -0
  113. package/packages/jev-judge/src/decision-engine.ts +231 -0
  114. package/packages/jev-judge/src/e2e-judge.ts +364 -0
  115. package/packages/jev-judge/src/flaky-detector.ts +190 -0
  116. package/packages/jev-judge/src/index.ts +345 -0
  117. package/packages/jev-judge/src/types.ts +131 -0
  118. package/packages/knowledge-graph/package.json +1 -1
  119. package/packages/knowledge-retrieval/package.json +1 -1
  120. package/packages/laravel-plugin/package.json +1 -1
  121. package/packages/learning-engine/package.json +1 -1
  122. package/packages/mcp-adapter/package.json +1 -1
  123. package/packages/memory-engine/package.json +1 -1
  124. package/packages/milestone-manager/package.json +1 -1
  125. package/packages/model-registry/package.json +1 -1
  126. package/packages/nextjs-plugin/package.json +1 -1
  127. package/packages/notification/package.json +1 -1
  128. package/packages/observability/package.json +1 -1
  129. package/packages/okf-indexer/package.json +1 -1
  130. package/packages/performance-optimizer/package.json +1 -1
  131. package/packages/privilege-broker/package.json +1 -1
  132. package/packages/project-analyzer/package.json +1 -1
  133. package/packages/project-bootstrap/package.json +1 -1
  134. package/packages/projection-engine/package.json +1 -1
  135. package/packages/prompt-compiler/package.json +1 -1
  136. package/packages/prompt-versioning/package.json +1 -1
  137. package/packages/provider-adapter-sdk/package.json +1 -1
  138. package/packages/provider-router/package.json +1 -1
  139. package/packages/provider-selector/package.json +1 -1
  140. package/packages/providers/package.json +1 -1
  141. package/packages/quota-manager/package.json +1 -1
  142. package/packages/rate-limiter/package.json +1 -1
  143. package/packages/react-vite-plugin/package.json +1 -1
  144. package/packages/release-manager/package.json +1 -1
  145. package/packages/requirement-compiler/package.json +1 -1
  146. package/packages/runtime/package.json +1 -1
  147. package/packages/scheduler/package.json +1 -1
  148. package/packages/scheduler-adapter/package.json +1 -1
  149. package/packages/session/package.json +1 -1
  150. package/packages/session-api/package.json +1 -1
  151. package/packages/session-export/package.json +1 -1
  152. package/packages/shared-context/package.json +1 -1
  153. package/packages/skill-mcp-client/package.json +1 -1
  154. package/packages/skill-registry/package.json +1 -1
  155. package/packages/sprint-planner/package.json +1 -1
  156. package/packages/subscription-engine/package.json +1 -1
  157. package/packages/task-compiler/package.json +1 -1
  158. package/packages/tencentdb-memory/package.json +1 -1
  159. package/packages/tencentdb-sync/package.json +1 -1
  160. package/packages/test-data-generator/package.json +1 -1
  161. package/packages/test-generator/package.json +1 -1
  162. package/packages/todo-bd-sync/README.md +71 -0
  163. package/packages/todo-bd-sync/package.json +1 -1
  164. package/packages/todo-bd-sync/src/extension.ts +16 -1
  165. package/packages/token-estimation/package.json +1 -1
  166. package/packages/token-optimizer/package.json +1 -1
  167. package/packages/trajectory/dist/src/approved-patterns.d.ts +51 -0
  168. package/packages/trajectory/dist/src/approved-patterns.d.ts.map +1 -0
  169. package/packages/trajectory/dist/src/approved-patterns.js +134 -0
  170. package/packages/trajectory/dist/src/approved-patterns.js.map +1 -0
  171. package/packages/trajectory/dist/src/index.d.ts +13 -0
  172. package/packages/trajectory/dist/src/index.d.ts.map +1 -0
  173. package/packages/trajectory/dist/src/index.js +12 -0
  174. package/packages/trajectory/dist/src/index.js.map +1 -0
  175. package/packages/trajectory/dist/src/store.d.ts +69 -0
  176. package/packages/trajectory/dist/src/store.d.ts.map +1 -0
  177. package/packages/trajectory/dist/src/store.js +253 -0
  178. package/packages/trajectory/dist/src/store.js.map +1 -0
  179. package/packages/trajectory/dist/src/types.d.ts +73 -0
  180. package/packages/trajectory/dist/src/types.d.ts.map +1 -0
  181. package/packages/trajectory/dist/src/types.js +9 -0
  182. package/packages/trajectory/dist/src/types.js.map +1 -0
  183. package/packages/trajectory/dist/test/store.test.d.ts +2 -0
  184. package/packages/trajectory/dist/test/store.test.d.ts.map +1 -0
  185. package/packages/trajectory/dist/test/store.test.js +228 -0
  186. package/packages/trajectory/dist/test/store.test.js.map +1 -0
  187. package/packages/trajectory/package.json +29 -0
  188. package/packages/trajectory/src/approved-patterns.ts +180 -0
  189. package/packages/trajectory/src/index.ts +26 -0
  190. package/packages/trajectory/src/store.ts +285 -0
  191. package/packages/trajectory/src/types.ts +84 -0
  192. package/packages/trajectory/test/store.test.d.ts +2 -0
  193. package/packages/trajectory/test/store.test.ts +250 -0
  194. package/packages/tui/package.json +1 -1
  195. package/packages/types/package.json +1 -1
  196. package/packages/workflow-events/package.json +1 -1
  197. package/packages/workspace-scanner/package.json +1 -1
  198. package/packages/worktree/package.json +1 -1
  199. package/packages/write-review/package.json +1 -1
  200. package/packages/write-review/src/blackboard.ts +24 -1
  201. package/packages/write-review/src/types.ts +13 -0
  202. package/skills/harness-runtime/SKILL.md +67 -4
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Cron task management CLI.
3
+ *
4
+ * Usage:
5
+ * bun harness/langchain/run.ts cron add <schedule> <request>
6
+ * bun harness/langchain/run.ts cron list
7
+ * bun harness/langchain/run.ts cron rm <task-id>
8
+ *
9
+ * Schedules: every-5m, every-10m, every-30m, hourly, daily, weekly
10
+ */
11
+
12
+ import { readdirSync, readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "node:fs";
13
+ import { join } from "node:path";
14
+
15
+ const SCHEDULES = ["every-5m", "every-10m", "every-30m", "hourly", "daily", "weekly"] as const;
16
+ type Schedule = typeof SCHEDULES[number];
17
+
18
+ function getCronDir(workspace: string): string {
19
+ return join(workspace, ".cron-tasks");
20
+ }
21
+
22
+ function taskIdFromPath(schedule: string, filename: string): string {
23
+ return `${schedule}:${filename.replace(/\.json$/, "")}`;
24
+ }
25
+
26
+ function parseTaskId(id: string): { schedule: string; name: string } | null {
27
+ const colon = id.indexOf(":");
28
+ if (colon === -1) return null;
29
+ return { schedule: id.slice(0, colon), name: id.slice(colon + 1) };
30
+ }
31
+
32
+ function loadWorkspace(): string {
33
+ // Dynamically import to avoid a hard dep on herdr-bus when not needed
34
+ try {
35
+ const { getHerdrWorkspace } = require("../../packages/event-bus/src/herdr-bus.js");
36
+ return getHerdrWorkspace();
37
+ } catch {
38
+ const home = process.env.HOME ?? "/tmp";
39
+ return join(home, ".pi-harness");
40
+ }
41
+ }
42
+
43
+ export async function runCron(argv: string[]): Promise<void> {
44
+ const [subcommand, ...rest] = argv;
45
+
46
+ if (!subcommand) {
47
+ printCronHelp();
48
+ process.exit(0);
49
+ }
50
+
51
+ const workspace = loadWorkspace();
52
+ const cronDir = getCronDir(workspace);
53
+
54
+ switch (subcommand) {
55
+ case "add": {
56
+ const [schedule, ...requestParts] = rest;
57
+ if (!schedule || requestParts.length === 0) {
58
+ console.error("Usage: bd cron add <schedule> <request>");
59
+ console.error(`Schedules: ${SCHEDULES.join(", ")}`);
60
+ process.exit(1);
61
+ }
62
+ if (!SCHEDULES.includes(schedule as Schedule)) {
63
+ console.error(`Unknown schedule: ${schedule}`);
64
+ console.error(`Valid: ${SCHEDULES.join(", ")}`);
65
+ process.exit(1);
66
+ }
67
+ const request = requestParts.join(" ");
68
+ const taskId = `task-${Date.now()}`;
69
+ const taskPath = join(cronDir, schedule, `${taskId}.json`);
70
+
71
+ if (!existsSync(cronDir)) mkdirSync(cronDir, { recursive: true });
72
+ if (!existsSync(join(cronDir, schedule))) mkdirSync(join(cronDir, schedule), { recursive: true });
73
+
74
+ writeFileSync(taskPath, JSON.stringify({ request, enabled: true }, null, 2));
75
+ console.log(`[cron] Added task ${schedule}:${taskId}`);
76
+ console.log(` Request: ${request.slice(0, 80)}${request.length > 80 ? "…" : ""}`);
77
+ break;
78
+ }
79
+
80
+ case "list": {
81
+ if (!existsSync(cronDir)) {
82
+ console.log("No cron tasks configured.");
83
+ return;
84
+ }
85
+ let found = false;
86
+ for (const schedule of SCHEDULES) {
87
+ const schedDir = join(cronDir, schedule);
88
+ if (!existsSync(schedDir)) continue;
89
+ const files = readdirSync(schedDir).filter((f) => f.endsWith(".json"));
90
+ for (const file of files) {
91
+ found = true;
92
+ let data: { request?: string; enabled?: boolean };
93
+ try {
94
+ data = JSON.parse(readFileSync(join(schedDir, file), "utf8"));
95
+ } catch {
96
+ continue;
97
+ }
98
+ const id = taskIdFromPath(schedule, file);
99
+ const status = data.enabled === false ? " [PAUSED]" : "";
100
+ const req = (data.request ?? "").slice(0, 70);
101
+ console.log(` ${id}${status}`);
102
+ console.log(` → ${req}${data.request && data.request.length > 70 ? "…" : ""}`);
103
+ }
104
+ }
105
+ if (!found) console.log("No cron tasks configured.");
106
+ break;
107
+ }
108
+
109
+ case "rm": {
110
+ const [taskId] = rest;
111
+ if (!taskId) {
112
+ console.error("Usage: bd cron rm <task-id>");
113
+ console.error("Run 'bd cron list' to see task IDs.");
114
+ process.exit(1);
115
+ }
116
+ const parsed = parseTaskId(taskId);
117
+ if (!parsed) {
118
+ console.error(`Invalid task ID format: ${taskId}`);
119
+ console.error("Expected: <schedule>:<task-name> (e.g. hourly:task-1234)");
120
+ process.exit(1);
121
+ }
122
+ const taskPath = join(cronDir, parsed.schedule, `${parsed.name}.json`);
123
+ if (!existsSync(taskPath)) {
124
+ console.error(`Task not found: ${taskId}`);
125
+ process.exit(1);
126
+ }
127
+ unlinkSync(taskPath);
128
+ console.log(`[cron] Removed ${taskId}`);
129
+ break;
130
+ }
131
+
132
+ case "help": {
133
+ printCronHelp();
134
+ break;
135
+ }
136
+
137
+ default: {
138
+ console.error(`Unknown subcommand: ${subcommand}`);
139
+ printCronHelp();
140
+ process.exit(1);
141
+ }
142
+ }
143
+ }
144
+
145
+ function printCronHelp(): void {
146
+ console.log(`\
147
+ Cron task management.
148
+
149
+ Usage: bd cron <subcommand> [args]
150
+
151
+ Subcommands:
152
+ add <schedule> <request>
153
+ Schedule a task. Example:
154
+ bd cron add hourly "Check for outdated dependencies"
155
+
156
+ Valid schedules: ${SCHEDULES.join(", ")}
157
+
158
+ list
159
+ Show all scheduled tasks.
160
+
161
+ rm <task-id>
162
+ Remove a task. Use 'bd cron list' to find the task ID.
163
+
164
+ Examples:
165
+ bd cron add daily "Sync docs to wiki"
166
+ bd cron list
167
+ bd cron rm every-5m:task-1234567890
168
+ `);
169
+ }
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Loop Daemon — Auto-triggered write-review loop.
3
+ *
4
+ * Design philosophy: Human *on* the loop, not *in* the loop.
5
+ * The daemon starts itself, routes itself, and only notifies the human at gates
6
+ * (approval, escalation, blocked). No human ever acts as the message bus between
7
+ * GPT and MiniMax.
8
+ *
9
+ * Architecture:
10
+ *
11
+ * TRIGGERS
12
+ * bd task created ─┐
13
+ * inbox file ─┤
14
+ * bus event ─┼──► watcher (poll) ─► LeaseManager.claim ─► LangGraph.run
15
+ * cron (stub) ─┘ │
16
+ * │ publish (loop-events.ts) ─► HerdrEventBus
17
+ * │ gates ─► NotificationCenter
18
+ *
19
+ * Milestones:
20
+ * M1 — Daemon skeleton + inbox/bus watchers
21
+ * M2 — Runner integration: LeaseManager → buildWriteReviewLoop → publish
22
+ * M3 — Gates & notifications
23
+ * M4 — Robustness: surge/529 auto-resume + retry backoff, stale-lease, bd-tasks
24
+ * watcher (worker heartbeats: still TODO)
25
+ *
26
+ * Wiki: wiki/auto-trigger-multi-agent.md
27
+ */
28
+ import type { ApprovalClass } from "../../packages/autonomous-runtime/src/types.js";
29
+ import { type SurgePolicy } from "./surge.js";
30
+ import type { LoopWidget } from "./widget.js";
31
+ import { type LoopDeps } from "./graph.js";
32
+ export type TriggerSource = "bd-tasks" | "inbox" | "bus" | "cron";
33
+ export type ApprovalPolicy = "never" | "on_blocked" | "on_class" | "always";
34
+ export interface DaemonConfig {
35
+ /** Agent/worker identity. Default: "loop-daemon" */
36
+ agentId?: string;
37
+ /** Trigger poll interval in ms. Default: 2000 */
38
+ pollMs?: number;
39
+ /** Max write-review rounds per task. Default: 3 */
40
+ maxIterations?: number;
41
+ /** Human gate policy. Default: "never" */
42
+ approvalPolicy?: ApprovalPolicy;
43
+ /** Use deterministic stubs (no API keys). Default: false */
44
+ dryRun?: boolean;
45
+ /** Abort loop if cumulative cost exceeds this. Default: no cap */
46
+ costCapUsd?: number;
47
+ /** Surge (529/overloaded) retry policy. Default: 3→6→12 min, max 5 pauses */
48
+ surgePolicy?: Partial<SurgePolicy>;
49
+ /** Kill a task if it runs longer than this (ms). Prevents permanent freezes. Default: no timeout */
50
+ taskTimeoutMs?: number;
51
+ /** Use persistent file-based checkpointer for crash-resume. Default: false (MemorySaver). */
52
+ checkpointer?: boolean | string;
53
+ /** @internal Test injection — overrides dryRun/real deps entirely */
54
+ deps?: LoopDeps;
55
+ /** Which watchers to enable. Default: ["inbox", "bus"] */
56
+ sources?: TriggerSource[];
57
+ /** Herdr workspace override. Default: from herdr-bus */
58
+ workspace?: string;
59
+ /** NotificationCenter config */
60
+ notificationConfig?: {
61
+ telegramBotToken?: string;
62
+ telegramChatId?: string;
63
+ ntfyTopic?: string;
64
+ webhookUrl?: string;
65
+ };
66
+ /**
67
+ * Path to a tunnel-start script (e.g. tailscale-tunnel.sh).
68
+ * If set, the daemon health-checks the tunnel before each task and
69
+ * auto-restarts it if the target port is unreachable.
70
+ *
71
+ * Set to "auto" to search for scripts/tailscale-tunnel.sh in the
72
+ * project root, or give an absolute path.
73
+ * Default: none (no tunnel management)
74
+ */
75
+ tunnelCommand?: string;
76
+ /**
77
+ * Optional widget for TUI / status-line display.
78
+ * When set, the daemon updates the widget at each loop transition
79
+ * (mirrors pi-lens footer style: !NW ●ME).
80
+ */
81
+ widget?: LoopWidget;
82
+ }
83
+ export interface TriggeredTask {
84
+ /** Stable id — derived from the trigger source */
85
+ taskId: string;
86
+ /** Human-readable task description */
87
+ request: string;
88
+ /** How the task arrived */
89
+ source: TriggerSource;
90
+ /** Optional approval class from task metadata */
91
+ approvalClass?: ApprovalClass;
92
+ /** ISO timestamp of when the trigger was observed */
93
+ triggeredAt: string;
94
+ }
95
+ export interface TaskProposedPayload {
96
+ taskId: string;
97
+ request: string;
98
+ approvalClass?: ApprovalClass;
99
+ }
100
+ /** Write an ack file (used by tests / manual approval). */
101
+ export declare function writeAck(inboxDir: string, taskId: string, decision: "approved" | "denied"): void;
102
+ /**
103
+ * The main daemon class. Coordinates watchers, leasing, loop execution, and
104
+ * notifications.
105
+ *
106
+ * Usage:
107
+ * const daemon = new LoopDaemon({ dryRun: true, sources: ["inbox", "bus"] });
108
+ * daemon.start();
109
+ * // ... daemon runs in the background ...
110
+ * daemon.stop();
111
+ */
112
+ export declare class LoopDaemon {
113
+ private readonly config;
114
+ private readonly agentId;
115
+ private readonly leaseManager;
116
+ private readonly bus;
117
+ private readonly notificationCenter;
118
+ private readonly inboxDir;
119
+ private readonly inboxWatcher;
120
+ private readonly busWatcher;
121
+ private readonly bdWatcher;
122
+ private readonly cronWatcher;
123
+ private readonly tunnelMonitor;
124
+ private readonly statusLine;
125
+ private readonly widget;
126
+ /** Currently running tasks (taskId → RunningTask) */
127
+ private readonly running;
128
+ private stopped;
129
+ constructor(config?: DaemonConfig);
130
+ /** Start the daemon — begins watching all configured sources. */
131
+ start(): void;
132
+ /** Stop all watchers and release all held leases. */
133
+ stop(): void;
134
+ /** Returns true if stop() has been called. */
135
+ get isStopped(): boolean;
136
+ private _onTriggered;
137
+ private _runTask;
138
+ private _publishTransition;
139
+ /**
140
+ * Drive the TUI widget through loop transitions.
141
+ * Called from onStep within _runTask.
142
+ */
143
+ private _updateWidget;
144
+ private _reviewReportPath;
145
+ private _releaseLease;
146
+ private _notifyHumanReviewNeeded;
147
+ private _closeBdIssue;
148
+ private _notifyReadyForClient;
149
+ /**
150
+ * Write a loop-completion event to ~/.pi-harness-runtime/loop-completions/.
151
+ * The harness extension (pi-harness-runtime package in the pi-coding-agent process)
152
+ * watches this directory and calls pi.sendUserMessage() to update the TUI todo count.
153
+ *
154
+ * File format:
155
+ * <taskId>.json {"taskId","request","verdict","iterations","finishedAt"}
156
+ */
157
+ private _writeLoopCompletion;
158
+ private _buildChannels;
159
+ }
160
+ export { LoopDaemon as default };
161
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Daemon Acceptance Tests (T1–T7)
3
+ *
4
+ * All tests run with dryRun=true — no API keys needed.
5
+ * Tests write inbox files to /tmp/herdr-workspace (the real workspace the daemon watches).
6
+ *
7
+ * Run:
8
+ * bun test harness/langchain/daemon.test.ts
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=daemon.test.d.ts.map
@@ -316,7 +316,9 @@ describe("T6 — maxIterations cap", () => {
316
316
  review: async () => ({
317
317
  verdict: "changes_requested" as const,
318
318
  summary: "need changes",
319
- comments: [{ file: `file${counter.n}.ts`, comment: "fix this", severity: "major" }],
319
+ comments: [
320
+ { file: `file${counter.n}.ts`, comment: "fix this", severity: "major" },
321
+ ],
320
322
  }),
321
323
  };
322
324
  const daemon = new LoopDaemon(