@dorokuma/herdsman 0.6.0

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 (184) hide show
  1. package/LICENSE +23 -0
  2. package/README.ja.md +143 -0
  3. package/README.md +150 -0
  4. package/dist/drizzle.config.d.ts +3 -0
  5. package/dist/drizzle.config.d.ts.map +1 -0
  6. package/dist/drizzle.config.js +7 -0
  7. package/dist/drizzle.config.js.map +1 -0
  8. package/dist/src/agent-history/claude-reader.d.ts +10 -0
  9. package/dist/src/agent-history/claude-reader.d.ts.map +1 -0
  10. package/dist/src/agent-history/claude-reader.js +90 -0
  11. package/dist/src/agent-history/claude-reader.js.map +1 -0
  12. package/dist/src/agent-history/codex-reader.d.ts +10 -0
  13. package/dist/src/agent-history/codex-reader.d.ts.map +1 -0
  14. package/dist/src/agent-history/codex-reader.js +119 -0
  15. package/dist/src/agent-history/codex-reader.js.map +1 -0
  16. package/dist/src/agent-history/discovery.d.ts +13 -0
  17. package/dist/src/agent-history/discovery.d.ts.map +1 -0
  18. package/dist/src/agent-history/discovery.js +220 -0
  19. package/dist/src/agent-history/discovery.js.map +1 -0
  20. package/dist/src/agent-history/gemini-reader.d.ts +10 -0
  21. package/dist/src/agent-history/gemini-reader.d.ts.map +1 -0
  22. package/dist/src/agent-history/gemini-reader.js +96 -0
  23. package/dist/src/agent-history/gemini-reader.js.map +1 -0
  24. package/dist/src/agent-history/opencode-reader.d.ts +10 -0
  25. package/dist/src/agent-history/opencode-reader.d.ts.map +1 -0
  26. package/dist/src/agent-history/opencode-reader.js +90 -0
  27. package/dist/src/agent-history/opencode-reader.js.map +1 -0
  28. package/dist/src/agent-history/pi-reader.d.ts +10 -0
  29. package/dist/src/agent-history/pi-reader.d.ts.map +1 -0
  30. package/dist/src/agent-history/pi-reader.js +59 -0
  31. package/dist/src/agent-history/pi-reader.js.map +1 -0
  32. package/dist/src/agent-history/readers.d.ts +16 -0
  33. package/dist/src/agent-history/readers.d.ts.map +1 -0
  34. package/dist/src/agent-history/readers.js +45 -0
  35. package/dist/src/agent-history/readers.js.map +1 -0
  36. package/dist/src/agent-history/service.d.ts +43 -0
  37. package/dist/src/agent-history/service.d.ts.map +1 -0
  38. package/dist/src/agent-history/service.js +124 -0
  39. package/dist/src/agent-history/service.js.map +1 -0
  40. package/dist/src/agent-history/text.d.ts +10 -0
  41. package/dist/src/agent-history/text.d.ts.map +1 -0
  42. package/dist/src/agent-history/text.js +64 -0
  43. package/dist/src/agent-history/text.js.map +1 -0
  44. package/dist/src/agent-history/tool-compaction.d.ts +8 -0
  45. package/dist/src/agent-history/tool-compaction.d.ts.map +1 -0
  46. package/dist/src/agent-history/tool-compaction.js +134 -0
  47. package/dist/src/agent-history/tool-compaction.js.map +1 -0
  48. package/dist/src/cli/herdsman-daemon.d.ts +3 -0
  49. package/dist/src/cli/herdsman-daemon.d.ts.map +1 -0
  50. package/dist/src/cli/herdsman-daemon.js +18 -0
  51. package/dist/src/cli/herdsman-daemon.js.map +1 -0
  52. package/dist/src/cli/herdsman.d.ts +42 -0
  53. package/dist/src/cli/herdsman.d.ts.map +1 -0
  54. package/dist/src/cli/herdsman.js +338 -0
  55. package/dist/src/cli/herdsman.js.map +1 -0
  56. package/dist/src/config/load.d.ts +14 -0
  57. package/dist/src/config/load.d.ts.map +1 -0
  58. package/dist/src/config/load.js +28 -0
  59. package/dist/src/config/load.js.map +1 -0
  60. package/dist/src/config/runtime.d.ts +40 -0
  61. package/dist/src/config/runtime.d.ts.map +1 -0
  62. package/dist/src/config/runtime.js +111 -0
  63. package/dist/src/config/runtime.js.map +1 -0
  64. package/dist/src/config/schema.d.ts +25 -0
  65. package/dist/src/config/schema.d.ts.map +1 -0
  66. package/dist/src/config/schema.js +26 -0
  67. package/dist/src/config/schema.js.map +1 -0
  68. package/dist/src/daemon/client.d.ts +9 -0
  69. package/dist/src/daemon/client.d.ts.map +1 -0
  70. package/dist/src/daemon/client.js +51 -0
  71. package/dist/src/daemon/client.js.map +1 -0
  72. package/dist/src/daemon/herdr-session-watch-manager.d.ts +33 -0
  73. package/dist/src/daemon/herdr-session-watch-manager.d.ts.map +1 -0
  74. package/dist/src/daemon/herdr-session-watch-manager.js +245 -0
  75. package/dist/src/daemon/herdr-session-watch-manager.js.map +1 -0
  76. package/dist/src/daemon/observability-server.d.ts +60 -0
  77. package/dist/src/daemon/observability-server.d.ts.map +1 -0
  78. package/dist/src/daemon/observability-server.js +501 -0
  79. package/dist/src/daemon/observability-server.js.map +1 -0
  80. package/dist/src/daemon/process-manager.d.ts +80 -0
  81. package/dist/src/daemon/process-manager.d.ts.map +1 -0
  82. package/dist/src/daemon/process-manager.js +178 -0
  83. package/dist/src/daemon/process-manager.js.map +1 -0
  84. package/dist/src/daemon/service.d.ts +5 -0
  85. package/dist/src/daemon/service.d.ts.map +1 -0
  86. package/dist/src/daemon/service.js +104 -0
  87. package/dist/src/daemon/service.js.map +1 -0
  88. package/dist/src/db/agent-context-snapshots.d.ts +11 -0
  89. package/dist/src/db/agent-context-snapshots.d.ts.map +1 -0
  90. package/dist/src/db/agent-context-snapshots.js +129 -0
  91. package/dist/src/db/agent-context-snapshots.js.map +1 -0
  92. package/dist/src/db/agent-events.d.ts +54 -0
  93. package/dist/src/db/agent-events.d.ts.map +1 -0
  94. package/dist/src/db/agent-events.js +124 -0
  95. package/dist/src/db/agent-events.js.map +1 -0
  96. package/dist/src/db/agent-history-cache.d.ts +31 -0
  97. package/dist/src/db/agent-history-cache.d.ts.map +1 -0
  98. package/dist/src/db/agent-history-cache.js +46 -0
  99. package/dist/src/db/agent-history-cache.js.map +1 -0
  100. package/dist/src/db/agent-orchestrator-scopes.d.ts +40 -0
  101. package/dist/src/db/agent-orchestrator-scopes.d.ts.map +1 -0
  102. package/dist/src/db/agent-orchestrator-scopes.js +148 -0
  103. package/dist/src/db/agent-orchestrator-scopes.js.map +1 -0
  104. package/dist/src/db/agents.d.ts +34 -0
  105. package/dist/src/db/agents.d.ts.map +1 -0
  106. package/dist/src/db/agents.js +295 -0
  107. package/dist/src/db/agents.js.map +1 -0
  108. package/dist/src/db/apply-migrations.d.ts +4 -0
  109. package/dist/src/db/apply-migrations.d.ts.map +1 -0
  110. package/dist/src/db/apply-migrations.js +37 -0
  111. package/dist/src/db/apply-migrations.js.map +1 -0
  112. package/dist/src/db/client.d.ts +5 -0
  113. package/dist/src/db/client.d.ts.map +1 -0
  114. package/dist/src/db/client.js +6 -0
  115. package/dist/src/db/client.js.map +1 -0
  116. package/dist/src/db/herdr-sessions.d.ts +18 -0
  117. package/dist/src/db/herdr-sessions.d.ts.map +1 -0
  118. package/dist/src/db/herdr-sessions.js +67 -0
  119. package/dist/src/db/herdr-sessions.js.map +1 -0
  120. package/dist/src/db/herdr-workspaces.d.ts +14 -0
  121. package/dist/src/db/herdr-workspaces.d.ts.map +1 -0
  122. package/dist/src/db/herdr-workspaces.js +53 -0
  123. package/dist/src/db/herdr-workspaces.js.map +1 -0
  124. package/dist/src/db/migrate.d.ts +2 -0
  125. package/dist/src/db/migrate.d.ts.map +1 -0
  126. package/dist/src/db/migrate.js +8 -0
  127. package/dist/src/db/migrate.js.map +1 -0
  128. package/dist/src/db/schema.d.ts +1258 -0
  129. package/dist/src/db/schema.d.ts.map +1 -0
  130. package/dist/src/db/schema.js +102 -0
  131. package/dist/src/db/schema.js.map +1 -0
  132. package/dist/src/herdr/pane-identity-resolver.d.ts +14 -0
  133. package/dist/src/herdr/pane-identity-resolver.d.ts.map +1 -0
  134. package/dist/src/herdr/pane-identity-resolver.js +34 -0
  135. package/dist/src/herdr/pane-identity-resolver.js.map +1 -0
  136. package/dist/src/herdr/session-list.d.ts +14 -0
  137. package/dist/src/herdr/session-list.d.ts.map +1 -0
  138. package/dist/src/herdr/session-list.js +44 -0
  139. package/dist/src/herdr/session-list.js.map +1 -0
  140. package/dist/src/herdr/session-snapshot.d.ts +10 -0
  141. package/dist/src/herdr/session-snapshot.d.ts.map +1 -0
  142. package/dist/src/herdr/session-snapshot.js +19 -0
  143. package/dist/src/herdr/session-snapshot.js.map +1 -0
  144. package/dist/src/herdr/socket-client.d.ts +19 -0
  145. package/dist/src/herdr/socket-client.d.ts.map +1 -0
  146. package/dist/src/herdr/socket-client.js +230 -0
  147. package/dist/src/herdr/socket-client.js.map +1 -0
  148. package/dist/src/observability/agent-context-service.d.ts +29 -0
  149. package/dist/src/observability/agent-context-service.d.ts.map +1 -0
  150. package/dist/src/observability/agent-context-service.js +170 -0
  151. package/dist/src/observability/agent-context-service.js.map +1 -0
  152. package/dist/src/observability/agent-index-service.d.ts +60 -0
  153. package/dist/src/observability/agent-index-service.d.ts.map +1 -0
  154. package/dist/src/observability/agent-index-service.js +376 -0
  155. package/dist/src/observability/agent-index-service.js.map +1 -0
  156. package/dist/src/observability/agent-orchestrator-service.d.ts +42 -0
  157. package/dist/src/observability/agent-orchestrator-service.d.ts.map +1 -0
  158. package/dist/src/observability/agent-orchestrator-service.js +95 -0
  159. package/dist/src/observability/agent-orchestrator-service.js.map +1 -0
  160. package/dist/src/observability/contracts.d.ts +161 -0
  161. package/dist/src/observability/contracts.d.ts.map +1 -0
  162. package/dist/src/observability/contracts.js +10 -0
  163. package/dist/src/observability/contracts.js.map +1 -0
  164. package/dist/src/observability/schemas.d.ts +49 -0
  165. package/dist/src/observability/schemas.d.ts.map +1 -0
  166. package/dist/src/observability/schemas.js +47 -0
  167. package/dist/src/observability/schemas.js.map +1 -0
  168. package/dist/src/shared/json-lines.d.ts +7 -0
  169. package/dist/src/shared/json-lines.d.ts.map +1 -0
  170. package/dist/src/shared/json-lines.js +25 -0
  171. package/dist/src/shared/json-lines.js.map +1 -0
  172. package/drizzle/0000_rare_robin_chapel.sql +90 -0
  173. package/drizzle/0001_opposite_toxin.sql +13 -0
  174. package/drizzle/0002_worthless_energizer.sql +2 -0
  175. package/drizzle/0003_opposite_tarantula.sql +14 -0
  176. package/drizzle/0004_serious_lorna_dane.sql +1 -0
  177. package/drizzle/0005_pane_generation.sql +7 -0
  178. package/drizzle/meta/0000_snapshot.json +621 -0
  179. package/drizzle/meta/0001_snapshot.json +709 -0
  180. package/drizzle/meta/0002_snapshot.json +563 -0
  181. package/drizzle/meta/0003_snapshot.json +657 -0
  182. package/drizzle/meta/0004_snapshot.json +664 -0
  183. package/drizzle/meta/_journal.json +12 -0
  184. package/package.json +82 -0
