@borgee/agents-host 0.2.1 → 0.2.26

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 (78) hide show
  1. package/README.md +184 -21
  2. package/dist/agents-host-supervisor.d.ts +7 -5
  3. package/dist/agents-host-supervisor.js +24 -4
  4. package/dist/agents-host.d.ts +89 -15
  5. package/dist/agents-host.js +2099 -142
  6. package/dist/chat/chat-control-plane.d.ts +14 -3
  7. package/dist/chat/sdk-chat-control-plane.d.ts +16 -4
  8. package/dist/chat/sdk-chat-control-plane.js +69 -9
  9. package/dist/cli-args.d.ts +46 -5
  10. package/dist/cli-args.js +313 -32
  11. package/dist/cli.d.ts +9 -0
  12. package/dist/cli.js +112 -5
  13. package/dist/compatibility-gates.d.ts +35 -0
  14. package/dist/compatibility-gates.js +127 -0
  15. package/dist/config.d.ts +1 -0
  16. package/dist/config.js +23 -5
  17. package/dist/connections-state-store.d.ts +81 -0
  18. package/dist/connections-state-store.js +228 -0
  19. package/dist/context/injection.d.ts +109 -0
  20. package/dist/context/injection.js +350 -0
  21. package/dist/context/prompt.d.ts +4 -1
  22. package/dist/context/prompt.js +170 -1
  23. package/dist/context/turn-preparation.d.ts +9 -0
  24. package/dist/context/turn-preparation.js +106 -0
  25. package/dist/debug.d.ts +44 -0
  26. package/dist/debug.js +135 -0
  27. package/dist/gateway/localhost-gateway.d.ts +52 -0
  28. package/dist/gateway/localhost-gateway.js +857 -0
  29. package/dist/index.js +7 -5
  30. package/dist/local-config.d.ts +4 -1
  31. package/dist/local-config.js +24 -7
  32. package/dist/managed-daemon-log.d.ts +34 -0
  33. package/dist/managed-daemon-log.js +261 -0
  34. package/dist/managed-daemon.d.ts +220 -0
  35. package/dist/managed-daemon.js +1601 -0
  36. package/dist/policy/authorization-audit.d.ts +63 -0
  37. package/dist/policy/authorization-audit.js +94 -0
  38. package/dist/policy/copilot-permission.d.ts +15 -0
  39. package/dist/policy/copilot-permission.js +193 -0
  40. package/dist/policy/gateway-authorization.d.ts +42 -0
  41. package/dist/policy/gateway-authorization.js +162 -0
  42. package/dist/providers/awaiting-user.d.ts +12 -0
  43. package/dist/providers/awaiting-user.js +151 -0
  44. package/dist/providers/claude/adapter.d.ts +3 -1
  45. package/dist/providers/claude/adapter.js +8 -12
  46. package/dist/providers/claude/cli-client.d.ts +12 -5
  47. package/dist/providers/claude/cli-client.js +184 -37
  48. package/dist/providers/claude/session-store.d.ts +24 -0
  49. package/dist/providers/claude/session-store.js +65 -12
  50. package/dist/providers/codex/adapter.d.ts +11 -0
  51. package/dist/providers/codex/adapter.js +19 -0
  52. package/dist/providers/codex/cli-client.d.ts +103 -0
  53. package/dist/providers/codex/cli-client.js +1133 -0
  54. package/dist/providers/codex/project-doc.d.ts +3 -0
  55. package/dist/providers/codex/project-doc.js +66 -0
  56. package/dist/providers/codex/session-store.d.ts +38 -0
  57. package/dist/providers/codex/session-store.js +150 -0
  58. package/dist/providers/copilot/adapter.d.ts +3 -1
  59. package/dist/providers/copilot/adapter.js +8 -12
  60. package/dist/providers/copilot/cli-client.d.ts +20 -2
  61. package/dist/providers/copilot/cli-client.js +251 -71
  62. package/dist/providers/copilot/session-store.d.ts +24 -0
  63. package/dist/providers/copilot/session-store.js +65 -12
  64. package/dist/providers/create-provider.d.ts +11 -2
  65. package/dist/providers/create-provider.js +131 -12
  66. package/dist/run.d.ts +1 -0
  67. package/dist/run.js +5 -2
  68. package/dist/state-paths.d.ts +13 -1
  69. package/dist/state-paths.js +84 -3
  70. package/dist/task-thread-resolution.d.ts +10 -0
  71. package/dist/task-thread-resolution.js +48 -0
  72. package/dist/types.d.ts +174 -1
  73. package/dist/visible-mentions.d.ts +3 -0
  74. package/dist/visible-mentions.js +15 -0
  75. package/package.json +19 -17
  76. package/skills/borgee-agent/SKILL.md +33 -0
  77. package/skills/borgee-agent/borgee-agent.mjs +473 -0
  78. package/skills/borgee-agent/borgee-agent.py +409 -0
