awb-agent-manager 1.0.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 (154) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +246 -0
  3. package/dist/lib/agent-lockfile.d.ts +37 -0
  4. package/dist/lib/agent-lockfile.js +205 -0
  5. package/dist/lib/agent-lockfile.js.map +1 -0
  6. package/dist/lib/agent-manager-commands.d.ts +34 -0
  7. package/dist/lib/agent-manager-commands.js +531 -0
  8. package/dist/lib/agent-manager-commands.js.map +1 -0
  9. package/dist/lib/base-session-manager.d.ts +127 -0
  10. package/dist/lib/base-session-manager.js +667 -0
  11. package/dist/lib/base-session-manager.js.map +1 -0
  12. package/dist/lib/chat-attachment-prep.d.ts +35 -0
  13. package/dist/lib/chat-attachment-prep.js +180 -0
  14. package/dist/lib/chat-attachment-prep.js.map +1 -0
  15. package/dist/lib/chat-session-manager.d.ts +29 -0
  16. package/dist/lib/chat-session-manager.js +400 -0
  17. package/dist/lib/chat-session-manager.js.map +1 -0
  18. package/dist/lib/circuit-breaker.d.ts +34 -0
  19. package/dist/lib/circuit-breaker.js +146 -0
  20. package/dist/lib/circuit-breaker.js.map +1 -0
  21. package/dist/lib/cli-adapters/antigravity.d.ts +15 -0
  22. package/dist/lib/cli-adapters/antigravity.js +114 -0
  23. package/dist/lib/cli-adapters/antigravity.js.map +1 -0
  24. package/dist/lib/cli-adapters/base.d.ts +115 -0
  25. package/dist/lib/cli-adapters/base.js +111 -0
  26. package/dist/lib/cli-adapters/base.js.map +1 -0
  27. package/dist/lib/cli-adapters/claude.d.ts +19 -0
  28. package/dist/lib/cli-adapters/claude.js +233 -0
  29. package/dist/lib/cli-adapters/claude.js.map +1 -0
  30. package/dist/lib/cli-adapters/codex.d.ts +14 -0
  31. package/dist/lib/cli-adapters/codex.js +152 -0
  32. package/dist/lib/cli-adapters/codex.js.map +1 -0
  33. package/dist/lib/cli-adapters/deepseek.d.ts +15 -0
  34. package/dist/lib/cli-adapters/deepseek.js +70 -0
  35. package/dist/lib/cli-adapters/deepseek.js.map +1 -0
  36. package/dist/lib/cli-adapters/index.d.ts +8 -0
  37. package/dist/lib/cli-adapters/index.js +27 -0
  38. package/dist/lib/cli-adapters/index.js.map +1 -0
  39. package/dist/lib/cli-adapters/model-introspect.d.ts +3 -0
  40. package/dist/lib/cli-adapters/model-introspect.js +65 -0
  41. package/dist/lib/cli-adapters/model-introspect.js.map +1 -0
  42. package/dist/lib/cli-error-signatures.d.ts +9 -0
  43. package/dist/lib/cli-error-signatures.js +22 -0
  44. package/dist/lib/cli-error-signatures.js.map +1 -0
  45. package/dist/lib/cli-output-summary.d.ts +2 -0
  46. package/dist/lib/cli-output-summary.js +104 -0
  47. package/dist/lib/cli-output-summary.js.map +1 -0
  48. package/dist/lib/cli-resolver.d.ts +2 -0
  49. package/dist/lib/cli-resolver.js +177 -0
  50. package/dist/lib/cli-resolver.js.map +1 -0
  51. package/dist/lib/config.d.ts +13 -0
  52. package/dist/lib/config.js +124 -0
  53. package/dist/lib/config.js.map +1 -0
  54. package/dist/lib/constants.d.ts +36 -0
  55. package/dist/lib/constants.js +51 -0
  56. package/dist/lib/constants.js.map +1 -0
  57. package/dist/lib/environment-provisioner.d.ts +31 -0
  58. package/dist/lib/environment-provisioner.js +182 -0
  59. package/dist/lib/environment-provisioner.js.map +1 -0
  60. package/dist/lib/error-log-uploader.d.ts +19 -0
  61. package/dist/lib/error-log-uploader.js +138 -0
  62. package/dist/lib/error-log-uploader.js.map +1 -0
  63. package/dist/lib/event-dispatcher.d.ts +149 -0
  64. package/dist/lib/event-dispatcher.js +799 -0
  65. package/dist/lib/event-dispatcher.js.map +1 -0
  66. package/dist/lib/event-log-recorder.d.ts +11 -0
  67. package/dist/lib/event-log-recorder.js +77 -0
  68. package/dist/lib/event-log-recorder.js.map +1 -0
  69. package/dist/lib/event-stream.d.ts +26 -0
  70. package/dist/lib/event-stream.js +177 -0
  71. package/dist/lib/event-stream.js.map +1 -0
  72. package/dist/lib/fs-browser.d.ts +30 -0
  73. package/dist/lib/fs-browser.js +287 -0
  74. package/dist/lib/fs-browser.js.map +1 -0
  75. package/dist/lib/host-mcp/logs.d.ts +19 -0
  76. package/dist/lib/host-mcp/logs.js +102 -0
  77. package/dist/lib/host-mcp/logs.js.map +1 -0
  78. package/dist/lib/host-mcp/platform.d.ts +24 -0
  79. package/dist/lib/host-mcp/platform.js +133 -0
  80. package/dist/lib/host-mcp/platform.js.map +1 -0
  81. package/dist/lib/host-mcp/screens.d.ts +22 -0
  82. package/dist/lib/host-mcp/screens.js +172 -0
  83. package/dist/lib/host-mcp/screens.js.map +1 -0
  84. package/dist/lib/host-mcp/server.d.ts +3 -0
  85. package/dist/lib/host-mcp/server.js +233 -0
  86. package/dist/lib/host-mcp/server.js.map +1 -0
  87. package/dist/lib/host-mcp/tools.d.ts +172 -0
  88. package/dist/lib/host-mcp/tools.js +1241 -0
  89. package/dist/lib/host-mcp/tools.js.map +1 -0
  90. package/dist/lib/instance-heartbeat.d.ts +55 -0
  91. package/dist/lib/instance-heartbeat.js +118 -0
  92. package/dist/lib/instance-heartbeat.js.map +1 -0
  93. package/dist/lib/legacy-import.d.ts +17 -0
  94. package/dist/lib/legacy-import.js +70 -0
  95. package/dist/lib/legacy-import.js.map +1 -0
  96. package/dist/lib/logging.d.ts +3 -0
  97. package/dist/lib/logging.js +65 -0
  98. package/dist/lib/logging.js.map +1 -0
  99. package/dist/lib/managed-agent-context.d.ts +25 -0
  100. package/dist/lib/managed-agent-context.js +33 -0
  101. package/dist/lib/managed-agent-context.js.map +1 -0
  102. package/dist/lib/managed-agent-store.d.ts +34 -0
  103. package/dist/lib/managed-agent-store.js +160 -0
  104. package/dist/lib/managed-agent-store.js.map +1 -0
  105. package/dist/lib/managed-agents.d.ts +24 -0
  106. package/dist/lib/managed-agents.js +87 -0
  107. package/dist/lib/managed-agents.js.map +1 -0
  108. package/dist/lib/mcp-client.d.ts +8 -0
  109. package/dist/lib/mcp-client.js +122 -0
  110. package/dist/lib/mcp-client.js.map +1 -0
  111. package/dist/lib/orphan-cleanup.d.ts +6 -0
  112. package/dist/lib/orphan-cleanup.js +108 -0
  113. package/dist/lib/orphan-cleanup.js.map +1 -0
  114. package/dist/lib/presence-heartbeat.d.ts +8 -0
  115. package/dist/lib/presence-heartbeat.js +61 -0
  116. package/dist/lib/presence-heartbeat.js.map +1 -0
  117. package/dist/lib/prompts.d.ts +29 -0
  118. package/dist/lib/prompts.js +208 -0
  119. package/dist/lib/prompts.js.map +1 -0
  120. package/dist/lib/rest.d.ts +61 -0
  121. package/dist/lib/rest.js +307 -0
  122. package/dist/lib/rest.js.map +1 -0
  123. package/dist/lib/run-provisioner.d.ts +21 -0
  124. package/dist/lib/run-provisioner.js +115 -0
  125. package/dist/lib/run-provisioner.js.map +1 -0
  126. package/dist/lib/self-path.d.ts +7 -0
  127. package/dist/lib/self-path.js +29 -0
  128. package/dist/lib/self-path.js.map +1 -0
  129. package/dist/lib/self-update.d.ts +46 -0
  130. package/dist/lib/self-update.js +482 -0
  131. package/dist/lib/self-update.js.map +1 -0
  132. package/dist/lib/service-install.d.ts +23 -0
  133. package/dist/lib/service-install.js +673 -0
  134. package/dist/lib/service-install.js.map +1 -0
  135. package/dist/lib/setup.d.ts +16 -0
  136. package/dist/lib/setup.js +157 -0
  137. package/dist/lib/setup.js.map +1 -0
  138. package/dist/lib/subagent-manager.d.ts +84 -0
  139. package/dist/lib/subagent-manager.js +793 -0
  140. package/dist/lib/subagent-manager.js.map +1 -0
  141. package/dist/lib/subagent-monitor.d.ts +43 -0
  142. package/dist/lib/subagent-monitor.js +229 -0
  143. package/dist/lib/subagent-monitor.js.map +1 -0
  144. package/dist/lib/ticket-session-manager.d.ts +23 -0
  145. package/dist/lib/ticket-session-manager.js +471 -0
  146. package/dist/lib/ticket-session-manager.js.map +1 -0
  147. package/dist/lib/worktree-manager.d.ts +39 -0
  148. package/dist/lib/worktree-manager.js +226 -0
  149. package/dist/lib/worktree-manager.js.map +1 -0
  150. package/dist/main.d.ts +2 -0
  151. package/dist/main.js +670 -0
  152. package/dist/main.js.map +1 -0
  153. package/dist/package.json +57 -0
  154. package/package.json +57 -0