@@ -0,0 +1,178 @@
1
+ import { spawn } from "node:child_process";
2
+ import { closeSync, existsSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
3
+ import { createConnection } from "node:net";
4
+ import { dirname } from "node:path";
5
+ export function readDaemonRuntimeRecord(path) {
6
+ if (!existsSync(path)) {
7
+ return undefined;
8
+ }
9
+ try {
10
+ const value = JSON.parse(readFileSync(path, "utf8"));
11
+ if (value.version !== 1 ||
12
+ typeof value.dbPath !== "string" ||
13
+ typeof value.homeDir !== "string" ||
14
+ typeof value.logPath !== "string" ||
15
+ typeof value.pid !== "number" ||
16
+ typeof value.pidPath !== "string" ||
17
+ typeof value.socketPath !== "string" ||
18
+ typeof value.startedAt !== "string") {
19
+ return undefined;
20
+ }
21
+ return value;
22
+ }
23
+ catch {
24
+ return undefined;
25
+ }
26
+ }
27
+ export function writeDaemonRuntimeRecord(path, record) {
28
+ mkdirSync(dirname(path), { mode: 0o700, recursive: true });
29
+ writeFileSync(path, `${JSON.stringify(record, null, 2)}\n`, { mode: 0o600 });
30
+ }
31
+ export async function prepareDaemonSocketPath(input) {
32
+ mkdirSync(dirname(input.socketPath), { mode: 0o700, recursive: true });
33
+ if (!existsSync(input.socketPath)) {
34
+ return;
35
+ }
36
+ const connectSocket = input.deps?.connectSocket ?? defaultConnectSocket;
37
+ if (await connectSocket(input.socketPath)) {
38
+ throw new Error(`Herdsman daemon socket is already reachable: ${input.socketPath}`);
39
+ }
40
+ rmSync(input.socketPath, { force: true });
41
+ }
42
+ export async function getDaemonStatus(input) {
43
+ const processIsRunning = input.deps?.isProcessRunning ?? isProcessRunning;
44
+ const connectSocket = input.deps?.connectSocket ?? defaultConnectSocket;
45
+ if (!existsSync(input.pidPath)) {
46
+ if (await connectSocket(input.socketPath)) {
47
+ return {
48
+ pidPath: input.pidPath,
49
+ socketPath: input.socketPath,
50
+ socketReachable: true,
51
+ state: "orphaned",
52
+ };
53
+ }
54
+ return { pidPath: input.pidPath, socketPath: input.socketPath, state: "stopped" };
55
+ }
56
+ const pid = Number(readFileSync(input.pidPath, "utf8").trim());
57
+ if (!Number.isInteger(pid) || pid <= 0 || !processIsRunning(pid)) {
58
+ if (await connectSocket(input.socketPath)) {
59
+ return {
60
+ pidPath: input.pidPath,
61
+ socketPath: input.socketPath,
62
+ socketReachable: true,
63
+ stalePid: pid,
64
+ state: "orphaned",
65
+ };
66
+ }
67
+ return {
68
+ pidPath: input.pidPath,
69
+ socketPath: input.socketPath,
70
+ stalePid: pid,
71
+ state: "stopped",
72
+ };
73
+ }
74
+ return {
75
+ pid,
76
+ pidPath: input.pidPath,
77
+ socketPath: input.socketPath,
78
+ socketReachable: await connectSocket(input.socketPath),
79
+ state: "running",
80
+ };
81
+ }
82
+ export async function startDaemonProcess(input) {
83
+ const status = await getDaemonStatus({
84
+ ...(input.deps !== undefined ? { deps: input.deps } : {}),
85
+ pidPath: input.pidPath,
86
+ socketPath: input.socketPath,
87
+ });
88
+ if (status.state === "running") {
89
+ throw new Error(`Herdsman daemon is already running with pid ${status.pid}`);
90
+ }
91
+ if (status.state === "orphaned") {
92
+ throw new Error(`Herdsman daemon socket is reachable but its PID is stale: ${status.socketPath}`);
93
+ }
94
+ mkdirSync(dirname(input.pidPath), { mode: 0o700, recursive: true });
95
+ mkdirSync(dirname(input.logPath), { mode: 0o700, recursive: true });
96
+ if (status.state === "stopped" && status.stalePid !== undefined) {
97
+ rmSync(input.pidPath, { force: true });
98
+ }
99
+ const logFd = openSync(input.logPath, "a", 0o600);
100
+ let child;
101
+ try {
102
+ child = (input.deps?.spawnProcess ?? spawnDaemonProcess)(input.nodePath, [input.entrypointPath], {
103
+ detached: true,
104
+ env: input.env,
105
+ stdio: ["ignore", logFd, logFd],
106
+ });
107
+ }
108
+ finally {
109
+ closeSync(logFd);
110
+ }
111
+ if (!child.pid) {
112
+ throw new Error("Failed to start Herdsman daemon: child pid was not assigned");
113
+ }
114
+ child.unref();
115
+ writeFileSync(input.pidPath, `${child.pid}\n`, { mode: 0o600 });
116
+ writeDaemonRuntimeRecord(input.runtimeRecordPath, {
117
+ ...input.runtimeRecord,
118
+ pid: child.pid,
119
+ startedAt: new Date().toISOString(),
120
+ version: 1,
121
+ });
122
+ return { pid: child.pid };
123
+ }
124
+ export async function stopDaemonProcess(input) {
125
+ const deps = input.deps ?? {};
126
+ const status = await getDaemonStatus({
127
+ deps,
128
+ pidPath: input.pidPath,
129
+ socketPath: input.socketPath,
130
+ });
131
+ if (status.state === "stopped") {
132
+ rmSync(input.pidPath, { force: true });
133
+ return { alreadyStopped: true };
134
+ }
135
+ if (status.state === "orphaned") {
136
+ throw new Error(`Herdsman daemon socket is reachable but its PID is stale: ${status.socketPath}`);
137
+ }
138
+ const killProcess = deps.killProcess ?? ((pid, signal) => process.kill(pid, signal));
139
+ const processIsRunning = deps.isProcessRunning ?? isProcessRunning;
140
+ const waitMs = deps.waitMs ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
141
+ killProcess(status.pid, "SIGTERM");
142
+ const deadline = Date.now() + input.timeoutMs;
143
+ while (Date.now() < deadline) {
144
+ if (!processIsRunning(status.pid)) {
145
+ rmSync(input.pidPath, { force: true });
146
+ return { alreadyStopped: false, pid: status.pid };
147
+ }
148
+ await waitMs(50);
149
+ }
150
+ throw new Error(`Timed out waiting for Herdsman daemon pid ${status.pid} to stop`);
151
+ }
152
+ function spawnDaemonProcess(command, args, options) {
153
+ const child = spawn(command, args, options);
154
+ return { pid: child.pid, unref: () => child.unref() };
155
+ }
156
+ export function isProcessRunning(pid, probe = process.kill) {
157
+ try {
158
+ probe(pid, 0);
159
+ return true;
160
+ }
161
+ catch (error) {
162
+ return typeof error === "object" && error !== null && "code" in error && error.code === "EPERM";
163
+ }
164
+ }
165
+ function defaultConnectSocket(socketPath) {
166
+ return new Promise((resolve) => {
167
+ const socket = createConnection(socketPath);
168
+ const done = (value) => {
169
+ socket.removeAllListeners();
170
+ socket.destroy();
171
+ resolve(value);
172
+ };
173
+ socket.once("connect", () => done(true));
174
+ socket.once("error", () => done(false));
175
+ socket.setTimeout(200, () => done(false));
176
+ });
177
+ }
178
+ //# sourceMappingURL=process-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../../../src/daemon/process-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function runObservabilityDaemonService(input?: {
2
+ environment?: NodeJS.ProcessEnv | undefined;
3
+ }): Promise<void>;
4
+ export declare function resolveMigrationsFolder(startDir: string): string;
5
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/daemon/service.ts"],"names":[],"mappings":"AAsBA,wBAAsB,6BAA6B,CACjD,KAAK,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAAA;CAAO,GAC1D,OAAO,CAAC,IAAI,CAAC,CAgEf;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAahE"}
@@ -0,0 +1,104 @@
1
+ import { existsSync, mkdirSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { env, exit } from "node:process";
4
+ import { fileURLToPath } from "node:url";
5
+ import { createAgentHistoryService } from "../agent-history/service.js";
6
+ import { resolveRuntime } from "../config/runtime.js";
7
+ import { AgentContextSnapshotStore } from "../db/agent-context-snapshots.js";
8
+ import { AgentEventStore } from "../db/agent-events.js";
9
+ import { AgentHistoryCacheStore } from "../db/agent-history-cache.js";
10
+ import { AgentOrchestratorScopeStore } from "../db/agent-orchestrator-scopes.js";
11
+ import { AgentStore } from "../db/agents.js";
12
+ import { applyMigrations } from "../db/apply-migrations.js";
13
+ import { openSqlite } from "../db/client.js";
14
+ import { HerdrSessionStore } from "../db/herdr-sessions.js";
15
+ import { HerdrWorkspaceStore } from "../db/herdr-workspaces.js";
16
+ import { createHerdrSessionListRunner } from "../herdr/session-list.js";
17
+ import { AgentContextService } from "../observability/agent-context-service.js";
18
+ import { AgentIndexService } from "../observability/agent-index-service.js";
19
+ import { AgentOrchestratorService } from "../observability/agent-orchestrator-service.js";
20
+ import { HerdrSessionWatchManager } from "./herdr-session-watch-manager.js";
21
+ import { ObservabilityRpcServer } from "./observability-server.js";
22
+ export async function runObservabilityDaemonService(input = {}) {
23
+ const runtime = resolveRuntime({ environment: input.environment });
24
+ applyEnvironment(runtime.environment);
25
+ mkdirSync(dirname(runtime.paths.dbPath), { recursive: true });
26
+ mkdirSync(dirname(runtime.paths.socketPath), { recursive: true });
27
+ const { sqlite } = openSqlite(runtime.paths.dbPath);
28
+ applyMigrations(sqlite, {
29
+ migrationsFolder: resolveMigrationsFolder(dirname(fileURLToPath(import.meta.url))),
30
+ });
31
+ const herdrSessions = new HerdrSessionStore(sqlite);
32
+ const herdrWorkspaces = new HerdrWorkspaceStore(sqlite);
33
+ const agents = new AgentStore(sqlite);
34
+ const agentEvents = new AgentEventStore(sqlite);
35
+ const agentHistoryCache = new AgentHistoryCacheStore(sqlite);
36
+ const agentContextSnapshots = new AgentContextSnapshotStore(sqlite);
37
+ const agentOrchestratorScopes = new AgentOrchestratorScopeStore(sqlite);
38
+ const history = createAgentHistoryService({ cache: agentHistoryCache });
39
+ const context = new AgentContextService({
40
+ history,
41
+ stores: { agentContextSnapshots, agents },
42
+ });
43
+ const daemonServices = { context, history };
44
+ const orchestrator = new AgentOrchestratorService({
45
+ agentEvents,
46
+ agents,
47
+ scopes: agentOrchestratorScopes,
48
+ });
49
+ const index = new AgentIndexService({
50
+ context: daemonServices.context,
51
+ stores: { agentEvents, agentHistoryCache, agents, herdrSessions, herdrWorkspaces },
52
+ });
53
+ const server = new ObservabilityRpcServer({
54
+ context: daemonServices.context,
55
+ history: daemonServices.history,
56
+ orchestrator,
57
+ registerPiSessionRef: (registration) => index.registerPiSessionRef(registration),
58
+ socketPath: runtime.paths.socketPath,
59
+ stores: { agentEvents, agents, herdrSessions, herdrWorkspaces },
60
+ });
61
+ const watchManager = new HerdrSessionWatchManager({
62
+ agents,
63
+ herdrSessions,
64
+ index,
65
+ onAgentContextChanged: (scope) => server.publishAgentContext(scope),
66
+ onAgentEvent: (event) => server.publishAgentEvent(event),
67
+ onAgentIndexRefreshed: (refreshed) => server.reconcileAgentLocations(refreshed),
68
+ sessionList: createHerdrSessionListRunner({ env: runtime.environment }),
69
+ });
70
+ await server.start();
71
+ await watchManager.start();
72
+ console.log(`Herdsman daemon listening on ${runtime.paths.socketPath}`);
73
+ const stop = async () => {
74
+ await watchManager.stop();
75
+ await server.stop();
76
+ sqlite.close();
77
+ exit(0);
78
+ };
79
+ process.once("SIGINT", stop);
80
+ process.once("SIGTERM", stop);
81
+ }
82
+ export function resolveMigrationsFolder(startDir) {
83
+ let current = resolve(startDir);
84
+ while (true) {
85
+ const migrationsFolder = resolve(current, "drizzle");
86
+ if (existsSync(resolve(migrationsFolder, "meta", "_journal.json"))) {
87
+ return migrationsFolder;
88
+ }
89
+ const parent = dirname(current);
90
+ if (parent === current) {
91
+ throw new Error(`Cannot find Herdsman migrations above ${startDir}`);
92
+ }
93
+ current = parent;
94
+ }
95
+ }
96
+ function applyEnvironment(environment) {
97
+ for (const [key, value] of Object.entries(environment)) {
98
+ if (value === undefined)
99
+ delete env[key];
100
+ else
101
+ env[key] = value;
102
+ }
103
+ }
104
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/daemon/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { DatabaseSync } from "node:sqlite";
2
+ import type { AgentContextSnapshotRecord } from "../observability/contracts.js";
3
+ export declare class AgentContextSnapshotStore {
4
+ #private;
5
+ constructor(sqlite: DatabaseSync);
6
+ get(agentId: string): AgentContextSnapshotRecord | undefined;
7
+ listByAgentIds(agentIds: string[]): AgentContextSnapshotRecord[];
8
+ put(input: Omit<AgentContextSnapshotRecord, "updatedAt">): AgentContextSnapshotRecord;
9
+ delete(agentId: string): void;
10
+ }
11
+ //# sourceMappingURL=agent-context-snapshots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-context-snapshots.d.ts","sourceRoot":"","sources":["../../../src/db/agent-context-snapshots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EACV,0BAA0B,EAG3B,MAAM,8BAA8B,CAAC;AAatC,qBAAa,yBAAyB;;gBAGxB,MAAM,EAAE,YAAY;IAIhC,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAO5D,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,0BAA0B,EAAE;IAShE,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,0BAA0B,EAAE,WAAW,CAAC,GAAG,0BAA0B;IAqCrF,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAG9B"}
@@ -0,0 +1,129 @@
1
+ export class AgentContextSnapshotStore {
2
+ #sqlite;
3
+ constructor(sqlite) {
4
+ this.#sqlite = sqlite;
5
+ }
6
+ get(agentId) {
7
+ const row = this.#sqlite
8
+ .prepare("select * from agent_context_snapshots where agent_id = ?")
9
+ .get(agentId);
10
+ return row ? mapSnapshot(row) : undefined;
11
+ }
12
+ listByAgentIds(agentIds) {
13
+ if (agentIds.length === 0)
14
+ return [];
15
+ const placeholders = agentIds.map(() => "?").join(", ");
16
+ const rows = this.#sqlite
17
+ .prepare(`select * from agent_context_snapshots where agent_id in (${placeholders})`)
18
+ .all(...agentIds);
19
+ return rows.map(mapSnapshot);
20
+ }
21
+ put(input) {
22
+ if ((input.historyRef === null) !== (input.sourceFingerprint === null)) {
23
+ throw new Error("Agent context history ref and source fingerprint must both be null or non-null");
24
+ }
25
+ const previous = this.get(input.agentId);
26
+ const now = Math.max(Date.now(), (previous?.updatedAt.getTime() ?? -Infinity) + 1);
27
+ this.#sqlite
28
+ .prepare(`insert into agent_context_snapshots
29
+ (agent_id, compact_history_json, history_ref_json, pane_revision, source_path, source_mtime_ms, source_size, updated_at)
30
+ values (?, ?, ?, ?, ?, ?, ?, ?)
31
+ on conflict(agent_id) do update set
32
+ compact_history_json = excluded.compact_history_json,
33
+ history_ref_json = excluded.history_ref_json,
34
+ pane_revision = excluded.pane_revision,
35
+ source_path = excluded.source_path,
36
+ source_mtime_ms = excluded.source_mtime_ms,
37
+ source_size = excluded.source_size,
38
+ updated_at = excluded.updated_at`)
39
+ .run(input.agentId, JSON.stringify(input.compactHistory), input.historyRef === null ? null : JSON.stringify(input.historyRef), input.paneRevision, input.sourceFingerprint?.path ?? null, input.sourceFingerprint?.mtimeMs ?? null, input.sourceFingerprint?.size ?? null, now);
40
+ const snapshot = this.get(input.agentId);
41
+ if (!snapshot)
42
+ throw new Error("Agent context snapshot write failed");
43
+ return snapshot;
44
+ }
45
+ delete(agentId) {
46
+ this.#sqlite.prepare("delete from agent_context_snapshots where agent_id = ?").run(agentId);
47
+ }
48
+ }
49
+ function mapSnapshot(row) {
50
+ const sourceFingerprint = mapSourceFingerprint(row);
51
+ const historyRef = row.history_ref_json === null ? null : parseHistoryRef(row.history_ref_json);
52
+ if ((historyRef === null) !== (sourceFingerprint === null)) {
53
+ throw new Error("Stored agent context history ref and source fingerprint are inconsistent");
54
+ }
55
+ return {
56
+ agentId: row.agent_id,
57
+ compactHistory: parseCompactHistory(row.compact_history_json),
58
+ historyRef,
59
+ paneRevision: row.pane_revision,
60
+ sourceFingerprint,
61
+ updatedAt: new Date(row.updated_at),
62
+ };
63
+ }
64
+ function mapSourceFingerprint(row) {
65
+ const values = [row.source_path, row.source_mtime_ms, row.source_size];
66
+ if (values.every((value) => value === null))
67
+ return null;
68
+ if (typeof row.source_path !== "string" ||
69
+ typeof row.source_mtime_ms !== "number" ||
70
+ typeof row.source_size !== "number") {
71
+ throw new Error("Stored agent context source fingerprint is invalid");
72
+ }
73
+ return { mtimeMs: row.source_mtime_ms, path: row.source_path, size: row.source_size };
74
+ }
75
+ function parseCompactHistory(value) {
76
+ const parsed = parseJson(value, "compact history");
77
+ if (!hasNullableHistoryRef(parsed.historyRef) ||
78
+ !hasNullableExcerpt(parsed.lastAssistantMessage) ||
79
+ !hasNullableToolResult(parsed.lastToolResult) ||
80
+ !hasNullableExcerpt(parsed.lastUserMessage) ||
81
+ typeof parsed.messageCount !== "number" ||
82
+ !hasNullableString(parsed.source) ||
83
+ !hasNullableString(parsed.updatedAt)) {
84
+ throw new Error("Stored agent context compact history is invalid");
85
+ }
86
+ return parsed;
87
+ }
88
+ function parseHistoryRef(value) {
89
+ const parsed = parseJson(value, "history ref");
90
+ if ((parsed.kind !== "agent_session" && parsed.kind !== "discovered_file") ||
91
+ typeof parsed.source !== "string" ||
92
+ typeof parsed.value !== "string" ||
93
+ !(parsed.path === undefined || typeof parsed.path === "string")) {
94
+ throw new Error("Stored agent context history ref is invalid");
95
+ }
96
+ return parsed;
97
+ }
98
+ function parseJson(value, label) {
99
+ try {
100
+ const parsed = JSON.parse(value);
101
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
102
+ throw new Error();
103
+ }
104
+ return parsed;
105
+ }
106
+ catch {
107
+ throw new Error(`Stored agent context ${label} is invalid`);
108
+ }
109
+ }
110
+ function hasNullableHistoryRef(value) {
111
+ return value === null || (typeof value === "object" && value !== null);
112
+ }
113
+ function hasNullableExcerpt(value) {
114
+ if (value === null)
115
+ return true;
116
+ if (typeof value !== "object" || value === null)
117
+ return false;
118
+ const excerpt = value;
119
+ return (typeof excerpt.ref === "string" &&
120
+ typeof excerpt.text === "string" &&
121
+ hasNullableString(excerpt.timestamp));
122
+ }
123
+ function hasNullableToolResult(value) {
124
+ return value === null || (typeof value === "object" && value !== null);
125
+ }
126
+ function hasNullableString(value) {
127
+ return value === null || typeof value === "string";
128
+ }
129
+ //# sourceMappingURL=agent-context-snapshots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-context-snapshots.js","sourceRoot":"","sources":["../../../src/db/agent-context-snapshots.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import type { DatabaseSync } from "node:sqlite";
2
+ import type { AgentEventRecord, AgentEventType, AgentQueryScope, CompactAgentHistory } from "../observability/contracts.js";
3
+ type AgentEventRow = {
4
+ agent_id: string | null;
5
+ compact_history_json: string | null;
6
+ created_at: number;
7
+ herdr_session_name: string;
8
+ id: number;
9
+ idempotency_key: string | null;
10
+ pane_id: string | null;
11
+ pane_generation: string | null;
12
+ payload_json: string;
13
+ deliverable: 0 | 1;
14
+ terminal_id: string | null;
15
+ type: AgentEventType;
16
+ workspace_id: string | null;
17
+ };
18
+ export declare class AgentEventStore {
19
+ #private;
20
+ constructor(sqlite: DatabaseSync);
21
+ append(input: {
22
+ agentId?: string | null;
23
+ compactHistory?: CompactAgentHistory | null;
24
+ herdrSessionName: string;
25
+ idempotencyKey?: string | null;
26
+ paneId?: string | null;
27
+ paneGeneration?: string | null;
28
+ payload: unknown;
29
+ terminalId?: string | null;
30
+ type: AgentEventType;
31
+ workspaceId?: string | null;
32
+ }): AgentEventRecord;
33
+ invalidatePane(input: {
34
+ herdrSessionName: string;
35
+ paneId: string;
36
+ paneGeneration?: string | null;
37
+ }): void;
38
+ latestStatusTransition(agentId: string, herdrSessionName: string): AgentEventRecord | undefined;
39
+ listAfter(input: AgentQueryScope & {
40
+ afterEventId?: number;
41
+ limit?: number;
42
+ }): AgentEventRecord[];
43
+ nextDeliverableAfter(input: {
44
+ afterEventId: number;
45
+ herdrSessionName: string;
46
+ ownerTerminalId: string;
47
+ workspaceId: string;
48
+ }): AgentEventRecord | undefined;
49
+ latestEventId(scope?: AgentQueryScope): number;
50
+ get(id: number): AgentEventRecord;
51
+ }
52
+ export declare function mapAgentEvent(row: AgentEventRow): AgentEventRecord;
53
+ export {};
54
+ //# sourceMappingURL=agent-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-events.d.ts","sourceRoot":"","sources":["../../../src/db/agent-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,8BAA8B,CAAC;AAEtC,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,cAAc,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEF,qBAAa,eAAe;;gBAGd,MAAM,EAAE,YAAY;IAIhC,MAAM,CAAC,KAAK,EAAE;QACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,cAAc,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;QAC5C,gBAAgB,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,IAAI,EAAE,cAAc,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,GAAG,gBAAgB;IAgCpB,cAAc,CAAC,KAAK,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI;IAUzG,sBAAsB,CACpB,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GACvB,gBAAgB,GAAG,SAAS;IAW/B,SAAS,CACP,KAAK,EAAE,eAAe,GAAG;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GACjE,gBAAgB,EAAE;IAkBrB,oBAAoB,CAAC,KAAK,EAAE;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,gBAAgB,GAAG,SAAS;IA2BhC,aAAa,CAAC,KAAK,GAAE,eAAoB,GAAG,MAAM;IAkBlD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB;CAOlC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,gBAAgB,CAclE"}
@@ -0,0 +1,124 @@
1
+ export class AgentEventStore {
2
+ #sqlite;
3
+ constructor(sqlite) {
4
+ this.#sqlite = sqlite;
5
+ }
6
+ append(input) {
7
+ const existing = input.idempotencyKey
8
+ ? this.#sqlite
9
+ .prepare("select * from agent_events where herdr_session_name = ? and idempotency_key = ?")
10
+ .get(input.herdrSessionName, input.idempotencyKey)
11
+ : undefined;
12
+ if (existing)
13
+ return mapAgentEvent(existing);
14
+ const result = this.#sqlite
15
+ .prepare(`insert into agent_events
16
+ (herdr_session_name, agent_id, pane_id, pane_generation, workspace_id, terminal_id, type, payload_json, compact_history_json, idempotency_key, deliverable, created_at)
17
+ values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)`)
18
+ .run(input.herdrSessionName, input.agentId ?? null, input.paneId ?? null, input.paneGeneration ?? null, input.workspaceId ?? null, input.terminalId ?? null, input.type, JSON.stringify(input.payload), input.compactHistory ? JSON.stringify(input.compactHistory) : null, input.idempotencyKey ?? null, Date.now());
19
+ return this.get(Number(result.lastInsertRowid));
20
+ }
21
+ invalidatePane(input) {
22
+ this.#sqlite
23
+ .prepare(`update agent_events set deliverable = 0
24
+ where herdr_session_name = ? and pane_id = ?
25
+ and (? is null or pane_generation = ? or pane_generation is null)`)
26
+ .run(input.herdrSessionName, input.paneId, input.paneGeneration ?? null, input.paneGeneration ?? null);
27
+ }
28
+ latestStatusTransition(agentId, herdrSessionName) {
29
+ const row = this.#sqlite
30
+ .prepare(`select * from agent_events
31
+ where agent_id = ? and herdr_session_name = ? and type = 'agent.status.changed'
32
+ order by id desc limit 1`)
33
+ .get(agentId, herdrSessionName);
34
+ return row ? mapAgentEvent(row) : undefined;
35
+ }
36
+ listAfter(input) {
37
+ const clauses = ["id > ?"];
38
+ const params = [input.afterEventId ?? 0];
39
+ if (input.herdrSessionName) {
40
+ clauses.push("herdr_session_name = ?");
41
+ params.push(input.herdrSessionName);
42
+ }
43
+ if (input.workspaceId) {
44
+ clauses.push("workspace_id = ?");
45
+ params.push(input.workspaceId);
46
+ }
47
+ const limit = input.limit ?? 100;
48
+ const rows = this.#sqlite
49
+ .prepare(`select * from agent_events where ${clauses.join(" and ")} order by id asc limit ?`)
50
+ .all(...params, limit);
51
+ return rows.map(mapAgentEvent);
52
+ }
53
+ nextDeliverableAfter(input) {
54
+ const row = this.#sqlite
55
+ .prepare(`select * from agent_events
56
+ where id > ?
57
+ and deliverable = 1
58
+ and herdr_session_name = ?
59
+ and workspace_id = ?
60
+ and terminal_id is not null
61
+ and terminal_id != ?
62
+ and agent_id is not null
63
+ and exists (
64
+ select 1 from agents
65
+ where agents.id = agent_events.agent_id
66
+ and agents.herdr_session_name = agent_events.herdr_session_name
67
+ and agents.workspace_id = agent_events.workspace_id
68
+ and agents.pane_id = agent_events.pane_id
69
+ )
70
+ order by id asc
71
+ limit 1`)
72
+ .get(input.afterEventId, input.herdrSessionName, input.workspaceId, input.ownerTerminalId);
73
+ return row ? mapAgentEvent(row) : undefined;
74
+ }
75
+ latestEventId(scope = {}) {
76
+ const clauses = [];
77
+ const params = [];
78
+ if (scope.herdrSessionName) {
79
+ clauses.push("herdr_session_name = ?");
80
+ params.push(scope.herdrSessionName);
81
+ }
82
+ if (scope.workspaceId) {
83
+ clauses.push("workspace_id = ?");
84
+ params.push(scope.workspaceId);
85
+ }
86
+ const where = clauses.length > 0 ? ` where ${clauses.join(" and ")}` : "";
87
+ const row = this.#sqlite
88
+ .prepare(`select max(id) as id from agent_events${where}`)
89
+ .get(...params);
90
+ return row?.id ?? 0;
91
+ }
92
+ get(id) {
93
+ const row = this.#sqlite.prepare("select * from agent_events where id = ?").get(id);
94
+ if (!row)
95
+ throw new Error(`Agent event not found: ${id}`);
96
+ return mapAgentEvent(row);
97
+ }
98
+ }
99
+ export function mapAgentEvent(row) {
100
+ return {
101
+ agentId: row.agent_id,
102
+ compactHistory: parseJson(row.compact_history_json),
103
+ createdAt: new Date(row.created_at),
104
+ herdrSessionName: row.herdr_session_name,
105
+ id: row.id,
106
+ paneId: row.pane_id,
107
+ paneGeneration: row.pane_generation,
108
+ payload: parseJson(row.payload_json) ?? {},
109
+ terminalId: row.terminal_id,
110
+ type: row.type,
111
+ workspaceId: row.workspace_id,
112
+ };
113
+ }
114
+ function parseJson(value) {
115
+ if (!value)
116
+ return null;
117
+ try {
118
+ return JSON.parse(value);
119
+ }
120
+ catch {
121
+ return null;
122
+ }
123
+ }
124
+ //# sourceMappingURL=agent-events.js.map