@borgee/agents-host 0.2.44 → 0.2.56
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.
- package/README.md +23 -27
- package/dist/agents-host.d.ts +26 -5
- package/dist/agents-host.js +163 -192
- package/dist/chat/chat-control-plane.d.ts +3 -0
- package/dist/chat/sdk-chat-control-plane.d.ts +4 -3
- package/dist/chat/sdk-chat-control-plane.js +3 -0
- package/dist/cli.js +1 -5
- package/dist/compatibility-gates.d.ts +4 -0
- package/dist/compatibility-gates.js +18 -1
- package/dist/context/claude-file-brief.d.ts +2 -0
- package/dist/context/claude-file-brief.js +83 -0
- package/dist/context/compaction.d.ts +20 -0
- package/dist/context/compaction.js +59 -0
- package/dist/context/injection.d.ts +39 -6
- package/dist/context/injection.js +317 -26
- package/dist/context/main-session-delegation.d.ts +1 -1
- package/dist/context/projection-strategy.d.ts +24 -0
- package/dist/context/projection-strategy.js +90 -0
- package/dist/context/prompt.d.ts +16 -1
- package/dist/context/prompt.js +456 -22
- package/dist/context/resolved-workspace.d.ts +2 -0
- package/dist/context/resolved-workspace.js +64 -0
- package/dist/context/skill-manual.d.ts +1 -0
- package/dist/context/skill-manual.js +4 -1
- package/dist/context/turn-preparation.d.ts +8 -2
- package/dist/context/turn-preparation.js +56 -14
- package/dist/gateway/localhost-gateway.js +2 -0
- package/dist/managed-daemon.js +122 -9
- package/dist/plugin-sdk.js +276 -359
- package/dist/plugin-sdk.js.map +4 -4
- package/dist/progress-to-activity.d.ts +16 -0
- package/dist/progress-to-activity.js +24 -0
- package/dist/projection-strategy-values.d.ts +4 -0
- package/dist/projection-strategy-values.js +28 -0
- package/dist/providers/acp-progress-collector.d.ts +44 -0
- package/dist/providers/acp-progress-collector.js +130 -0
- package/dist/providers/awaiting-user.d.ts +2 -3
- package/dist/providers/awaiting-user.js +5 -7
- package/dist/providers/claude/activity-metadata.d.ts +14 -0
- package/dist/providers/claude/activity-metadata.js +81 -0
- package/dist/providers/claude/cli-client.d.ts +1 -2
- package/dist/providers/claude/cli-client.js +190 -117
- package/dist/providers/codex/cli-client.js +3 -83
- package/dist/providers/codex/project-doc.js +12 -11
- package/dist/providers/copilot/cli-client.js +3 -83
- package/dist/providers/create-provider.d.ts +2 -0
- package/dist/providers/create-provider.js +20 -4
- package/dist/state-paths.d.ts +1 -1
- package/dist/state-paths.js +3 -3
- package/dist/task-thread-resolution.d.ts +3 -2
- package/dist/types.d.ts +130 -6
- package/package.json +2 -2
- package/skills/borgee-agent/SKILL.md +9 -1
- package/skills/borgee-agent/references/task-properties.md +5 -2
- package/dist/durable-cursor-store.d.ts +0 -5
- package/dist/durable-cursor-store.js +0 -7
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { type DebugLogger } from '../debug.js';
|
|
2
|
-
import type { PreparedProviderTurnInput, ProviderInput } from '../types.js';
|
|
2
|
+
import type { ProjectionStrategy, PreparedProviderTurnInput, ProviderInput } from '../types.js';
|
|
3
3
|
import { type ChannelContextStore } from './injection.js';
|
|
4
|
+
type ResolveProjectionStrategy = (input: ProviderInput) => Promise<ProjectionStrategy>;
|
|
4
5
|
export declare class ProviderTurnPreparer {
|
|
5
6
|
private readonly channelContextStore?;
|
|
6
7
|
private readonly logger;
|
|
7
|
-
|
|
8
|
+
private readonly resolveProjectionStrategy;
|
|
9
|
+
constructor(channelContextStore?: ChannelContextStore | undefined, logger?: DebugLogger, options?: {
|
|
10
|
+
projectionStrategy?: ProjectionStrategy;
|
|
11
|
+
resolveProjectionStrategy?: ResolveProjectionStrategy;
|
|
12
|
+
});
|
|
8
13
|
prepare(input: ProviderInput): Promise<PreparedProviderTurnInput>;
|
|
9
14
|
}
|
|
15
|
+
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { HostLogger, summarizeError } from '../debug.js';
|
|
2
|
+
import { DEFAULT_PROJECTION_STRATEGY } from '../projection-strategy-values.js';
|
|
2
3
|
import { buildHostedIncomingContentText, buildHostedTurnContentParts } from '../hosted-turn-content.js';
|
|
3
|
-
import { ChannelContextPreparationError, } from './injection.js';
|
|
4
|
-
import { buildPrompt } from './prompt.js';
|
|
4
|
+
import { buildRuntimeSurfaceForTurn, ChannelContextPreparationError, } from './injection.js';
|
|
5
|
+
import { buildClaudeSessionPromptAppend, buildClaudeTurnPrompt, buildPrompt } from './prompt.js';
|
|
5
6
|
function providerLabel(provider) {
|
|
6
7
|
if (provider === 'copilot') {
|
|
7
8
|
return 'Copilot';
|
|
@@ -16,26 +17,36 @@ function toPromptContext(channelContext, input) {
|
|
|
16
17
|
&& !input.collaboration
|
|
17
18
|
&& !input.collaborationOutcome
|
|
18
19
|
&& !input.attentionSnapshot
|
|
20
|
+
&& !input.compactionSnapshot
|
|
19
21
|
&& !input.collaborationCapabilities
|
|
20
22
|
&& !input.missedCollaborationDiagnostic
|
|
21
23
|
&& !input.taskThreadCollaborationContract) {
|
|
22
24
|
return undefined;
|
|
23
25
|
}
|
|
26
|
+
const runtimeSurface = channelContext?.payload.runtimeSurface ?? buildRuntimeSurfaceForTurn({
|
|
27
|
+
localhostGateway: channelContext?.payload.localhostGateway ?? channelContext?.localhostGateway,
|
|
28
|
+
collaboration: input.collaboration,
|
|
29
|
+
taskAssignmentContext: channelContext?.payload.taskAssignmentContext,
|
|
30
|
+
});
|
|
24
31
|
return {
|
|
25
32
|
...(channelContext
|
|
26
33
|
? {
|
|
27
34
|
channelContextPayloadPath: channelContext.payloadPath,
|
|
35
|
+
claudeProjectedBriefPath: channelContext.claudeProjectedBriefPath,
|
|
36
|
+
claudeProjectedBriefHash: channelContext.claudeProjectedBriefHash,
|
|
28
37
|
gatewayCredentialPath: channelContext.gatewayCredentialPath,
|
|
29
38
|
skillRuntime: channelContext.skillRuntime,
|
|
30
39
|
localhostGateway: channelContext.localhostGateway,
|
|
31
40
|
taskAssignmentContext: channelContext.payload.taskAssignmentContext,
|
|
32
|
-
|
|
41
|
+
resolvedWorkspace: channelContext.resolvedWorkspace,
|
|
33
42
|
}
|
|
34
43
|
: {}),
|
|
44
|
+
runtimeSurface,
|
|
35
45
|
collaborationTurnExecutionId: input.collaboration?.turnExecutionId,
|
|
36
46
|
collaborationTurnMode: input.collaboration?.turnMode,
|
|
37
47
|
collaborationOutcome: input.collaborationOutcome ?? channelContext?.payload.collaborationOutcome,
|
|
38
48
|
attentionSnapshot: input.attentionSnapshot ?? channelContext?.payload.attentionSnapshot,
|
|
49
|
+
compactionSnapshot: input.compactionSnapshot ?? channelContext?.payload.compactionSnapshot,
|
|
39
50
|
...(() => {
|
|
40
51
|
const collaborationCapabilities = input.collaborationCapabilities ?? channelContext?.payload.collaborationCapabilities;
|
|
41
52
|
return collaborationCapabilities ? { collaborationCapabilities } : {};
|
|
@@ -71,9 +82,12 @@ function resolveProviderSessionRouting(input) {
|
|
|
71
82
|
export class ProviderTurnPreparer {
|
|
72
83
|
channelContextStore;
|
|
73
84
|
logger;
|
|
74
|
-
|
|
85
|
+
resolveProjectionStrategy;
|
|
86
|
+
constructor(channelContextStore, logger = new HostLogger(), options = {}) {
|
|
75
87
|
this.channelContextStore = channelContextStore;
|
|
76
88
|
this.logger = logger;
|
|
89
|
+
this.resolveProjectionStrategy = options.resolveProjectionStrategy
|
|
90
|
+
?? (async () => options.projectionStrategy ?? DEFAULT_PROJECTION_STRATEGY);
|
|
77
91
|
}
|
|
78
92
|
async prepare(input) {
|
|
79
93
|
const incomingParts = input.incomingParts ?? buildHostedTurnContentParts({
|
|
@@ -82,11 +96,16 @@ export class ProviderTurnPreparer {
|
|
|
82
96
|
const incomingContent = incomingParts.length > 0
|
|
83
97
|
? buildHostedIncomingContentText(incomingParts)
|
|
84
98
|
: input.incomingContent;
|
|
99
|
+
const projectionStrategy = input.provider === 'claude'
|
|
100
|
+
? await this.resolveProjectionStrategy(input)
|
|
101
|
+
: undefined;
|
|
85
102
|
let channelContext;
|
|
86
103
|
if (this.channelContextStore) {
|
|
87
104
|
try {
|
|
88
105
|
const prepareInput = {
|
|
89
106
|
channelId: input.channelId,
|
|
107
|
+
provider: input.provider,
|
|
108
|
+
projectionStrategy,
|
|
90
109
|
collaboration: input.collaboration
|
|
91
110
|
? {
|
|
92
111
|
...input.collaboration,
|
|
@@ -96,6 +115,7 @@ export class ProviderTurnPreparer {
|
|
|
96
115
|
: undefined,
|
|
97
116
|
collaborationOutcome: input.collaborationOutcome,
|
|
98
117
|
attentionSnapshot: input.attentionSnapshot,
|
|
118
|
+
compactionSnapshot: input.compactionSnapshot,
|
|
99
119
|
collaborationCapabilities: input.collaborationCapabilities,
|
|
100
120
|
missedCollaborationDiagnostic: input.missedCollaborationDiagnostic,
|
|
101
121
|
...(input.taskThreadCollaborationContract
|
|
@@ -122,21 +142,43 @@ export class ProviderTurnPreparer {
|
|
|
122
142
|
}
|
|
123
143
|
const promptContext = toPromptContext(channelContext, input);
|
|
124
144
|
return {
|
|
145
|
+
agentName: input.agentName,
|
|
125
146
|
channelId: input.channelId,
|
|
126
147
|
incomingContent,
|
|
127
148
|
incomingParts,
|
|
128
149
|
incomingEventKind: input.incomingEventKind,
|
|
129
150
|
incomingMessageType: input.incomingMessageType,
|
|
130
|
-
prompt:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
151
|
+
prompt: input.provider === 'claude'
|
|
152
|
+
? buildClaudeTurnPrompt({
|
|
153
|
+
agentName: input.agentName,
|
|
154
|
+
channelId: input.channelId,
|
|
155
|
+
incomingAuthorId: input.incomingAuthorId,
|
|
156
|
+
incomingContent,
|
|
157
|
+
incomingEventKind: input.incomingEventKind,
|
|
158
|
+
incomingMessageType: input.incomingMessageType,
|
|
159
|
+
promptContext,
|
|
160
|
+
promptStrategy: projectionStrategy,
|
|
161
|
+
})
|
|
162
|
+
: buildPrompt({
|
|
163
|
+
agentName: input.agentName,
|
|
164
|
+
provider: input.provider,
|
|
165
|
+
channelId: input.channelId,
|
|
166
|
+
incomingAuthorId: input.incomingAuthorId,
|
|
167
|
+
incomingContent,
|
|
168
|
+
incomingEventKind: input.incomingEventKind,
|
|
169
|
+
incomingMessageType: input.incomingMessageType,
|
|
170
|
+
promptContext,
|
|
171
|
+
}),
|
|
172
|
+
...(input.provider === 'claude'
|
|
173
|
+
? {
|
|
174
|
+
claudeSessionPromptAppend: buildClaudeSessionPromptAppend({
|
|
175
|
+
agentName: input.agentName,
|
|
176
|
+
promptContext,
|
|
177
|
+
promptStrategy: projectionStrategy,
|
|
178
|
+
}),
|
|
179
|
+
projectionStrategy,
|
|
180
|
+
}
|
|
181
|
+
: {}),
|
|
140
182
|
promptContext,
|
|
141
183
|
providerSessionRouting: resolveProviderSessionRouting(input),
|
|
142
184
|
};
|
|
@@ -910,6 +910,8 @@ function mapGatewayControlPlaneError(error, fallbackReason) {
|
|
|
910
910
|
// is broken, and it would retry the same bad call instead of correcting it.
|
|
911
911
|
case 'bpp.task_property_key_unknown':
|
|
912
912
|
return new GatewayHttpError(400, { error: 'unknown_property_key' }, 'bad-request');
|
|
913
|
+
case 'bpp.task_property_value_invalid':
|
|
914
|
+
return new GatewayHttpError(400, { error: 'invalid_property_value' }, 'bad-request');
|
|
913
915
|
case 'bpp.task_property_value_too_long':
|
|
914
916
|
return new GatewayHttpError(400, { error: 'property_value_too_long' }, 'bad-request');
|
|
915
917
|
case 'bpp.task_invalid_status':
|
package/dist/managed-daemon.js
CHANGED
|
@@ -2,13 +2,15 @@ import { createHash, randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { promises as fs } from 'node:fs';
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
4
|
import { createConnection, createServer } from 'node:net';
|
|
5
|
-
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { AgentsHostSupervisor } from './agents-host-supervisor.js';
|
|
8
|
-
import {
|
|
8
|
+
import { DEFAULT_PROJECTION_STRATEGY, normalizeProjectionStrategy, } from './projection-strategy-values.js';
|
|
9
|
+
import { resolveChannelWorkspaceDirectory, resolveChannelWorkspaceRootDirectory, resolveManagedWorkspaceCollectionRoot, resolveTaskWorkspaceDirectory, } from './context/injection.js';
|
|
10
|
+
import { CLAUDE_PROVIDER_V2_COMPATIBILITY_GATE, COMPATIBILITY_GATES_ENV, createManagedRuntimeSettingsFingerprint, INTERNAL_CLAUDE_PROMPT_STRATEGY_ENV, INTERNAL_DISABLED_COMPATIBILITY_GATES_ENV, INTERNAL_POLICY_MODE_ENV, INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV, MANAGED_RUNTIME_CONVERGENCE_COMPATIBILITY_GATE, MANAGED_RUNTIME_SETTINGS_SCHEMA_VERSION, resolveDisabledDefaultCompatibilityGates, resolveManagedRuntimeSettingsSnapshot, serializeManagedRuntimeSettingsSnapshot, normalizeInternalProviderImplementationOverrides, } from './compatibility-gates.js';
|
|
9
11
|
import { DEFAULT_PROVIDER_COMMAND_CONFIG, hasLegacyClaudeOneShotArgs, loadConfigFromEnv, } from './config.js';
|
|
10
12
|
import { loadLocalConfigGenerateSpec, materializeLocalConfig, parseGenerateConfigSpec, resolveLocalConfigLayout, } from './local-config.js';
|
|
11
|
-
import { normalizeManagedRuntimeKey, resolveManagedBootstrapLockPath, resolveManagedDaemonEndpoint, resolveManagedDaemonLogPath, resolveManagedRuntimeRoot, resolveManagedRuntimeSettingsPath, } from './state-paths.js';
|
|
13
|
+
import { normalizeManagedRuntimeKey, resolveManagedBootstrapLockPath, resolveManagedDaemonEndpoint, resolveManagedDaemonLogPath, resolveManagedRuntimeRoot, resolveManagedStateRoot, resolveManagedRuntimeSettingsPath, } from './state-paths.js';
|
|
12
14
|
const MANAGED_ROOT_MODE = 0o700;
|
|
13
15
|
const MANAGED_CONFIG_MODE = 0o600;
|
|
14
16
|
const BOOTSTRAP_LOCK_WAIT_MS = 10_000;
|
|
@@ -48,6 +50,9 @@ function isAlreadyExistsError(error) {
|
|
|
48
50
|
function isSocketBusyError(error) {
|
|
49
51
|
return isNodeErrorWithCode(error, 'EADDRINUSE');
|
|
50
52
|
}
|
|
53
|
+
function isRecord(value) {
|
|
54
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
55
|
+
}
|
|
51
56
|
function delay(milliseconds) {
|
|
52
57
|
return new Promise((resolveDelay) => {
|
|
53
58
|
setTimeout(resolveDelay, milliseconds);
|
|
@@ -157,6 +162,7 @@ function normalizeManagedRuntimeSettingsSnapshot(snapshot) {
|
|
|
157
162
|
compatibilityGates,
|
|
158
163
|
providerImplementationOverrides,
|
|
159
164
|
internalPolicyMode: snapshot.internalPolicyMode,
|
|
165
|
+
projectionStrategy: snapshot.projectionStrategy ?? DEFAULT_PROJECTION_STRATEGY,
|
|
160
166
|
};
|
|
161
167
|
}
|
|
162
168
|
function parseManagedRuntimeSettingsSnapshotRecord(value, sourceLabel) {
|
|
@@ -178,11 +184,19 @@ function parseManagedRuntimeSettingsSnapshotRecord(value, sourceLabel) {
|
|
|
178
184
|
if (record.internalPolicyMode !== 'audit-only' && record.internalPolicyMode !== 'enforce') {
|
|
179
185
|
throw new Error(`Invalid ${sourceLabel}: expected internalPolicyMode to be "audit-only" or "enforce"`);
|
|
180
186
|
}
|
|
187
|
+
const rawProjectionStrategy = typeof record.projectionStrategy === 'string'
|
|
188
|
+
? record.projectionStrategy
|
|
189
|
+
: record.claudePromptStrategy;
|
|
190
|
+
const projectionStrategy = normalizeProjectionStrategy(rawProjectionStrategy);
|
|
191
|
+
if (rawProjectionStrategy !== undefined && !projectionStrategy) {
|
|
192
|
+
throw new Error(`Invalid ${sourceLabel}: expected projectionStrategy to be "session-brief", "turn-full", "message-only", "turn-thin", or "file-brief"`);
|
|
193
|
+
}
|
|
181
194
|
return normalizeManagedRuntimeSettingsSnapshot({
|
|
182
195
|
schemaVersion: MANAGED_RUNTIME_SETTINGS_SCHEMA_VERSION,
|
|
183
196
|
compatibilityGates: [...record.compatibilityGates],
|
|
184
197
|
providerImplementationOverrides: [...record.providerImplementationOverrides],
|
|
185
198
|
internalPolicyMode: record.internalPolicyMode,
|
|
199
|
+
projectionStrategy: projectionStrategy ?? DEFAULT_PROJECTION_STRATEGY,
|
|
186
200
|
});
|
|
187
201
|
}
|
|
188
202
|
async function loadManagedRuntimeSettingsSnapshot(rootPath) {
|
|
@@ -205,7 +219,7 @@ async function writeManagedRuntimeSettingsSnapshot(rootPath, snapshot) {
|
|
|
205
219
|
await ensureDirectory(rootPath, MANAGED_ROOT_MODE);
|
|
206
220
|
const settingsPath = resolveManagedRuntimeSettingsPath(rootPath);
|
|
207
221
|
const normalizedSnapshot = normalizeManagedRuntimeSettingsSnapshot(snapshot);
|
|
208
|
-
await fs.writeFile(settingsPath, `${
|
|
222
|
+
await fs.writeFile(settingsPath, `${serializeManagedRuntimeSettingsSnapshot(normalizedSnapshot)}\n`, {
|
|
209
223
|
encoding: 'utf8',
|
|
210
224
|
mode: MANAGED_CONFIG_MODE,
|
|
211
225
|
});
|
|
@@ -226,6 +240,7 @@ function buildManagedRuntimeSettingsEnv(baseEnv, snapshot) {
|
|
|
226
240
|
[INTERNAL_DISABLED_COMPATIBILITY_GATES_ENV]: resolveDisabledDefaultCompatibilityGates(snapshot.compatibilityGates).join(','),
|
|
227
241
|
[INTERNAL_PROVIDER_IMPLEMENTATIONS_ENV]: snapshot.providerImplementationOverrides.join(','),
|
|
228
242
|
[INTERNAL_POLICY_MODE_ENV]: snapshot.internalPolicyMode,
|
|
243
|
+
[INTERNAL_CLAUDE_PROMPT_STRATEGY_ENV]: snapshot.projectionStrategy,
|
|
229
244
|
};
|
|
230
245
|
}
|
|
231
246
|
function buildDesiredManagedRuntimeSettingsFromSnapshot(snapshot) {
|
|
@@ -819,6 +834,101 @@ async function shutdownManagedDaemon(rootPath, sendRequest, waitForShutdown) {
|
|
|
819
834
|
}
|
|
820
835
|
await waitForShutdown(rootPath);
|
|
821
836
|
}
|
|
837
|
+
function resolveTrustedPersistedChannelWorkspaceRoot(workspaceCollectionRoot, owningChannelId, rootPath) {
|
|
838
|
+
if (!owningChannelId || !isAbsolute(rootPath)) {
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
841
|
+
const expectedWorkspacePath = resolveChannelWorkspaceDirectory(workspaceCollectionRoot, owningChannelId);
|
|
842
|
+
if (rootPath !== expectedWorkspacePath) {
|
|
843
|
+
return null;
|
|
844
|
+
}
|
|
845
|
+
return resolveChannelWorkspaceRootDirectory(workspaceCollectionRoot, owningChannelId);
|
|
846
|
+
}
|
|
847
|
+
async function discoverManagedWorkspaceRootsForPurge(rootPath, processEnv) {
|
|
848
|
+
const trustedWorkspaceCollectionRoots = new Set([
|
|
849
|
+
resolveManagedWorkspaceCollectionRoot(undefined, processEnv),
|
|
850
|
+
]);
|
|
851
|
+
const managedStateRoot = resolveManagedStateRoot(rootPath);
|
|
852
|
+
const agentStateEntries = await fs.readdir(managedStateRoot, { withFileTypes: true }).catch((error) => {
|
|
853
|
+
if (isNotFoundError(error)) {
|
|
854
|
+
return [];
|
|
855
|
+
}
|
|
856
|
+
throw error;
|
|
857
|
+
});
|
|
858
|
+
const workspaceRoots = new Set();
|
|
859
|
+
for (const agentStateEntry of agentStateEntries) {
|
|
860
|
+
if (!agentStateEntry.isDirectory()) {
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
const channelContextRoot = join(managedStateRoot, agentStateEntry.name, 'channel-context');
|
|
864
|
+
const channelEntries = await fs.readdir(channelContextRoot, { withFileTypes: true }).catch((error) => {
|
|
865
|
+
if (isNotFoundError(error)) {
|
|
866
|
+
return [];
|
|
867
|
+
}
|
|
868
|
+
throw error;
|
|
869
|
+
});
|
|
870
|
+
for (const channelEntry of channelEntries) {
|
|
871
|
+
if (!channelEntry.isDirectory()) {
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
874
|
+
const payloadPath = join(channelContextRoot, channelEntry.name, 'context.json');
|
|
875
|
+
const payload = await fs.readFile(payloadPath, 'utf8').catch((error) => {
|
|
876
|
+
if (isNotFoundError(error)) {
|
|
877
|
+
return undefined;
|
|
878
|
+
}
|
|
879
|
+
throw error;
|
|
880
|
+
});
|
|
881
|
+
if (!payload) {
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
884
|
+
let parsed;
|
|
885
|
+
try {
|
|
886
|
+
parsed = JSON.parse(payload);
|
|
887
|
+
}
|
|
888
|
+
catch {
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
if (!isRecord(parsed) || typeof parsed.channelId !== 'string' || !isRecord(parsed.resolvedWorkspace)) {
|
|
892
|
+
continue;
|
|
893
|
+
}
|
|
894
|
+
const resolvedWorkspace = parsed.resolvedWorkspace;
|
|
895
|
+
if ((resolvedWorkspace.authority !== 'channel' && resolvedWorkspace.authority !== 'task')
|
|
896
|
+
|| typeof resolvedWorkspace.rootPath !== 'string'
|
|
897
|
+
|| !isAbsolute(resolvedWorkspace.rootPath)) {
|
|
898
|
+
continue;
|
|
899
|
+
}
|
|
900
|
+
for (const workspaceCollectionRoot of trustedWorkspaceCollectionRoots) {
|
|
901
|
+
if (resolvedWorkspace.authority === 'channel') {
|
|
902
|
+
if (typeof resolvedWorkspace.owningChannelId !== 'string'
|
|
903
|
+
|| resolvedWorkspace.owningChannelId.length === 0) {
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
906
|
+
const trustedChannelWorkspaceRoot = resolveTrustedPersistedChannelWorkspaceRoot(workspaceCollectionRoot, resolvedWorkspace.owningChannelId, resolvedWorkspace.rootPath);
|
|
907
|
+
if (!trustedChannelWorkspaceRoot) {
|
|
908
|
+
continue;
|
|
909
|
+
}
|
|
910
|
+
workspaceRoots.add(trustedChannelWorkspaceRoot);
|
|
911
|
+
break;
|
|
912
|
+
}
|
|
913
|
+
const expectedWorkspacePath = resolvedWorkspace.authority === 'task'
|
|
914
|
+
? typeof resolvedWorkspace.taskId === 'string' && resolvedWorkspace.taskId.length > 0
|
|
915
|
+
? resolveTaskWorkspaceDirectory(workspaceCollectionRoot, parsed.channelId, resolvedWorkspace.taskId)
|
|
916
|
+
: null
|
|
917
|
+
: null;
|
|
918
|
+
if (!expectedWorkspacePath) {
|
|
919
|
+
continue;
|
|
920
|
+
}
|
|
921
|
+
if (resolvedWorkspace.rootPath !== expectedWorkspacePath) {
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
workspaceRoots.add(dirname(expectedWorkspacePath));
|
|
925
|
+
workspaceRoots.add(resolveChannelWorkspaceRootDirectory(workspaceCollectionRoot, parsed.channelId));
|
|
926
|
+
break;
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
return [...workspaceRoots].sort((left, right) => left.localeCompare(right));
|
|
931
|
+
}
|
|
822
932
|
export async function cleanupManagedRuntime(options, deps = {}) {
|
|
823
933
|
const sendRequest = deps.sendRequest ?? sendManagedDaemonRequest;
|
|
824
934
|
const removeRuntimeRoot = deps.removeRuntimeRoot ??
|
|
@@ -855,6 +965,9 @@ export async function cleanupManagedRuntime(options, deps = {}) {
|
|
|
855
965
|
await waitForShutdown(resolved.rootPath);
|
|
856
966
|
}
|
|
857
967
|
if (options.purge === true) {
|
|
968
|
+
for (const workspaceRoot of await discoverManagedWorkspaceRootsForPurge(resolved.rootPath, options.processEnv ?? process.env)) {
|
|
969
|
+
await fs.rm(workspaceRoot, { recursive: true, force: true });
|
|
970
|
+
}
|
|
858
971
|
await removeRuntimeRoot(resolved.rootPath);
|
|
859
972
|
}
|
|
860
973
|
}
|
|
@@ -900,16 +1013,16 @@ export async function spawnManagedDaemonProcess(options, deps = {}) {
|
|
|
900
1013
|
}
|
|
901
1014
|
const thisPath = fileURLToPath(import.meta.url);
|
|
902
1015
|
const cliEntrypointPath = join(dirname(thisPath), thisPath.endsWith('.ts') ? 'cli.ts' : 'cli.js');
|
|
1016
|
+
const baseEnv = {
|
|
1017
|
+
...process.env,
|
|
1018
|
+
...(options.processEnv ?? {}),
|
|
1019
|
+
};
|
|
903
1020
|
return spawnDetachedProcess({
|
|
904
1021
|
rootPath: options.rootPath,
|
|
905
1022
|
command: process.execPath,
|
|
906
1023
|
env: {
|
|
907
|
-
...buildManagedRuntimeSettingsEnv(
|
|
908
|
-
...process.env,
|
|
909
|
-
...(options.processEnv ?? {}),
|
|
910
|
-
}, managedRuntimeSettingsSnapshot),
|
|
1024
|
+
...buildManagedRuntimeSettingsEnv(baseEnv, managedRuntimeSettingsSnapshot),
|
|
911
1025
|
AGENTS_HOST_MANAGED_DAEMON_LOG_PATH: resolveManagedDaemonLogPath(options.rootPath),
|
|
912
|
-
AGENTS_HOST_INTERNAL_TASK_WORKSPACE_ROOT_DIR: options.rootPath,
|
|
913
1026
|
},
|
|
914
1027
|
args: [
|
|
915
1028
|
...process.execArgv,
|