@@ -1,9 +1,32 @@
1
1
  export interface ClaudeChannelSessionStore {
2
2
  load(agentId: string): Promise<Record<string, string>>;
3
3
  save(agentId: string, sessions: Record<string, string>): Promise<void>;
4
+ close?(): Promise<void> | void;
4
5
  }
5
6
  export interface FileClaudeChannelSessionStoreOptions {
6
7
  resolvePath(agentId: string): string;
8
+ fileSystem?: ClaudeSessionStoreFileSystem;
9
+ platform?: NodeJS.Platform;
10
+ }
11
+ interface ClaudeSessionStoreDirectoryHandle {
12
+ sync(): Promise<void>;
13
+ close(): Promise<void>;
14
+ }
15
+ interface ClaudeSessionStoreFileHandle extends ClaudeSessionStoreDirectoryHandle {
16
+ writeFile(data: string, options: {
17
+ encoding: BufferEncoding;
18
+ }): Promise<void>;
19
+ }
20
+ interface ClaudeSessionStoreFileSystem {
21
+ mkdir(path: string, options: {
22
+ recursive: true;
23
+ mode: number;
24
+ }): Promise<void>;
25
+ openDirectory(path: string): Promise<ClaudeSessionStoreDirectoryHandle>;
26
+ openFile(path: string, flags: string, mode: number): Promise<ClaudeSessionStoreFileHandle>;
27
+ readFile(path: string, encoding: BufferEncoding): Promise<string>;
28
+ rename(from: string, to: string): Promise<void>;
29
+ unlink(path: string): Promise<void>;
7
30
  }
8
31
  export declare class FileClaudeChannelSessionStore implements ClaudeChannelSessionStore {
9
32
  private readonly options;
@@ -12,3 +35,4 @@ export declare class FileClaudeChannelSessionStore implements ClaudeChannelSessi
12
35
  load(agentId: string): Promise<Record<string, string>>;
13
36
  save(agentId: string, sessions: Record<string, string>): Promise<void>;
14
37
  }
38
+ export {};
@@ -1,12 +1,63 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { mkdir, open, readFile, rename, unlink } from 'node:fs/promises';
3
3
  import { dirname } from 'node:path';
