@agenthippo-ai/agenthippo 0.2.3-dataplane → 1.110.11
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/out/agentpack/index.js +3 -1
- package/out/agentpack/paths.js +25 -2
- package/out/analytics/dashboard/localFleetAdapter.js +82 -2
- package/out/analytics/dashboard/provider.js +13 -2
- package/out/analytics/dashboard/webview/panel.js +3 -2
- package/out/analytics/identity.js +0 -0
- package/out/analytics/service.js +29 -25
- package/out/analytics/sessionEvents.js +100 -24
- package/out/auth/authBaseUrl.js +59 -0
- package/out/auth/bootstrapApply.js +9 -10
- package/out/auth/brokerClient.js +48 -14
- package/out/auth/provider.js +8 -21
- package/out/auth/sessionStore.js +3 -40
- package/out/auth/signInFlow.js +2 -1
- package/out/auth-broker/config.js +50 -5
- package/out/auth-broker/server.js +126 -26
- package/out/auth-broker/store.js +25 -24
- package/out/authority/warrant.js +206 -0
- package/out/branding.js +27 -1
- package/out/cli/commands/conformance.js +249 -0
- package/out/cli/commands/data-plane.js +151 -0
- package/out/cli/commands/deploy.js +1 -0
- package/out/cli/commands/gateway.js +4 -0
- package/out/cli/commands/pack.js +182 -3
- package/out/cli/commands/sandbox.js +351 -0
- package/out/cli/commands/serve.js +1145 -130
- package/out/cli/commands/store.js +12 -4
- package/out/cli/credential-context.js +17 -0
- package/out/cli/data-plane/gateway.js +28 -5
- package/out/cli/data-plane/index.js +18 -2
- package/out/cli/data-plane/registry.js +9 -0
- package/out/cli/data-plane/remote.js +106 -0
- package/out/cli/data-plane/sidecar.js +225 -0
- package/out/cli/deploy/layers/identity.js +88 -4
- package/out/cli/deploy-init.js +89 -24
- package/out/cli/deps.js +106 -2
- package/out/cli/idp-init.js +35 -0
- package/out/cli/index.js +171 -17
- package/out/cli/pack-install-ref.js +15 -0
- package/out/cli/pack-loader.js +8 -1
- package/out/cli/pack-runtime.js +61 -0
- package/out/cli/runtime.js +35 -1
- package/out/cli/serve-hardening.js +260 -14
- package/out/cli/utils.js +12 -1
- package/out/engines/base.js +32 -3
- package/out/engines/claude.js +33 -15
- package/out/engines/codex.js +111 -27
- package/out/engines/custom.js +15 -1
- package/out/evidence/sessionShip.js +643 -0
- package/out/extension.js +11 -2
- package/out/gateway/bridge.js +40 -2
- package/out/gateway/client.js +34 -1
- package/out/gateway/installSource.js +68 -0
- package/out/gateway/lifecycle.js +185 -51
- package/out/gateway/outboundPaths.js +4 -1
- package/out/gateway/secretsPreflight.js +90 -0
- package/out/gateway/service.js +7 -2
- package/out/headless/index.js +25 -2
- package/out/live-e2e/mcp-demo/server.mjs +32 -0
- package/out/mcp.js +30 -0
- package/out/pack/caps.js +271 -0
- package/out/pack/governor.js +326 -0
- package/out/pack/lease-schema.js +273 -0
- package/out/pack/lease.js +682 -0
- package/out/pack/reconcile.js +217 -0
- package/out/pack/signature.js +839 -0
- package/out/remote/handleRemoteChat.js +44 -3
- package/out/remote/remoteTrust.js +277 -0
- package/out/remote/serveClient.js +52 -5
- package/out/runner/host.js +141 -0
- package/out/runner/protocol.js +128 -0
- package/out/runner/remoteEngine.js +166 -0
- package/out/runtime/interfaces/edit-tracker.js +2 -0
- package/out/runtime/vscode/vscode-edit-tracker.js +2 -0
- package/out/sandbox/containerDriver.js +572 -0
- package/out/sandbox/processDriver.js +318 -0
- package/out/sandbox/sandboxRunner.js +303 -0
- package/out/sandbox/support.js +301 -0
- package/out/sandbox/types.js +55 -0
- package/out/scripts/agentide-litellm.sh +67 -5
- package/out/scripts/agentide_litellm_hooks_v1.py +266 -21
- package/out/scripts/analytics/agentide-litellm-otel.config.yaml +98 -132
- package/out/scripts/analytics/setup-analytics.ps1 +45 -14
- package/out/scripts/analytics/setup-analytics.sh +106 -15
- package/out/scripts/analytics/start-analytics.sh +86 -14
- package/out/scripts/gateway/setup-gateway.sh +72 -32
- package/out/shared/models.js +11 -110
- package/out/spotlight/install.js +7 -1
- package/out/store/index.js +41 -10
- package/out/sync.js +3 -1
- package/out/test/analytics.test.js +162 -23
- package/out/test/auth-baseurl.test.js +132 -0
- package/out/test/auth-bootstrapApply.test.js +27 -6
- package/out/test/auth-broker-hardening.test.js +227 -0
- package/out/test/auth-broker.test.js +59 -9
- package/out/test/branding.test.js +13 -0
- package/out/test/caps-governor.test.js +460 -0
- package/out/test/codex-new-file-survival.test.js +119 -0
- package/out/test/configuration-scopes.test.js +131 -0
- package/out/test/data-plane-engine-wiring.test.js +32 -0
- package/out/test/data-plane.test.js +380 -0
- package/out/test/deploy-init.test.js +47 -1
- package/out/test/gateway-client.test.js +28 -0
- package/out/test/gateway-install-source.test.js +111 -0
- package/out/test/gateway-lifecycle.test.js +1 -1
- package/out/test/gateway-outbound.test.js +7 -0
- package/out/test/gateway-secrets-preflight.test.js +127 -0
- package/out/test/gateway-session-routing.test.js +18 -0
- package/out/test/governor-hardening.test.js +222 -0
- package/out/test/headless-sync.test.js +22 -0
- package/out/test/lease-signature.test.js +357 -0
- package/out/test/lease-trust-root.test.js +273 -0
- package/out/test/lease-validation.test.js +224 -0
- package/out/test/lease.test.js +114 -0
- package/out/test/localFleetAdapter.test.js +91 -0
- package/out/test/mcp.test.js +27 -1
- package/out/test/pack-admission.test.js +216 -0
- package/out/test/pack-digest-parity.test.js +140 -0
- package/out/test/pack-reconcile.test.js +183 -0
- package/out/test/pack-signature-artifact.test.js +103 -0
- package/out/test/pack-signature.test.js +176 -0
- package/out/test/pack-trust-root.test.js +202 -0
- package/out/test/remote-trust.test.js +242 -0
- package/out/test/runner-protocol.test.js +249 -0
- package/out/test/sandbox-driver.test.js +553 -0
- package/out/test/sandbox-hardening.test.js +406 -0
- package/out/test/sandbox-runner.test.js +343 -0
- package/out/test/sandbox-scope.test.js +449 -0
- package/out/test/serve-cron-acceptance.test.js +370 -0
- package/out/test/serve-gateway-turn.test.js +122 -0
- package/out/test/serve-hardening.test.js +227 -15
- package/out/test/serveClient.test.js +6 -5
- package/out/test/sessionShip.test.js +618 -0
- package/out/test/spotlightPublish.test.js +28 -0
- package/out/test/store-install-safe.test.js +69 -0
- package/out/test/tls-bypass.test.js +90 -0
- package/out/test/warrant.test.js +138 -0
- package/out/utils.js +46 -9
- package/package.json +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) AgentHippo.ai. All rights reserved.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isTerminalFrame = isTerminalFrame;
|
|
7
|
+
exports.isTaggedEvent = isTaggedEvent;
|
|
8
|
+
exports.encodeRunnerFrame = encodeRunnerFrame;
|
|
9
|
+
exports.encodeClientFrame = encodeClientFrame;
|
|
10
|
+
exports.parseRunnerFrame = parseRunnerFrame;
|
|
11
|
+
exports.parseClientFrame = parseClientFrame;
|
|
12
|
+
exports.splitFrames = splitFrames;
|
|
13
|
+
exports.toWireOptions = toWireOptions;
|
|
14
|
+
function isTerminalFrame(frame) {
|
|
15
|
+
return 'type' in frame && (frame.type === 'result' || frame.type === 'failed');
|
|
16
|
+
}
|
|
17
|
+
/** A streamed event that names its turn — the only shape safe to route to a single emitter. */
|
|
18
|
+
function isTaggedEvent(frame) {
|
|
19
|
+
return 'event' in frame;
|
|
20
|
+
}
|
|
21
|
+
function encodeRunnerFrame(frame) {
|
|
22
|
+
return `${JSON.stringify(frame)}\n`;
|
|
23
|
+
}
|
|
24
|
+
function encodeClientFrame(frame) {
|
|
25
|
+
return `${JSON.stringify(frame)}\n`;
|
|
26
|
+
}
|
|
27
|
+
/** Parse one runner→serve line. Returns undefined for anything malformed (never throws). */
|
|
28
|
+
function parseRunnerFrame(line) {
|
|
29
|
+
const parsed = parseObject(line);
|
|
30
|
+
if (!parsed) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const type = parsed.type;
|
|
34
|
+
if (type === 'ready') {
|
|
35
|
+
return { type: 'ready', ...(parsed.demux === true ? { demux: true } : {}) };
|
|
36
|
+
}
|
|
37
|
+
// Tagged streamed event. Checked before the untagged branch below because this envelope
|
|
38
|
+
// carries no top-level `type` — the inner event holds it. Validating that inner type here
|
|
39
|
+
// keeps a malformed envelope from becoming an event the emitter switch silently ignores,
|
|
40
|
+
// which would look like a turn that streamed nothing.
|
|
41
|
+
if (typeof parsed.id === 'string' && parsed.event && typeof parsed.event === 'object') {
|
|
42
|
+
const inner = parsed.event.type;
|
|
43
|
+
if (typeof inner === 'string' && RUNNER_EVENT_TYPES.has(inner)) {
|
|
44
|
+
return { id: parsed.id, event: parsed.event };
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
if (type === 'result' && typeof parsed.id === 'string') {
|
|
49
|
+
return {
|
|
50
|
+
type: 'result',
|
|
51
|
+
id: parsed.id,
|
|
52
|
+
...(typeof parsed.nativeSessionId === 'string' ? { nativeSessionId: parsed.nativeSessionId } : {}),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (type === 'failed' && typeof parsed.id === 'string') {
|
|
56
|
+
return {
|
|
57
|
+
type: 'failed',
|
|
58
|
+
id: parsed.id,
|
|
59
|
+
message: typeof parsed.message === 'string' ? parsed.message : 'Sandbox turn failed',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (type === 'question' && parsed.payload && typeof parsed.payload === 'object') {
|
|
63
|
+
return {
|
|
64
|
+
type: 'question',
|
|
65
|
+
payload: parsed.payload,
|
|
66
|
+
...(typeof parsed.id === 'string' ? { id: parsed.id } : {}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Untagged streamed event (legacy peer) — validated by shape, not re-listed here.
|
|
70
|
+
if (typeof type === 'string' && RUNNER_EVENT_TYPES.has(type)) {
|
|
71
|
+
return parsed;
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
/** Parse one serve→runner line. Returns undefined for anything malformed (never throws). */
|
|
76
|
+
function parseClientFrame(line) {
|
|
77
|
+
const parsed = parseObject(line);
|
|
78
|
+
if (!parsed) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
if (parsed.type === 'run' && typeof parsed.id === 'string' && typeof parsed.message === 'string') {
|
|
82
|
+
const options = parsed.options && typeof parsed.options === 'object' ? parsed.options : {};
|
|
83
|
+
return { type: 'run', id: parsed.id, message: parsed.message, options: options };
|
|
84
|
+
}
|
|
85
|
+
if (parsed.type === 'abort' && typeof parsed.id === 'string') {
|
|
86
|
+
return { type: 'abort', id: parsed.id };
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const RUNNER_EVENT_TYPES = new Set([
|
|
91
|
+
'text', 'thinking', 'toolStart', 'toolEnd', 'progress', 'error', 'done', 'nativeSessionId', 'probe',
|
|
92
|
+
]);
|
|
93
|
+
function parseObject(line) {
|
|
94
|
+
let parsed;
|
|
95
|
+
try {
|
|
96
|
+
parsed = JSON.parse(line);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
return parsed;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Split a byte stream into newline-delimited frames. Returns the parsed lines plus whatever
|
|
108
|
+
* partial text is left over, which the caller carries into the next chunk.
|
|
109
|
+
*/
|
|
110
|
+
function splitFrames(buffer) {
|
|
111
|
+
const parts = buffer.split('\n');
|
|
112
|
+
const rest = parts.pop() ?? '';
|
|
113
|
+
return { lines: parts.filter((l) => l.trim().length > 0), rest };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The credential scrub, applied where serve builds a `run` frame. The four secrets that must
|
|
117
|
+
* never cross: `AgentRequestOptions.apiKey` plus `EngineConfig`'s `litellmApiKey` /
|
|
118
|
+
* `openaiApiKey` / `anthropicApiKey` (the latter three live in engine config, which the runner
|
|
119
|
+
* builds in-sandbox from `baseUrl` + `modelToken` — they are never sent).
|
|
120
|
+
*/
|
|
121
|
+
function toWireOptions(options, model) {
|
|
122
|
+
const { apiKey: _dropped, ...rest } = options;
|
|
123
|
+
return {
|
|
124
|
+
...rest,
|
|
125
|
+
...(model.baseUrl ? { baseUrl: model.baseUrl } : {}),
|
|
126
|
+
...(model.modelToken ? { modelToken: model.modelToken } : {}),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) AgentHippo.ai. All rights reserved.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RemoteEngine = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* `RemoteEngine` (PLAN/serve-v4-clean.md §3): satisfies `AgentEngine` by forwarding the turn to
|
|
9
|
+
* a runner inside a sandbox. serve's turn loop, streaming, rate limiting and session handling do
|
|
10
|
+
* not change — this is the same move `RemoteDataPlane` (`cli/data-plane/remote.ts`) already
|
|
11
|
+
* makes against the in-process `DataPlane`, one layer up.
|
|
12
|
+
*/
|
|
13
|
+
const customEngineIpc_1 = require("../engines/customEngineIpc");
|
|
14
|
+
const protocol_1 = require("./protocol");
|
|
15
|
+
class RemoteEngine {
|
|
16
|
+
id;
|
|
17
|
+
displayName;
|
|
18
|
+
channel;
|
|
19
|
+
model;
|
|
20
|
+
logger;
|
|
21
|
+
/** Per-run sinks, keyed by run id — the protocol multiplexes turns on one channel. */
|
|
22
|
+
pending = new Map();
|
|
23
|
+
buffer = '';
|
|
24
|
+
seq = 0;
|
|
25
|
+
wired = false;
|
|
26
|
+
/**
|
|
27
|
+
* Set from the peer's `ready` frame. Starts FALSE and stays false until the peer proves it
|
|
28
|
+
* tags streamed events: a run frame can be sent before `ready` arrives, so "not yet known"
|
|
29
|
+
* must mean "assume it cannot", or the first pair of concurrent turns races the handshake.
|
|
30
|
+
*/
|
|
31
|
+
peerDemux = false;
|
|
32
|
+
constructor(opts) {
|
|
33
|
+
this.id = opts.id;
|
|
34
|
+
this.displayName = opts.displayName;
|
|
35
|
+
this.channel = opts.channel;
|
|
36
|
+
this.model = opts.model ?? {};
|
|
37
|
+
this.logger = opts.logger;
|
|
38
|
+
}
|
|
39
|
+
async stream(message, options, emitter, _runtime, signal) {
|
|
40
|
+
this.wire();
|
|
41
|
+
const id = `r${++this.seq}`;
|
|
42
|
+
const settled = new Promise((resolve, reject) => {
|
|
43
|
+
this.pending.set(id, { emitter, resolve, reject, chain: Promise.resolve() });
|
|
44
|
+
});
|
|
45
|
+
const onAbort = () => { this.send({ type: 'abort', id }); };
|
|
46
|
+
if (signal) {
|
|
47
|
+
if (signal.aborted) {
|
|
48
|
+
onAbort();
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
// A fresh warrant for this turn when the caller can mint one; the create-time token is
|
|
56
|
+
// the fallback for paths that mint nothing (tier 0, tests).
|
|
57
|
+
const modelToken = this.model.mintToken
|
|
58
|
+
? (await this.model.mintToken()) ?? this.model.modelToken
|
|
59
|
+
: this.model.modelToken;
|
|
60
|
+
this.send({
|
|
61
|
+
type: 'run',
|
|
62
|
+
id,
|
|
63
|
+
message,
|
|
64
|
+
options: (0, protocol_1.toWireOptions)(options, { ...this.model, modelToken }),
|
|
65
|
+
});
|
|
66
|
+
// Resolves on the TERMINAL frame (result/failed) — never on the streamed `done`,
|
|
67
|
+
// which engines emit mid-run.
|
|
68
|
+
await settled;
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
this.pending.delete(id);
|
|
72
|
+
signal?.removeEventListener('abort', onAbort);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** No-op by design: the runner drives its own maintenance timer in-sandbox (see runner/host.ts). */
|
|
76
|
+
onMaintenance() { }
|
|
77
|
+
/** Sandbox teardown is the driver's job (`destroy(handle)` at session end), not the engine's. */
|
|
78
|
+
dispose() { }
|
|
79
|
+
wire() {
|
|
80
|
+
if (this.wired) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this.wired = true;
|
|
84
|
+
this.channel.input.on('data', (chunk) => {
|
|
85
|
+
this.buffer += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
|
|
86
|
+
const { lines, rest } = (0, protocol_1.splitFrames)(this.buffer);
|
|
87
|
+
this.buffer = rest;
|
|
88
|
+
for (const line of lines) {
|
|
89
|
+
const frame = (0, protocol_1.parseRunnerFrame)(line);
|
|
90
|
+
if (!frame) {
|
|
91
|
+
this.logger?.warn('[RemoteEngine] dropped malformed runner frame');
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
this.dispatch(frame);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
void this.channel.closed?.then(() => this.failAll(new Error('sandbox channel closed')), (err) => this.failAll(err instanceof Error ? err : new Error(String(err))));
|
|
98
|
+
}
|
|
99
|
+
dispatch(frame) {
|
|
100
|
+
if ((0, protocol_1.isTaggedEvent)(frame)) {
|
|
101
|
+
// Routed to exactly one turn. No entry means the turn already settled or was aborted
|
|
102
|
+
// and a late event arrived behind its terminal frame — dropping it is correct.
|
|
103
|
+
this.enqueue(this.pending.get(frame.id), (e) => (0, customEngineIpc_1.applyParsedRunnerEvent)(e.emitter, frame.event));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (frame.type === 'ready') {
|
|
107
|
+
this.peerDemux = frame.demux === true;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (frame.type === 'result') {
|
|
111
|
+
// Behind this turn's own events, so a turn never settles while its last delta is still
|
|
112
|
+
// inside an unfinished emitter call.
|
|
113
|
+
this.settle(frame.id, (entry) => entry.resolve(frame.nativeSessionId));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (frame.type === 'failed') {
|
|
117
|
+
this.settle(frame.id, (entry) => entry.reject(new Error(frame.message)));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (frame.type === 'question') {
|
|
121
|
+
// One-way notification; the runner already answered it `declined` locally.
|
|
122
|
+
const targets = frame.id ? [this.pending.get(frame.id)] : [...this.pending.values()];
|
|
123
|
+
for (const entry of targets) {
|
|
124
|
+
this.enqueue(entry, (e) => e.emitter.question(frame.payload).then(() => undefined));
|
|
125
|
+
}
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// LEGACY peer only: untagged events carry nothing that names their turn, so the best
|
|
129
|
+
// available behaviour is to broadcast. That is only safe because a peer which has not
|
|
130
|
+
// advertised `demux` is given one turn at a time (see sandboxRunner's `exclusive`).
|
|
131
|
+
for (const entry of this.pending.values()) {
|
|
132
|
+
this.enqueue(entry, (e) => (0, customEngineIpc_1.applyParsedRunnerEvent)(e.emitter, frame).then(() => undefined));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** Appends work to one turn's ordered chain. An emitter failure never breaks the chain. */
|
|
136
|
+
enqueue(entry, work) {
|
|
137
|
+
if (!entry) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
entry.chain = entry.chain.then(() => work(entry)).then(() => undefined, (err) => {
|
|
141
|
+
this.logger?.warn(`[RemoteEngine] emitter error: ${err instanceof Error ? err.message : String(err)}`);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/** Settles a turn once everything already streamed for it has been applied. */
|
|
145
|
+
settle(id, finish) {
|
|
146
|
+
const entry = this.pending.get(id);
|
|
147
|
+
if (!entry) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
void entry.chain.then(() => finish(entry));
|
|
151
|
+
}
|
|
152
|
+
/** True once the peer's `ready` proved it tags streamed events — see `peerDemux`. */
|
|
153
|
+
supportsDemux() {
|
|
154
|
+
return this.peerDemux;
|
|
155
|
+
}
|
|
156
|
+
failAll(err) {
|
|
157
|
+
for (const [id, entry] of this.pending) {
|
|
158
|
+
entry.reject(err);
|
|
159
|
+
this.pending.delete(id);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
send(frame) {
|
|
163
|
+
this.channel.output.write((0, protocol_1.encodeClientFrame)(frame));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
exports.RemoteEngine = RemoteEngine;
|
|
@@ -9,6 +9,8 @@ exports.NoOpEditTracker = void 0;
|
|
|
9
9
|
* Suitable for eval mode, CLI, and production where edit tracking is not needed.
|
|
10
10
|
*/
|
|
11
11
|
class NoOpEditTracker {
|
|
12
|
+
/** Nothing is written back here — callers must not delete a file expecting this to restore it. */
|
|
13
|
+
appliesEdits = false;
|
|
12
14
|
async startTracking(_sessionId, _files) {
|
|
13
15
|
return undefined;
|
|
14
16
|
}
|
|
@@ -44,6 +44,8 @@ const vscode = __importStar(require("vscode"));
|
|
|
44
44
|
*/
|
|
45
45
|
class VSCodeEditTracker {
|
|
46
46
|
logger;
|
|
47
|
+
/** `applyEdit` writes through the IDE's workspace edit, so a pre-delete is recoverable. */
|
|
48
|
+
appliesEdits = true;
|
|
47
49
|
constructor(logger) {
|
|
48
50
|
this.logger = logger;
|
|
49
51
|
}
|