@@ -0,0 +1,160 @@
1
+ import { promises as fsp } from 'node:fs';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { MANAGED_AGENTS_DIR } from './constants.js';
5
+ import { resolveSelfCommand } from './self-path.js';
6
+ export function managedAgentDir(agentId) {
7
+ return join(MANAGED_AGENTS_DIR, agentId);
8
+ }
9
+ export function configPathFor(agentId) {
10
+ return join(managedAgentDir(agentId), 'config.json');
11
+ }
12
+ export function apiKeyPathFor(agentId) {
13
+ return join(managedAgentDir(agentId), 'apikey');
14
+ }
15
+ export function mcpConfigPathFor(agentId) {
16
+ return join(managedAgentDir(agentId), 'mcp-config.json');
17
+ }
18
+ export function credentialPathFor(agentId) {
19
+ return join(managedAgentDir(agentId), 'credential.json');
20
+ }
21
+ export async function readAgentCredential(agentId) {
22
+ const path = credentialPathFor(agentId);
23
+ if (!existsSync(path))
24
+ return null;
25
+ try {
26
+ const raw = JSON.parse(readFileSync(path, 'utf8'));
27
+ if (!raw || typeof raw !== 'object')
28
+ return null;
29
+ if (typeof raw.provider !== 'string' || !raw.provider)
30
+ return null;
31
+ return {
32
+ credential_id: typeof raw.credential_id === 'string' ? raw.credential_id : '',
33
+ provider: raw.provider,
34
+ fields: raw.fields && typeof raw.fields === 'object' ? raw.fields : {},
35
+ };
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ }
41
+ export async function writeAgentCredential(agentId, credential) {
42
+ await ensureManagedAgentDir(agentId);
43
+ await fsp.writeFile(credentialPathFor(agentId), JSON.stringify(credential, null, 2), { mode: 0o600 });
44
+ }
45
+ export async function eraseAgentCredential(agentId) {
46
+ await fsp.unlink(credentialPathFor(agentId)).catch(() => undefined);
47
+ }
48
+ export function subagentLogPathFor(agentId) {
49
+ return join(managedAgentDir(agentId), 'subagent.log');
50
+ }
51
+ export function cliHomeDirFor(agentId) {
52
+ return join(managedAgentDir(agentId), 'cli-home');
53
+ }
54
+ export async function ensureCliHomeDir(agentId) {
55
+ const dir = cliHomeDirFor(agentId);
56
+ await fsp.mkdir(dir, { recursive: true, mode: 0o700 });
57
+ return dir;
58
+ }
59
+ export async function ensureManagedAgentDir(agentId) {
60
+ const dir = managedAgentDir(agentId);
61
+ await fsp.mkdir(dir, { recursive: true, mode: 0o700 });
62
+ return dir;
63
+ }
64
+ export async function readManagedAgentConfig(agentId) {
65
+ const path = configPathFor(agentId);
66
+ if (!existsSync(path))
67
+ return null;
68
+ try {
69
+ const raw = JSON.parse(readFileSync(path, 'utf8'));
70
+ if (raw && typeof raw === 'object' && raw.agent_id === agentId) {
71
+ return raw;
72
+ }
73
+ }
74
+ catch {
75
+ }
76
+ return null;
77
+ }
78
+ export async function writeManagedAgentConfig(cfg) {
79
+ await ensureManagedAgentDir(cfg.agent_id);
80
+ await fsp.writeFile(configPathFor(cfg.agent_id), JSON.stringify(cfg, null, 2), { mode: 0o600 });
81
+ }
82
+ export async function readApiKey(agentId) {
83
+ const path = apiKeyPathFor(agentId);
84
+ if (!existsSync(path))
85
+ return null;
86
+ try {
87
+ const raw = readFileSync(path, 'utf8').trim();
88
+ return raw || null;
89
+ }
90
+ catch {
91
+ return null;
92
+ }
93
+ }
94
+ export async function writeApiKey(agentId, raw) {
95
+ await ensureManagedAgentDir(agentId);
96
+ await fsp.writeFile(apiKeyPathFor(agentId), raw, { mode: 0o600 });
97
+ }
98
+ export async function writeMcpConfig(agentId, awbUrl, rawApiKey) {
99
+ await ensureManagedAgentDir(agentId);
100
+ const path = mcpConfigPathFor(agentId);
101
+ const self = resolveSelfCommand();
102
+ const body = {
103
+ mcpServers: {
104
+ awb: {
105
+ type: 'http',
106
+ url: `${awbUrl.replace(/\/$/, '')}/mcp`,
107
+ headers: {
108
+ Authorization: `Bearer ${rawApiKey}`,
109
+ 'X-AWB-Client-Type': 'managed-subagent',
110
+ },
111
+ },
112
+ host: {
113
+ type: 'stdio',
114
+ command: self.command,
115
+ args: [...self.prefixArgs, 'mcp-host'],
116
+ },
117
+ },
118
+ };
119
+ await fsp.writeFile(path, JSON.stringify(body, null, 2), { mode: 0o600 });
120
+ return path;
121
+ }
122
+ export async function eraseSecrets(agentId) {
123
+ await Promise.allSettled([
124
+ fsp.unlink(apiKeyPathFor(agentId)),
125
+ fsp.unlink(mcpConfigPathFor(agentId)),
126
+ fsp.unlink(credentialPathFor(agentId)),
127
+ ]);
128
+ }
129
+ export function maskKey(raw) {
130
+ if (!raw)
131
+ return '';
132
+ if (raw.length <= 12)
133
+ return raw.slice(0, 4) + '***';
134
+ return raw.slice(0, 8) + '***' + raw.slice(-4);
135
+ }
136
+ export async function listManagedAgentDirs() {
137
+ let entries;
138
+ try {
139
+ entries = await fsp.readdir(MANAGED_AGENTS_DIR);
140
+ }
141
+ catch {
142
+ return [];
143
+ }
144
+ const out = [];
145
+ for (const name of entries) {
146
+ const full = join(MANAGED_AGENTS_DIR, name);
147
+ try {
148
+ const stat = await fsp.stat(full);
149
+ if (!stat.isDirectory())
150
+ continue;
151
+ const cfg = configPathFor(name);
152
+ if (existsSync(cfg))
153
+ out.push(name);
154
+ }
155
+ catch {
156
+ }
157
+ }
158
+ return out;
159
+ }
160
+ //# sourceMappingURL=managed-agent-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-agent-store.js","sourceRoot":"","sources":["../../src/lib/managed-agent-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export type ManagedAgentStatus = 'idle' | 'spawning' | 'running' | 'stopped' | 'error';
2
+ export interface ManagedAgentRecord {
3
+ agent_id: string;
4
+ name: string;
5
+ cli: string;
6
+ working_dir: string;
7
+ status: ManagedAgentStatus;
8
+ pid: number | null;
9
+ spawned_at: string | null;
10
+ stopped_at: string | null;
11
+ last_error: string | null;
12
+ }
13
+ export declare class ManagedAgentRegistry {
14
+ #private;
15
+ list(): ManagedAgentRecord[];
16
+ get(agentId: string): ManagedAgentRecord | null;
17
+ upsert(rec: Pick<ManagedAgentRecord, 'agent_id' | 'name' | 'cli' | 'working_dir'>): ManagedAgentRecord;
18
+ setWorkingDir(agentId: string, workingDir: string): ManagedAgentRecord | null;
19
+ markRunning(agentId: string, pid: number): ManagedAgentRecord | null;
20
+ markStopped(agentId: string, reason?: string): ManagedAgentRecord | null;
21
+ markError(agentId: string, message: string): ManagedAgentRecord | null;
22
+ liveAgentIds(): string[];
23
+ workingDirs(): string[];
24
+ }
@@ -0,0 +1,87 @@
1
+ import { log } from './logging.js';
2
+ export class ManagedAgentRegistry {
3
+ #byId = new Map();
4
+ list() {
5
+ return Array.from(this.#byId.values());
6
+ }
7
+ get(agentId) {
8
+ return this.#byId.get(agentId) ?? null;
9
+ }
10
+ upsert(rec) {
11
+ const existing = this.#byId.get(rec.agent_id);
12
+ if (existing) {
13
+ existing.name = rec.name || existing.name;
14
+ existing.cli = rec.cli || existing.cli;
15
+ existing.working_dir = rec.working_dir || existing.working_dir;
16
+ return existing;
17
+ }
18
+ const fresh = {
19
+ agent_id: rec.agent_id,
20
+ name: rec.name || rec.agent_id.slice(0, 8),
21
+ cli: rec.cli || 'claude',
22
+ working_dir: rec.working_dir || '',
23
+ status: 'idle',
24
+ pid: null,
25
+ spawned_at: null,
26
+ stopped_at: null,
27
+ last_error: null,
28
+ };
29
+ this.#byId.set(rec.agent_id, fresh);
30
+ return fresh;
31
+ }
32
+ setWorkingDir(agentId, workingDir) {
33
+ const rec = this.#byId.get(agentId);
34
+ if (!rec)
35
+ return null;
36
+ rec.working_dir = workingDir;
37
+ return rec;
38
+ }
39
+ markRunning(agentId, pid) {
40
+ const rec = this.#byId.get(agentId);
41
+ if (!rec)
42
+ return null;
43
+ rec.status = 'running';
44
+ rec.pid = pid;
45
+ rec.spawned_at = new Date().toISOString();
46
+ rec.stopped_at = null;
47
+ rec.last_error = null;
48
+ return rec;
49
+ }
50
+ markStopped(agentId, reason) {
51
+ const rec = this.#byId.get(agentId);
52
+ if (!rec)
53
+ return null;
54
+ rec.status = 'stopped';
55
+ rec.pid = null;
56
+ rec.stopped_at = new Date().toISOString();
57
+ if (reason)
58
+ rec.last_error = reason;
59
+ return rec;
60
+ }
61
+ markError(agentId, message) {
62
+ const rec = this.#byId.get(agentId);
63
+ if (!rec)
64
+ return null;
65
+ rec.status = 'error';
66
+ rec.last_error = message;
67
+ log(`[managed-agent ${agentId.slice(0, 8)}] error: ${message}`);
68
+ return rec;
69
+ }
70
+ liveAgentIds() {
71
+ const out = [];
72
+ for (const rec of this.#byId.values()) {
73
+ if (rec.status === 'running' || rec.status === 'spawning')
74
+ out.push(rec.agent_id);
75
+ }
76
+ return out;
77
+ }
78
+ workingDirs() {
79
+ const seen = new Set();
80
+ for (const rec of this.#byId.values()) {
81
+ if (rec.working_dir)
82
+ seen.add(rec.working_dir);
83
+ }
84
+ return Array.from(seen);
85
+ }
86
+ }
87
+ //# sourceMappingURL=managed-agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-agents.js","sourceRoot":"","sources":["../../src/lib/managed-agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { AwbConfig } from './rest.js';
2
+ export interface McpCallOptions {
3
+ timeoutMs?: number;
4
+ clientName?: string;
5
+ }
6
+ export declare function callMcpTool(config: AwbConfig, toolName: string, toolArgs: Record<string, unknown> | undefined, opts?: McpCallOptions): Promise<any>;
7
+ export declare function unwrapToolResult(rpcResponse: any): any;
8
+ export declare function fireAndForgetTool(config: AwbConfig, toolName: string, toolArgs: Record<string, unknown> | undefined): Promise<void>;
@@ -0,0 +1,122 @@
1
+ import { REQUEST_TIMEOUT_MS } from './constants.js';
2
+ import { log } from './logging.js';
3
+ export async function callMcpTool(config, toolName, toolArgs, opts = {}) {
4
+ const base = (config?.url ?? '').replace(/\/$/, '');
5
+ if (!base)
6
+ throw new Error('callMcpTool: config.url missing');
7
+ if (!config?.apiKey)
8
+ throw new Error('callMcpTool: config.apiKey missing');
9
+ const url = `${base}/mcp`;
10
+ const timeoutMs = opts.timeoutMs ?? REQUEST_TIMEOUT_MS;
11
+ const baseHeaders = {
12
+ Authorization: `Bearer ${config.apiKey}`,
13
+ 'Content-Type': 'application/json',
14
+ Accept: 'application/json, text/event-stream',
15
+ };
16
+ const initResp = await fetch(url, {
17
+ method: 'POST',
18
+ headers: baseHeaders,
19
+ body: JSON.stringify({
20
+ jsonrpc: '2.0',
21
+ id: 1,
22
+ method: 'initialize',
23
+ params: {
24
+ protocolVersion: '2025-03-26',
25
+ capabilities: { experimental: { 'awb/schemaVersion': { version: 2 } } },
26
+ clientInfo: { name: opts.clientName || 'awb-agent-manager-tool', version: '1.0.0' },
27
+ },
28
+ }),
29
+ signal: AbortSignal.timeout(timeoutMs),
30
+ });
31
+ if (!initResp.ok) {
32
+ throw new Error(`initialize HTTP ${initResp.status}`);
33
+ }
34
+ const sid = initResp.headers.get('mcp-session-id');
35
+ if (!sid)
36
+ throw new Error('initialize did not return Mcp-Session-Id');
37
+ await initResp.text().catch(() => null);
38
+ const sessionHeaders = { ...baseHeaders, 'Mcp-Session-Id': sid };
39
+ await fetch(url, {
40
+ method: 'POST',
41
+ headers: sessionHeaders,
42
+ body: JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' }),
43
+ signal: AbortSignal.timeout(timeoutMs),
44
+ }).then((r) => r.text().catch(() => null));
45
+ let result = null;
46
+ try {
47
+ const callResp = await fetch(url, {
48
+ method: 'POST',
49
+ headers: sessionHeaders,
50
+ body: JSON.stringify({
51
+ jsonrpc: '2.0',
52
+ id: 2,
53
+ method: 'tools/call',
54
+ params: { name: toolName, arguments: toolArgs ?? {} },
55
+ }),
56
+ signal: AbortSignal.timeout(timeoutMs),
57
+ });
58
+ if (!callResp.ok) {
59
+ throw new Error(`tools/call ${toolName} HTTP ${callResp.status}`);
60
+ }
61
+ result = await parseStreamableResponse(callResp);
62
+ }
63
+ finally {
64
+ fetch(url, {
65
+ method: 'DELETE',
66
+ headers: sessionHeaders,
67
+ signal: AbortSignal.timeout(timeoutMs),
68
+ })
69
+ .then((r) => r.text().catch(() => null))
70
+ .catch(() => {
71
+ });
72
+ }
73
+ return result;
74
+ }
75
+ async function parseStreamableResponse(resp) {
76
+ const contentType = resp.headers.get('content-type') ?? '';
77
+ const text = await resp.text();
78
+ if (!text)
79
+ return null;
80
+ if (contentType.includes('text/event-stream')) {
81
+ for (const line of text.split('\n')) {
82
+ const m = /^data:\s*(.+)$/.exec(line);
83
+ if (m) {
84
+ try {
85
+ return JSON.parse(m[1]);
86
+ }
87
+ catch {
88
+ }
89
+ }
90
+ }
91
+ return null;
92
+ }
93
+ try {
94
+ return JSON.parse(text);
95
+ }
96
+ catch {
97
+ return null;
98
+ }
99
+ }
100
+ export function unwrapToolResult(rpcResponse) {
101
+ const content = rpcResponse?.result?.content;
102
+ if (!Array.isArray(content) || content.length === 0)
103
+ return null;
104
+ const text = content[0]?.text;
105
+ if (typeof text !== 'string')
106
+ return null;
107
+ try {
108
+ return JSON.parse(text);
109
+ }
110
+ catch {
111
+ return text;
112
+ }
113
+ }
114
+ export async function fireAndForgetTool(config, toolName, toolArgs) {
115
+ try {
116
+ await callMcpTool(config, toolName, toolArgs);
117
+ }
118
+ catch (err) {
119
+ log(`MCP tool ${toolName} failed (fire-and-forget): ${err?.message ?? err}`);
120
+ }
121
+ }
122
+ //# sourceMappingURL=mcp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/lib/mcp-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface CleanupResult {
2
+ scanned: number;
3
+ reaped: number;
4
+ skipped?: number;
5
+ }
6
+ export declare function cleanupOrphanSubagents(): Promise<CleanupResult>;
@@ -0,0 +1,108 @@
1
+ import { promises as fsp } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { SUBAGENTS_BASE_DIR } from './constants.js';
4
+ import { log } from './logging.js';
5
+ const KILL_BACKUP_DELAY_MS = 2000;
6
+ async function readPid(pidPath) {
7
+ try {
8
+ const raw = await fsp.readFile(pidPath, 'utf8');
9
+ const pid = parseInt(raw.trim(), 10);
10
+ return Number.isFinite(pid) && pid > 0 ? pid : null;
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ }
16
+ function isPidAlive(pid) {
17
+ try {
18
+ process.kill(pid, 0);
19
+ return true;
20
+ }
21
+ catch (err) {
22
+ return err?.code === 'EPERM';
23
+ }
24
+ }
25
+ async function readLiveCfgPathsFromProc() {
26
+ let procEntries;
27
+ try {
28
+ procEntries = await fsp.readdir('/proc');
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ const live = new Set();
34
+ for (const entry of procEntries) {
35
+ if (!/^\d+$/.test(entry))
36
+ continue;
37
+ try {
38
+ const cmdline = await fsp.readFile(`/proc/${entry}/cmdline`, 'utf8');
39
+ const parts = cmdline.split('\0');
40
+ const idx = parts.indexOf('--mcp-config');
41
+ if (idx >= 0 && parts[idx + 1])
42
+ live.add(parts[idx + 1]);
43
+ }
44
+ catch {
45
+ }
46
+ }
47
+ return live;
48
+ }
49
+ async function reapOne(dir, entry, liveCfgPaths) {
50
+ const pidPath = join(dir, entry);
51
+ const cfgPath = pidPath.replace(/\.pid$/, '.json');
52
+ if (liveCfgPaths && liveCfgPaths.has(cfgPath)) {
53
+ return { skipped: true };
54
+ }
55
+ const pid = await readPid(pidPath);
56
+ if (pid != null && isPidAlive(pid)) {
57
+ log(`[orphan-cleanup] killing stale subagent pid=${pid} (${entry})`);
58
+ try {
59
+ process.kill(pid, 'SIGTERM');
60
+ }
61
+ catch {
62
+ }
63
+ const t = setTimeout(() => {
64
+ try {
65
+ process.kill(pid, 'SIGKILL');
66
+ }
67
+ catch {
68
+ }
69
+ }, KILL_BACKUP_DELAY_MS);
70
+ if (typeof t.unref === 'function')
71
+ t.unref();
72
+ }
73
+ await fsp.unlink(pidPath).catch(() => { });
74
+ await fsp.unlink(cfgPath).catch(() => { });
75
+ return { skipped: false };
76
+ }
77
+ export async function cleanupOrphanSubagents() {
78
+ let entries;
79
+ try {
80
+ entries = await fsp.readdir(SUBAGENTS_BASE_DIR);
81
+ }
82
+ catch {
83
+ return { scanned: 0, reaped: 0 };
84
+ }
85
+ const pidFiles = entries.filter((e) => e.endsWith('.pid'));
86
+ if (pidFiles.length === 0) {
87
+ return { scanned: 0, reaped: 0 };
88
+ }
89
+ const liveCfgPaths = await readLiveCfgPathsFromProc();
90
+ log(`[orphan-cleanup] scanning ${pidFiles.length} pid sidecar(s) in ${SUBAGENTS_BASE_DIR} (live cfg paths in /proc: ${liveCfgPaths ? liveCfgPaths.size : 'unavailable'})`);
91
+ let reaped = 0;
92
+ let skipped = 0;
93
+ for (const entry of pidFiles) {
94
+ try {
95
+ const r = await reapOne(SUBAGENTS_BASE_DIR, entry, liveCfgPaths);
96
+ if (r.skipped)
97
+ skipped++;
98
+ else
99
+ reaped++;
100
+ }
101
+ catch (err) {
102
+ log(`[orphan-cleanup] skipping ${entry}: ${err?.message ?? err}`);
103
+ }
104
+ }
105
+ log(`[orphan-cleanup] reaped ${reaped}/${pidFiles.length} orphan subagents (${skipped} protected as live-sibling)`);
106
+ return { scanned: pidFiles.length, reaped, skipped };
107
+ }
108
+ //# sourceMappingURL=orphan-cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orphan-cleanup.js","sourceRoot":"","sources":["../../src/lib/orphan-cleanup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { AwbConfig } from './rest.js';
2
+ export declare class PresenceHeartbeat {
3
+ #private;
4
+ constructor(config: AwbConfig, agentId: string | null);
5
+ start(): void;
6
+ stop(): void;
7
+ pingNow(): Promise<void>;
8
+ }
@@ -0,0 +1,61 @@
1
+ import { HEARTBEAT_INTERVAL_MS, REQUEST_TIMEOUT_MS } from './constants.js';
2
+ import { log } from './logging.js';
3
+ export class PresenceHeartbeat {
4
+ #config;
5
+ #agentId;
6
+ #timer = null;
7
+ #stopped = false;
8
+ constructor(config, agentId) {
9
+ this.#config = config;
10
+ this.#agentId = agentId;
11
+ }
12
+ start() {
13
+ if (!this.#agentId) {
14
+ log('Presence heartbeat skipped — agent_id not in agent.json (run pairing first)');
15
+ return;
16
+ }
17
+ this.#stopped = false;
18
+ this.#ping().catch((err) => log(`Presence ping (initial) failed: ${err?.message ?? err}`));
19
+ this.#timer = setInterval(() => {
20
+ this.#ping().catch((err) => log(`Presence ping failed: ${err?.message ?? err}`));
21
+ }, HEARTBEAT_INTERVAL_MS);
22
+ this.#timer.unref?.();
23
+ log(`Presence heartbeat started (agent=${this.#agentId.slice(0, 8)} interval=${HEARTBEAT_INTERVAL_MS / 1000}s)`);
24
+ }
25
+ stop() {
26
+ this.#stopped = true;
27
+ if (this.#timer) {
28
+ clearInterval(this.#timer);
29
+ this.#timer = null;
30
+ }
31
+ }
32
+ async pingNow() {
33
+ if (this.#stopped || !this.#agentId)
34
+ return;
35
+ try {
36
+ await this.#ping();
37
+ }
38
+ catch (err) {
39
+ log(`Presence ping (forced) failed: ${err?.message ?? err}`);
40
+ }
41
+ }
42
+ async #ping() {
43
+ if (this.#stopped)
44
+ return;
45
+ const url = `${this.#config.url.replace(/\/$/, '')}/api/agent/ping`;
46
+ const resp = await fetch(url, {
47
+ method: 'POST',
48
+ headers: {
49
+ 'X-Agent-Key': this.#config.apiKey,
50
+ 'Content-Type': 'application/json',
51
+ },
52
+ body: JSON.stringify({ agent_id: this.#agentId }),
53
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
54
+ });
55
+ if (!resp.ok) {
56
+ throw new Error(`POST /api/agent/ping HTTP ${resp.status}`);
57
+ }
58
+ await resp.text().catch(() => null);
59
+ }
60
+ }
61
+ //# sourceMappingURL=presence-heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence-heartbeat.js","sourceRoot":"","sources":["../../src/lib/presence-heartbeat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAanC,MAAM,OAAO,iBAAiB;IAC5B,OAAO,CAAY;IACnB,QAAQ,CAAgB;IACxB,MAAM,GAA0B,IAAI,CAAC;IACrC,QAAQ,GAAG,KAAK,CAAC;IAEjB,YAAY,MAAiB,EAAE,OAAsB;QACnD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,GAAG,CAAC,6EAA6E,CAAC,CAAC;YACnF,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACzB,GAAG,CAAC,mCAAmC,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAC9D,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACzB,GAAG,CAAC,yBAAyB,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CACpD,CAAC;QACJ,CAAC,EAAE,qBAAqB,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;QACtB,GAAG,CACD,qCAAqC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,aAAa,qBAAqB,GAAG,IAAI,IAAI,CAC5G,CAAC;IACJ,CAAC;IAED,IAAI;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IAMD,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC5C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,GAAG,CAAC,kCAAkC,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC;QACpE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC5B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;gBAClC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;SAChD,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import type { ColumnPrompt, PromptComposer } from './event-dispatcher.js';
2
+ import { type PreparedAttachment, type RawChatAttachment } from './chat-attachment-prep.js';
3
+ interface MentionLike {
4
+ actor_name?: string;
5
+ mention_source?: string;
6
+ role_shortcut?: string;
7
+ ticket_id?: string;
8
+ content?: string;
9
+ }
10
+ interface ChatHistoryEntry {
11
+ sender_type?: string;
12
+ sender_name?: string;
13
+ sender_id?: string;
14
+ content?: string;
15
+ created_at?: string;
16
+ attachments?: RawChatAttachment[];
17
+ type?: string;
18
+ }
19
+ interface ChatRoomNewMessage {
20
+ content?: string;
21
+ sender_name?: string;
22
+ sender_id?: string;
23
+ }
24
+ export declare function composeTriggerPrompt(ticket: any, _rolePrompt: string, ticketPrompt: string, fallbackTicketId: string, columnPrompt: ColumnPrompt | null, extraInstructions?: string | null): string;
25
+ export declare function composeChatPrompt(_rolePrompt: string, history: ChatHistoryEntry[], newMessage: string, roomId?: string, usesNativeMcp?: boolean): string;
26
+ export declare function composeCommentMentionPrompt(ticket: any, _rolePrompt: string, mention: MentionLike, fallbackTicketId: string): string;
27
+ export declare function composeChatRoomPrompt(roomId: string, history: ChatHistoryEntry[], newMessage: ChatRoomNewMessage, attachments?: PreparedAttachment[], usesNativeMcp?: boolean, historyAttachments?: Map<ChatHistoryEntry, PreparedAttachment[]>): string;
28
+ export declare const promptComposer: PromptComposer;
29
+ export {};