4
- async function syncDirectory(path) {
5
- const directoryHandle = await open(path, 'r');
4
+ const nodeFileSystem = {
5
+ async mkdir(path, options) {
6
+ await mkdir(path, options);
7
+ },
8
+ async openDirectory(path) {
9
+ return open(path, 'r');
10
+ },
11
+ async openFile(path, flags, mode) {
12
+ return open(path, flags, mode);
13
+ },
14
+ async readFile(path, encoding) {
15
+ return readFile(path, encoding);
16
+ },
17
+ async rename(from, to) {
18
+ await rename(from, to);
19
+ },
20
+ async unlink(path) {
21
+ await unlink(path);
22
+ },
23
+ };
24
+ function shouldIgnoreDirectorySyncError(platform, error) {
25
+ const code = error.code;
26
+ return platform === 'win32' && (code === 'EPERM' || code === 'EINVAL');
27
+ }
28
+ async function syncDirectory(path, fileSystem, platform) {
29
+ let directoryHandle;
6
30
  try {
7
- await directoryHandle.sync();
31
+ try {
32
+ directoryHandle = await fileSystem.openDirectory(path);
33
+ }
34
+ catch (error) {
35
+ if (!shouldIgnoreDirectorySyncError(platform, error)) {
36
+ throw error;
37
+ }
38
+ return;
39
+ }
40
+ try {
41
+ await directoryHandle.sync();
42
+ }
43
+ catch (error) {
44
+ if (!shouldIgnoreDirectorySyncError(platform, error)) {
45
+ throw error;
46
+ }
47
+ }
48
+ }
49
+ catch (error) {
50
+ if (directoryHandle) {
51
+ try {
52
+ await directoryHandle.close();
53
+ }
54
+ catch {
55
+ // Preserve the original directory durability failure.
56
+ }
57
+ }
58
+ throw error;
8
59
  }
9
- finally {
60
+ if (directoryHandle) {
10
61
  await directoryHandle.close();
11
62
  }
12
63
  }
@@ -32,7 +83,7 @@ export class FileClaudeChannelSessionStore {
32
83
  async loadFromPath(filePath) {
33
84
  let raw;
34
85
  try {
35
- raw = await readFile(filePath, 'utf8');
86
+ raw = await (this.options.fileSystem ?? nodeFileSystem).readFile(filePath, 'utf8');
36
87
  }
37
88
  catch (error) {
38
89
  throw error;
@@ -54,11 +105,13 @@ export class FileClaudeChannelSessionStore {
54
105
  async save(agentId, sessions) {
55
106
  const filePath = this.options.resolvePath(agentId);
56
107
  const parentPath = dirname(filePath);
57
- await mkdir(parentPath, { recursive: true, mode: 0o700 });
108
+ const fileSystem = this.options.fileSystem ?? nodeFileSystem;
109
+ const platform = this.options.platform ?? process.platform;
110
+ await fileSystem.mkdir(parentPath, { recursive: true, mode: 0o700 });
58
111
  const entries = Object.entries(sessions).sort(([left], [right]) => left.localeCompare(right));
59
112
  if (entries.length === 0) {
60
113
  try {
61
- await unlink(filePath);
114
+ await fileSystem.unlink(filePath);
62
115
  }
63
116
  catch (error) {
64
117
  if (error.code !== 'ENOENT') {
@@ -66,21 +119,21 @@ export class FileClaudeChannelSessionStore {
66
119
  }
67
120
  return;
68
121
  }
69
- await syncDirectory(parentPath);
122
+ await syncDirectory(parentPath, fileSystem, platform);
70
123
  return;
71
124
  }
72
125
  const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
73
126
  let temporaryHandle;
74
127
  try {
75
- temporaryHandle = await open(temporaryPath, 'wx', 0o600);
128
+ temporaryHandle = await fileSystem.openFile(temporaryPath, 'wx', 0o600);
76
129
  await temporaryHandle.writeFile(JSON.stringify(Object.fromEntries(entries)), {
77
130
  encoding: 'utf8',
78
131
  });
79
132
  await temporaryHandle.sync();
80
133
  await temporaryHandle.close();
81
134
  temporaryHandle = undefined;
82
- await rename(temporaryPath, filePath);
83
- await syncDirectory(parentPath);
135
+ await fileSystem.rename(temporaryPath, filePath);
136
+ await syncDirectory(parentPath, fileSystem, platform);
84
137
  }
85
138
  catch (error) {
86
139
  if (temporaryHandle) {
@@ -92,7 +145,7 @@ export class FileClaudeChannelSessionStore {
92
145
  }
93
146
  }
94
147
  try {
95
- await unlink(temporaryPath);
148
+ await fileSystem.unlink(temporaryPath);
96
149
  }
97
150
  catch {
98
151
  // Cleanup is best effort.
@@ -0,0 +1,11 @@
1
+ import type { ProviderAdapter } from '../provider-adapter.js';
2
+ import type { ProviderGenerateOptions, ProviderInput, ProviderReply } from '../../types.js';
3
+ import { ProviderTurnPreparer } from '../../context/turn-preparation.js';
4
+ import { CodexCliClient } from './cli-client.js';
5
+ export declare class CodexProviderAdapter implements ProviderAdapter {
6
+ private readonly cli;
7
+ private readonly turnPreparer;
8
+ constructor(cli: CodexCliClient, turnPreparer: ProviderTurnPreparer);
9
+ generateReply(input: ProviderInput, options?: ProviderGenerateOptions): Promise<ProviderReply>;
10
+ dispose(): Promise<void>;
11
+ }
@@ -0,0 +1,19 @@
1
+ import { createAwaitingUserProgressHandler, parseProviderReply } from '../awaiting-user.js';
2
+ export class CodexProviderAdapter {
3
+ cli;
4
+ turnPreparer;
5
+ constructor(cli, turnPreparer) {
6
+ this.cli = cli;
7
+ this.turnPreparer = turnPreparer;
8
+ }
9
+ async generateReply(input, options) {
10
+ const preparedTurn = await this.turnPreparer.prepare(input);
11
+ const text = await this.cli.generateReply(preparedTurn, {
12
+ onProgress: createAwaitingUserProgressHandler(options?.onProgress),
13
+ });
14
+ return parseProviderReply(text);
15
+ }
16
+ async dispose() {
17
+ await this.cli.dispose();
18
+ }
19
+ }
@@ -0,0 +1,103 @@
1
+ import spawn from 'cross-spawn';
2
+ import { PROTOCOL_VERSION, client, methods, ndJsonStream } from '@agentclientprotocol/sdk';
3
+ import { type DebugLogger } from '../../debug.js';
4
+ import type { PreparedProviderTurnInput, ProviderGenerateOptions } from '../../types.js';
5
+ import type { CodexChannelSessionStore } from './session-store.js';
6
+ interface CodexAcpRuntime {
7
+ spawn: typeof spawn;
8
+ client: typeof client;
9
+ ndJsonStream: typeof ndJsonStream;
10
+ methods: typeof methods;
11
+ protocolVersion: typeof PROTOCOL_VERSION;
12
+ cwd: string;
13
+ idleSessionTtlMs: number;
14
+ shutdownGracePeriodMs: number;
15
+ shutdownForceKillWaitMs: number;
16
+ readFile(path: string, options?: {
17
+ encoding?: BufferEncoding;
18
+ }): Promise<string>;
19
+ readdir(path: string): Promise<string[]>;
20
+ writeFile(path: string, data: string, options?: {
21
+ encoding?: BufferEncoding;
22
+ mode?: number;
23
+ }): Promise<void>;
24
+ mkdir(path: string, options?: {
25
+ recursive?: boolean;
26
+ mode?: number;
27
+ }): Promise<void>;
28
+ unlink(path: string): Promise<void>;
29
+ }
30
+ export declare class CodexCliClient {
31
+ private readonly command;
32
+ private readonly args;
33
+ private readonly sessionStore?;
34
+ private readonly resolveSessionStoreAgentId;
35
+ private readonly logger;
36
+ private readonly runtime;
37
+ private readonly channels;
38
+ private readonly persistedSessions;
39
+ private readonly closingSessions;
40
+ private readonly pendingSessionStarts;
41
+ private readonly pendingSessionCloses;
42
+ private readonly pendingSessionStoreOperations;
43
+ private readonly fatalPromise;
44
+ private rejectFatalPromise;
45
+ private child?;
46
+ private connection?;
47
+ private startPromise?;
48
+ private shutdownPromise?;
49
+ private childExitPromise?;
50
+ private resolveChildExit?;
51
+ private fatalError;
52
+ private disposing;
53
+ private backendClosed;
54
+ private loadedSessionStoreAgentId;
55
+ private sessionStoreLoadPromise;
56
+ private sessionStoreWriteQueue;
57
+ private sessionCapabilities;
58
+ constructor(command: string, args?: string[], runtimeOverrides?: Partial<CodexAcpRuntime>, sessionStore?: CodexChannelSessionStore | undefined, resolveSessionStoreAgentId?: () => string | undefined, logger?: DebugLogger);
59
+ generateReply(turn: PreparedProviderTurnInput, options?: ProviderGenerateOptions): Promise<string>;
60
+ generateReply(channelId: string, prompt: string, options?: ProviderGenerateOptions): Promise<string>;
61
+ dispose(): Promise<void>;
62
+ private ensureStarted;
63
+ private startBackend;
64
+ private getOrCreateChannelState;
65
+ private processChannelQueue;
66
+ private getOrCreateSession;
67
+ private startFreshSession;
68
+ private restoreOrCreateSession;
69
+ private restoreSession;
70
+ private clearBufferedSessionReplay;
71
+ private resolveSessionCwd;
72
+ private recycleSessionIfInjectionScopeChanged;
73
+ private resolveSessionAdditionalDirectories;
74
+ private resolveSessionVisibilityKey;
75
+ private resolveProjectedContextDirectory;
76
+ private buildProjectedPromptContext;
77
+ private copyProjectedFile;
78
+ private pruneProjectedGatewayAuthFiles;
79
+ private refreshProjectedPromptContextBestEffort;
80
+ private rewritePromptContextPaths;
81
+ private runTurn;
82
+ private raceWithFatal;
83
+ private invalidateSession;
84
+ private rejectQueuedTurnsAfterSessionTaint;
85
+ private failAll;
86
+ private closeSession;
87
+ private clearIdleTimer;
88
+ private reconcileIdleChannelState;
89
+ private ensureSessionStoreLoaded;
90
+ private readPersistedSessionId;
91
+ private persistSession;
92
+ private persistSessionBestEffort;
93
+ private clearPersistedSession;
94
+ private clearPersistedSessionBestEffort;
95
+ private flushSessionStore;
96
+ private trackSessionStoreOperation;
97
+ private evictIdleChannel;
98
+ private shutdownBackend;
99
+ private waitForPendingSessionStarts;
100
+ private waitForPendingSessionCloses;
101
+ private waitForChildExit;
102
+ }
103
+ export {};