@oscharko-dev/keiko-server 0.2.8 → 0.2.9
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/dist/.tsbuildinfo +1 -1
- package/dist/chat-handlers.d.ts +18 -2
- package/dist/chat-handlers.d.ts.map +1 -1
- package/dist/chat-handlers.js +185 -3
- package/dist/command-runner-errors.d.ts +17 -0
- package/dist/command-runner-errors.d.ts.map +1 -0
- package/dist/command-runner-errors.js +37 -0
- package/dist/command-runner-evidence.d.ts +23 -0
- package/dist/command-runner-evidence.d.ts.map +1 -0
- package/dist/command-runner-evidence.js +69 -0
- package/dist/command-runner-routes.d.ts +7 -0
- package/dist/command-runner-routes.d.ts.map +1 -0
- package/dist/command-runner-routes.js +175 -0
- package/dist/command-runner.d.ts +29 -0
- package/dist/command-runner.d.ts.map +1 -0
- package/dist/command-runner.js +348 -0
- package/dist/conversation-prompt.d.ts +2 -2
- package/dist/conversation-prompt.d.ts.map +1 -1
- package/dist/conversation-prompt.js +17 -1
- package/dist/csp.d.ts.map +1 -1
- package/dist/csp.js +3 -0
- package/dist/deps.d.ts +27 -1
- package/dist/deps.d.ts.map +1 -1
- package/dist/deps.js +288 -13
- package/dist/discussion-prompt.d.ts +4 -0
- package/dist/discussion-prompt.d.ts.map +1 -0
- package/dist/discussion-prompt.js +19 -0
- package/dist/editor/agentActionAudit.d.ts +18 -0
- package/dist/editor/agentActionAudit.d.ts.map +1 -0
- package/dist/editor/agentActionAudit.js +80 -0
- package/dist/editor/agentRoutes.d.ts +1 -0
- package/dist/editor/agentRoutes.d.ts.map +1 -1
- package/dist/editor/agentRoutes.js +292 -55
- package/dist/editor/agentSessionRegistry.d.ts +35 -0
- package/dist/editor/agentSessionRegistry.d.ts.map +1 -0
- package/dist/editor/agentSessionRegistry.js +243 -0
- package/dist/editor/completionRoutes.d.ts.map +1 -1
- package/dist/editor/completionRoutes.js +5 -10
- package/dist/editor/languageRoutes.d.ts +12 -1
- package/dist/editor/languageRoutes.d.ts.map +1 -1
- package/dist/editor/languageRoutes.js +71 -8
- package/dist/editor/languageService.d.ts +3 -2
- package/dist/editor/languageService.d.ts.map +1 -1
- package/dist/editor/languageService.js +41 -3
- package/dist/editor/languageServiceHost.d.ts.map +1 -1
- package/dist/editor/languageServiceHost.js +2 -2
- package/dist/editor/lsp/hostLanguageOperation.d.ts +17 -0
- package/dist/editor/lsp/hostLanguageOperation.d.ts.map +1 -0
- package/dist/editor/lsp/hostLanguageOperation.js +436 -0
- package/dist/editor/lsp/hostLanguageProviders.d.ts +26 -0
- package/dist/editor/lsp/hostLanguageProviders.d.ts.map +1 -0
- package/dist/editor/lsp/hostLanguageProviders.js +161 -0
- package/dist/editor/lsp/lspFrameCodec.d.ts +13 -0
- package/dist/editor/lsp/lspFrameCodec.d.ts.map +1 -0
- package/dist/editor/lsp/lspFrameCodec.js +164 -0
- package/dist/editor/lsp/lspJsonRpcClient.d.ts +34 -0
- package/dist/editor/lsp/lspJsonRpcClient.d.ts.map +1 -0
- package/dist/editor/lsp/lspJsonRpcClient.js +173 -0
- package/dist/editor/lsp/lspLanguageProvider.d.ts +7 -0
- package/dist/editor/lsp/lspLanguageProvider.d.ts.map +1 -0
- package/dist/editor/lsp/lspLanguageProvider.js +29 -0
- package/dist/editor/lsp/lspLifecycleLedger.d.ts +5 -0
- package/dist/editor/lsp/lspLifecycleLedger.d.ts.map +1 -0
- package/dist/editor/lsp/lspLifecycleLedger.js +37 -0
- package/dist/editor/lsp/lspNodeAdapter.d.ts +31 -0
- package/dist/editor/lsp/lspNodeAdapter.d.ts.map +1 -0
- package/dist/editor/lsp/lspNodeAdapter.js +230 -0
- package/dist/editor/lsp/lspProcessManager.d.ts +24 -0
- package/dist/editor/lsp/lspProcessManager.d.ts.map +1 -0
- package/dist/editor/lsp/lspProcessManager.js +255 -0
- package/dist/editor/lsp/lspRestartThrottle.d.ts +6 -0
- package/dist/editor/lsp/lspRestartThrottle.d.ts.map +1 -0
- package/dist/editor/lsp/lspRestartThrottle.js +24 -0
- package/dist/editor/lsp/lspStatusRoute.d.ts +8 -0
- package/dist/editor/lsp/lspStatusRoute.d.ts.map +1 -0
- package/dist/editor/lsp/lspStatusRoute.js +22 -0
- package/dist/editor/lsp/lspTransport.d.ts +19 -0
- package/dist/editor/lsp/lspTransport.d.ts.map +1 -0
- package/dist/editor/lsp/lspTransport.js +55 -0
- package/dist/editor/lsp/testing/fakeLspProcess.d.ts +23 -0
- package/dist/editor/lsp/testing/fakeLspProcess.d.ts.map +1 -0
- package/dist/editor/lsp/testing/fakeLspProcess.js +132 -0
- package/dist/files.d.ts +45 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +631 -7
- package/dist/gateway-readiness.js +3 -3
- package/dist/gateway-setup.d.ts +2 -0
- package/dist/gateway-setup.d.ts.map +1 -1
- package/dist/gateway-setup.js +275 -11
- package/dist/gitDelivery/actionSheetProjection.d.ts +30 -0
- package/dist/gitDelivery/actionSheetProjection.d.ts.map +1 -0
- package/dist/gitDelivery/actionSheetProjection.js +206 -0
- package/dist/gitDelivery/actionSheetRoutes.d.ts +29 -0
- package/dist/gitDelivery/actionSheetRoutes.d.ts.map +1 -0
- package/dist/gitDelivery/actionSheetRoutes.js +293 -0
- package/dist/gitDelivery/agentOperationsRoutes.d.ts +33 -0
- package/dist/gitDelivery/agentOperationsRoutes.d.ts.map +1 -0
- package/dist/gitDelivery/agentOperationsRoutes.js +405 -0
- package/dist/gitDelivery/commitRoutes.d.ts +23 -0
- package/dist/gitDelivery/commitRoutes.d.ts.map +1 -0
- package/dist/gitDelivery/commitRoutes.js +204 -0
- package/dist/gitDelivery/evidenceRoutes.d.ts +9 -0
- package/dist/gitDelivery/evidenceRoutes.d.ts.map +1 -0
- package/dist/gitDelivery/evidenceRoutes.js +101 -0
- package/dist/gitDelivery/execution.d.ts +38 -0
- package/dist/gitDelivery/execution.d.ts.map +1 -0
- package/dist/gitDelivery/execution.js +117 -0
- package/dist/gitDelivery/localMutationRoutes.d.ts +30 -0
- package/dist/gitDelivery/localMutationRoutes.d.ts.map +1 -0
- package/dist/gitDelivery/localMutationRoutes.js +165 -0
- package/dist/gitDelivery/mergeExecution.d.ts +63 -0
- package/dist/gitDelivery/mergeExecution.d.ts.map +1 -0
- package/dist/gitDelivery/mergeExecution.js +168 -0
- package/dist/gitDelivery/mergeRoutes.d.ts +12 -0
- package/dist/gitDelivery/mergeRoutes.d.ts.map +1 -0
- package/dist/gitDelivery/mergeRoutes.js +218 -0
- package/dist/gitDelivery/mutationEvidenceLedger.d.ts +23 -0
- package/dist/gitDelivery/mutationEvidenceLedger.d.ts.map +1 -0
- package/dist/gitDelivery/mutationEvidenceLedger.js +87 -0
- package/dist/gitDelivery/prExecution.d.ts +54 -0
- package/dist/gitDelivery/prExecution.d.ts.map +1 -0
- package/dist/gitDelivery/prExecution.js +192 -0
- package/dist/gitDelivery/prRoutes.d.ts +12 -0
- package/dist/gitDelivery/prRoutes.d.ts.map +1 -0
- package/dist/gitDelivery/prRoutes.js +256 -0
- package/dist/gitDelivery/pushExecution.d.ts +43 -0
- package/dist/gitDelivery/pushExecution.d.ts.map +1 -0
- package/dist/gitDelivery/pushExecution.js +124 -0
- package/dist/gitDelivery/pushRoutes.d.ts +12 -0
- package/dist/gitDelivery/pushRoutes.d.ts.map +1 -0
- package/dist/gitDelivery/pushRoutes.js +200 -0
- package/dist/gitDelivery/requestGuards.d.ts +15 -0
- package/dist/gitDelivery/requestGuards.d.ts.map +1 -0
- package/dist/gitDelivery/requestGuards.js +97 -0
- package/dist/gitDelivery/syncEvidence.d.ts +37 -0
- package/dist/gitDelivery/syncEvidence.d.ts.map +1 -0
- package/dist/gitDelivery/syncEvidence.js +85 -0
- package/dist/gitDelivery/syncExecution.d.ts +30 -0
- package/dist/gitDelivery/syncExecution.d.ts.map +1 -0
- package/dist/gitDelivery/syncExecution.js +266 -0
- package/dist/gitDelivery/syncRoutes.d.ts +13 -0
- package/dist/gitDelivery/syncRoutes.d.ts.map +1 -0
- package/dist/gitDelivery/syncRoutes.js +200 -0
- package/dist/gitPorcelainStatus.d.ts +15 -0
- package/dist/gitPorcelainStatus.d.ts.map +1 -0
- package/dist/gitPorcelainStatus.js +104 -0
- package/dist/gitRepositoryReads.d.ts +10 -0
- package/dist/gitRepositoryReads.d.ts.map +1 -0
- package/dist/gitRepositoryReads.js +314 -0
- package/dist/gitRepositoryRoutes.d.ts +7 -0
- package/dist/gitRepositoryRoutes.d.ts.map +1 -0
- package/dist/gitRepositoryRoutes.js +221 -0
- package/dist/gitRoutes.d.ts +66 -0
- package/dist/gitRoutes.d.ts.map +1 -0
- package/dist/gitRoutes.js +543 -0
- package/dist/governed-workflow.d.ts +2 -0
- package/dist/governed-workflow.d.ts.map +1 -1
- package/dist/governed-workflow.js +4 -0
- package/dist/grounded-qa.d.ts +11 -0
- package/dist/grounded-qa.d.ts.map +1 -1
- package/dist/grounded-qa.js +13 -4
- package/dist/headers.d.ts +4 -1
- package/dist/headers.d.ts.map +1 -1
- package/dist/headers.js +11 -4
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/qualityIntelligence/figmaSnapshotRoutes.d.ts +1 -1
- package/dist/qualityIntelligence/figmaSnapshotRoutes.d.ts.map +1 -1
- package/dist/qualityIntelligence/figmaSnapshotRoutes.js +1 -1
- package/dist/read-handlers.d.ts +5 -0
- package/dist/read-handlers.d.ts.map +1 -1
- package/dist/read-handlers.js +57 -1
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +259 -6
- package/dist/run-engine.d.ts.map +1 -1
- package/dist/run-engine.js +3 -0
- package/dist/run-handlers.d.ts.map +1 -1
- package/dist/run-handlers.js +74 -4
- package/dist/run-request.d.ts +11 -0
- package/dist/run-request.d.ts.map +1 -1
- package/dist/run-request.js +158 -10
- package/dist/runtime/capabilityDetector.d.ts +38 -0
- package/dist/runtime/capabilityDetector.d.ts.map +1 -0
- package/dist/runtime/capabilityDetector.js +443 -0
- package/dist/runtime/capabilityRoutes.d.ts +9 -0
- package/dist/runtime/capabilityRoutes.d.ts.map +1 -0
- package/dist/runtime/capabilityRoutes.js +45 -0
- package/dist/runtime/containerEngineDetector.d.ts +17 -0
- package/dist/runtime/containerEngineDetector.d.ts.map +1 -0
- package/dist/runtime/containerEngineDetector.js +222 -0
- package/dist/runtime/containerRoutes.d.ts +8 -0
- package/dist/runtime/containerRoutes.d.ts.map +1 -0
- package/dist/runtime/containerRoutes.js +207 -0
- package/dist/runtime/containerRunner-errors.d.ts +18 -0
- package/dist/runtime/containerRunner-errors.d.ts.map +1 -0
- package/dist/runtime/containerRunner-errors.js +42 -0
- package/dist/runtime/containerRunner-evidence.d.ts +24 -0
- package/dist/runtime/containerRunner-evidence.d.ts.map +1 -0
- package/dist/runtime/containerRunner-evidence.js +74 -0
- package/dist/runtime/containerRunner.d.ts +37 -0
- package/dist/runtime/containerRunner.d.ts.map +1 -0
- package/dist/runtime/containerRunner.js +443 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +24 -4
- package/dist/store/schema.d.ts +1 -1
- package/dist/store/schema.d.ts.map +1 -1
- package/dist/store/schema.js +62 -1
- package/dist/task-workspace/active-store.d.ts +21 -0
- package/dist/task-workspace/active-store.d.ts.map +1 -0
- package/dist/task-workspace/active-store.js +55 -0
- package/dist/task-workspace/authorization.d.ts +7 -0
- package/dist/task-workspace/authorization.d.ts.map +1 -0
- package/dist/task-workspace/authorization.js +54 -0
- package/dist/task-workspace/binding.d.ts +3 -0
- package/dist/task-workspace/binding.d.ts.map +1 -0
- package/dist/task-workspace/binding.js +22 -0
- package/dist/task-workspace/cleanup.d.ts +4 -0
- package/dist/task-workspace/cleanup.d.ts.map +1 -0
- package/dist/task-workspace/cleanup.js +428 -0
- package/dist/task-workspace/errors.d.ts +14 -0
- package/dist/task-workspace/errors.d.ts.map +1 -0
- package/dist/task-workspace/errors.js +81 -0
- package/dist/task-workspace/evidence.d.ts +32 -0
- package/dist/task-workspace/evidence.d.ts.map +1 -0
- package/dist/task-workspace/evidence.js +52 -0
- package/dist/task-workspace/field-safety.d.ts +3 -0
- package/dist/task-workspace/field-safety.d.ts.map +1 -0
- package/dist/task-workspace/field-safety.js +42 -0
- package/dist/task-workspace/health.d.ts +4 -0
- package/dist/task-workspace/health.d.ts.map +1 -0
- package/dist/task-workspace/health.js +163 -0
- package/dist/task-workspace/lifecycle.d.ts +3 -0
- package/dist/task-workspace/lifecycle.d.ts.map +1 -0
- package/dist/task-workspace/lifecycle.js +248 -0
- package/dist/task-workspace/locks.d.ts +13 -0
- package/dist/task-workspace/locks.d.ts.map +1 -0
- package/dist/task-workspace/locks.js +44 -0
- package/dist/task-workspace/managed-root.d.ts +7 -0
- package/dist/task-workspace/managed-root.d.ts.map +1 -0
- package/dist/task-workspace/managed-root.js +98 -0
- package/dist/task-workspace/mutex.d.ts +8 -0
- package/dist/task-workspace/mutex.d.ts.map +1 -0
- package/dist/task-workspace/mutex.js +82 -0
- package/dist/task-workspace/naming.d.ts +15 -0
- package/dist/task-workspace/naming.d.ts.map +1 -0
- package/dist/task-workspace/naming.js +0 -0
- package/dist/task-workspace/provisioning.d.ts +3 -0
- package/dist/task-workspace/provisioning.d.ts.map +1 -0
- package/dist/task-workspace/provisioning.js +528 -0
- package/dist/task-workspace/reconciliation.d.ts +15 -0
- package/dist/task-workspace/reconciliation.d.ts.map +1 -0
- package/dist/task-workspace/reconciliation.js +274 -0
- package/dist/task-workspace/repair.d.ts +3 -0
- package/dist/task-workspace/repair.d.ts.map +1 -0
- package/dist/task-workspace/repair.js +286 -0
- package/dist/task-workspace/routes.d.ts +19 -0
- package/dist/task-workspace/routes.d.ts.map +1 -0
- package/dist/task-workspace/routes.js +481 -0
- package/dist/task-workspace/store.d.ts +12 -0
- package/dist/task-workspace/store.d.ts.map +1 -0
- package/dist/task-workspace/store.js +128 -0
- package/dist/task-workspace/types.d.ts +170 -0
- package/dist/task-workspace/types.d.ts.map +1 -0
- package/dist/task-workspace/types.js +5 -0
- package/dist/voice-action-governance.d.ts +23 -0
- package/dist/voice-action-governance.d.ts.map +1 -0
- package/dist/voice-action-governance.js +126 -0
- package/dist/voice-handlers.d.ts +6 -0
- package/dist/voice-handlers.d.ts.map +1 -0
- package/dist/voice-handlers.js +570 -0
- package/dist/voice-realtime-grounded-tool.d.ts +31 -0
- package/dist/voice-realtime-grounded-tool.d.ts.map +1 -0
- package/dist/voice-realtime-grounded-tool.js +322 -0
- package/dist/voice-realtime.d.ts +69 -0
- package/dist/voice-realtime.d.ts.map +1 -0
- package/dist/voice-realtime.js +787 -0
- package/dist/workspace-state-handlers.d.ts +5 -0
- package/dist/workspace-state-handlers.d.ts.map +1 -0
- package/dist/workspace-state-handlers.js +106 -0
- package/package.json +20 -19
|
@@ -1,28 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// Issue #1392 — BFF routes for the editor-agent control plane: session discovery, snapshot read/write,
|
|
2
|
+
// action queueing, browser result reporting, and the SSE event stream. The durable control-plane state
|
|
3
|
+
// (session registry, live bridge tracking, bounded action queue, timeouts, fan-out) lives in
|
|
4
|
+
// agentSessionRegistry.ts; this module is the HTTP edge that parses requests, enforces *preflight*
|
|
5
|
+
// policy, and threads idempotency. The server only coordinates — it never executes an action or
|
|
6
|
+
// mutates editor/React state (AC5); the browser bridge owns that.
|
|
7
|
+
//
|
|
8
|
+
// Preflight conflicts (status "conflict", HTTP 409) gate admission to the queue. The Issue #1391/#1394
|
|
9
|
+
// structural gates (DIRTY / VERSION / HASH / OUT_OF_SCOPE / INVALID_EDITS / PRECONDITION_REQUIRED) run
|
|
10
|
+
// first; the Issue #1392 liveness gate runs last: an otherwise-valid action for a session with no live
|
|
11
|
+
// browser bridge is answered with NO_ACTIVE_BRIDGE (AC1). Past preflight, the registry can still return
|
|
12
|
+
// a lifecycle failure: QUEUE_FULL (HTTP 429, the bounded queue is saturated) or, asynchronously,
|
|
13
|
+
// TIMED_OUT when the bridge never acknowledges before the deadline (AC2).
|
|
14
|
+
//
|
|
15
|
+
// No raw source content (snapshot text, text edits, patch bodies) is logged anywhere in this path.
|
|
16
|
+
import { createHash } from "node:crypto";
|
|
17
|
+
import { EDITOR_AGENT_SCHEMA_VERSION, classifyEditorAgentAction, editorAgentWritePreconditionError, isContainedAgentPath, isEditorAgentAction, isEditorAgentWriteActionType, parseEditorAgentActionsPostBody, parseEditorAgentSnapshotRequest, validateAgentTextEdits, } from "@oscharko-dev/keiko-contracts";
|
|
18
|
+
import { computeFileContent, validatePatch, } from "@oscharko-dev/keiko-tools";
|
|
19
|
+
import { isDenied, resolveWithinWorkspace, } from "@oscharko-dev/keiko-workspace";
|
|
20
|
+
import { nodeWorkspaceFs } from "@oscharko-dev/keiko-workspace/internal/fs";
|
|
21
|
+
import { errorBody, STREAMING, } from "../routes.js";
|
|
3
22
|
import { SSE_HEADERS, readyMessage } from "../sse.js";
|
|
4
23
|
import { readJsonObject } from "../files.js";
|
|
24
|
+
import { editorAgentRegistry } from "./agentSessionRegistry.js";
|
|
25
|
+
import { _resetEditorAgentAuditForTests, listEditorAgentActionAudit, recordEditorAgentActionAudit, } from "./agentActionAudit.js";
|
|
5
26
|
const MAX_AGENT_BODY_BYTES = 1_048_576;
|
|
6
27
|
const DEFAULT_SNAPSHOT_TEXT_BUDGET_BYTES = 64 * 1024;
|
|
7
|
-
|
|
28
|
+
// HTTP-level idempotency: a replayed Idempotency-Key returns the original outcome; a key reused with a
|
|
29
|
+
// different action body is a 409. This is request de-duplication and stays at the route edge. The map
|
|
30
|
+
// is bounded (FIFO eviction) and stores only a hash of the request body, so it cannot grow without
|
|
31
|
+
// limit or retain raw action content (text edits, patch bodies) on a long-lived server.
|
|
32
|
+
const MAX_IDEMPOTENCY_ENTRIES = 1024;
|
|
8
33
|
const idempotency = new Map();
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
function isRouteResult(value) {
|
|
12
|
-
return typeof value === "object" && value !== null && "status" in value && "body" in value;
|
|
34
|
+
function hashRequest(body) {
|
|
35
|
+
return createHash("sha256").update(body).digest("hex");
|
|
13
36
|
}
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
|
|
37
|
+
function rememberIdempotency(key, requestHash, result) {
|
|
38
|
+
if (!idempotency.has(key) && idempotency.size >= MAX_IDEMPOTENCY_ENTRIES) {
|
|
39
|
+
const oldest = idempotency.keys().next().value;
|
|
40
|
+
if (oldest !== undefined)
|
|
41
|
+
idempotency.delete(oldest);
|
|
42
|
+
}
|
|
43
|
+
idempotency.set(key, { requestHash, result });
|
|
17
44
|
}
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
schemaVersion: EDITOR_AGENT_SCHEMA_VERSION,
|
|
21
|
-
eventId: nextEventId(),
|
|
22
|
-
...event,
|
|
23
|
-
};
|
|
24
|
-
for (const subscriber of subscribers)
|
|
25
|
-
subscriber(envelope);
|
|
45
|
+
function isRouteResult(value) {
|
|
46
|
+
return typeof value === "object" && value !== null && "status" in value && "body" in value;
|
|
26
47
|
}
|
|
27
48
|
function utf8Prefix(text, maxBytes) {
|
|
28
49
|
let bytes = 0;
|
|
@@ -72,14 +93,150 @@ function contentHashConflict(action, snapshot) {
|
|
|
72
93
|
? null
|
|
73
94
|
: conflict(action, "CONTENT_HASH_MISMATCH", "The active document content hash no longer matches.");
|
|
74
95
|
}
|
|
96
|
+
function containmentConflict(action, snapshot) {
|
|
97
|
+
const file = targetFile(action, snapshot);
|
|
98
|
+
if (file === null)
|
|
99
|
+
return null;
|
|
100
|
+
return isContainedAgentPath(file)
|
|
101
|
+
? null
|
|
102
|
+
: conflict(action, "OUT_OF_SCOPE", "The target file escapes the workspace root.");
|
|
103
|
+
}
|
|
104
|
+
// Issue #1395 (ADR-0062) — a write action whose target is a contained but always-on-deny-listed path
|
|
105
|
+
// (.env, .ssh, .keiko, credentials, …) is denied by policy across ALL write action types. Previously
|
|
106
|
+
// the deny-list was enforced only on the applyPatch path (via validatePatch); this closes the gap for
|
|
107
|
+
// applyTextEdits/save/format. Surfaced as the existing OUT_OF_SCOPE conflict so no new wire code is
|
|
108
|
+
// introduced; the fine-grained governance reason (denied-sensitive-path) lives in the audit record.
|
|
109
|
+
function sensitivePathConflict(action, snapshot) {
|
|
110
|
+
const file = targetFile(action, snapshot);
|
|
111
|
+
if (file === null || !isContainedAgentPath(file))
|
|
112
|
+
return null;
|
|
113
|
+
return isDenied(file)
|
|
114
|
+
? conflict(action, "OUT_OF_SCOPE", "The target file is a protected workspace path.")
|
|
115
|
+
: null;
|
|
116
|
+
}
|
|
117
|
+
function textEditsConflict(action) {
|
|
118
|
+
if (action.type !== "applyTextEdits")
|
|
119
|
+
return null;
|
|
120
|
+
const error = validateAgentTextEdits(action.textEdits ?? []);
|
|
121
|
+
return error === null ? null : conflict(action, "INVALID_EDITS", error);
|
|
122
|
+
}
|
|
123
|
+
function workspaceInfoFromRoot(root) {
|
|
124
|
+
return {
|
|
125
|
+
root,
|
|
126
|
+
name: undefined,
|
|
127
|
+
version: undefined,
|
|
128
|
+
testFramework: "unknown",
|
|
129
|
+
sourceDirs: [],
|
|
130
|
+
testDirs: [],
|
|
131
|
+
languages: [],
|
|
132
|
+
ignoreLines: [],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const OUT_OF_SCOPE_REJECTION_CODES = new Set(["path-unsafe", "path-denied", "binary"]);
|
|
136
|
+
function mapPatchValidation(action, validation) {
|
|
137
|
+
if (validation.files.length > 1) {
|
|
138
|
+
return conflict(action, "OUT_OF_SCOPE", "Multi-file patches are not supported on the agent action path.");
|
|
139
|
+
}
|
|
140
|
+
const scopeRejection = validation.reasons.find((reason) => OUT_OF_SCOPE_REJECTION_CODES.has(reason.code));
|
|
141
|
+
if (scopeRejection !== undefined) {
|
|
142
|
+
return conflict(action, "OUT_OF_SCOPE", scopeRejection.message);
|
|
143
|
+
}
|
|
144
|
+
const firstReason = validation.reasons.at(0);
|
|
145
|
+
if (firstReason !== undefined) {
|
|
146
|
+
return conflict(action, "INVALID_EDITS", firstReason.message);
|
|
147
|
+
}
|
|
148
|
+
const firstConflict = validation.conflicts.at(0);
|
|
149
|
+
if (firstConflict !== undefined) {
|
|
150
|
+
return conflict(action, "INVALID_EDITS", firstConflict.reason);
|
|
151
|
+
}
|
|
152
|
+
if (validation.ok && validation.files.length === 0) {
|
|
153
|
+
return conflict(action, "INVALID_EDITS", "Patch contains no applicable file change.");
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
function patchValidationConflict(action, snapshot) {
|
|
158
|
+
if (action.type !== "applyPatch")
|
|
159
|
+
return null;
|
|
160
|
+
const validation = validatePatch(workspaceInfoFromRoot(snapshot.workspaceRoot), action.patch ?? "", {
|
|
161
|
+
fs: nodeWorkspaceFs,
|
|
162
|
+
});
|
|
163
|
+
return mapPatchValidation(action, validation);
|
|
164
|
+
}
|
|
165
|
+
function wholeDocumentReplaceEdit(currentContent, postImage) {
|
|
166
|
+
const currentLineCount = currentContent.split("\n").length;
|
|
167
|
+
return {
|
|
168
|
+
range: {
|
|
169
|
+
start: { line: 0, character: 0 },
|
|
170
|
+
end: { line: currentLineCount + 1, character: 0 },
|
|
171
|
+
},
|
|
172
|
+
newText: postImage,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function deriveSingleFilePostImage(file, snapshot) {
|
|
176
|
+
const absolute = resolveWithinWorkspace(snapshot.workspaceRoot, file.path);
|
|
177
|
+
const exists = nodeWorkspaceFs.exists(absolute);
|
|
178
|
+
const currentContent = exists ? nodeWorkspaceFs.readFileUtf8(absolute) : "";
|
|
179
|
+
const outcome = computeFileContent(file, exists ? currentContent : undefined);
|
|
180
|
+
if (outcome.content === null || outcome.conflicts.length > 0)
|
|
181
|
+
return null;
|
|
182
|
+
return wholeDocumentReplaceEdit(currentContent, outcome.content);
|
|
183
|
+
}
|
|
184
|
+
// Translates a queued, preflight-validated single-file applyPatch into the contract textEdits the
|
|
185
|
+
// browser reviews and applies. Computing the post-image with keiko-tools' tested single-file apply
|
|
186
|
+
// logic against the current on-disk content guarantees the cross-cutting invariant
|
|
187
|
+
// applyTextEditsToText(currentContent, edits) === patchedSingleFileContent. Returns null when the
|
|
188
|
+
// patch is not the expected single-file shape or its post-image cannot be derived (including any
|
|
189
|
+
// filesystem/path error), so the caller fails the action rather than emitting an un-appliable one.
|
|
190
|
+
// keiko-tools strips a/ b/ git prefixes; both the patch path and snapshot.activeFile are
|
|
191
|
+
// workspace-relative POSIX paths. Normalize a leading ./ and backslashes so a legitimately
|
|
192
|
+
// matching same-file patch is not rejected on a cosmetic difference.
|
|
193
|
+
function normalizeWorkspaceRelativePath(path) {
|
|
194
|
+
return path.replace(/\\/gu, "/").replace(/^\.\//u, "");
|
|
195
|
+
}
|
|
196
|
+
function deriveAgentPatchTextEdits(action, snapshot) {
|
|
197
|
+
// Intentional re-validation: preflight already validated this patch, but validatePatch is
|
|
198
|
+
// deterministic and pure over (workspace, patch, fs), so deriving here keeps this function
|
|
199
|
+
// self-contained without threading mutable validation state through the queue path.
|
|
200
|
+
const validation = validatePatch(workspaceInfoFromRoot(snapshot.workspaceRoot), action.patch ?? "", { fs: nodeWorkspaceFs });
|
|
201
|
+
const file = validation.files.at(0);
|
|
202
|
+
if (!validation.ok || validation.files.length !== 1 || file === undefined)
|
|
203
|
+
return null;
|
|
204
|
+
// The post-image is derived from the patch's file content but the browser applies it to the
|
|
205
|
+
// open buffer. Refuse to apply a patch that targets a different file than the open buffer.
|
|
206
|
+
if (snapshot.activeFile === null ||
|
|
207
|
+
normalizeWorkspaceRelativePath(file.path) !==
|
|
208
|
+
normalizeWorkspaceRelativePath(snapshot.activeFile)) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
const edit = deriveSingleFilePostImage(file, snapshot);
|
|
213
|
+
return edit === null ? null : [edit];
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Builds the action envelope to broadcast to the bridge. For applyPatch the contract textEdits are
|
|
220
|
+
// derived (whole-document replace) so the browser reviews a concrete edit; null means the patch could
|
|
221
|
+
// not be prepared and the action must be failed rather than queued. Every other action type is
|
|
222
|
+
// broadcast unchanged.
|
|
223
|
+
function buildEmitAction(action, snapshot) {
|
|
224
|
+
if (action.type !== "applyPatch")
|
|
225
|
+
return action;
|
|
226
|
+
const textEdits = deriveAgentPatchTextEdits(action, snapshot);
|
|
227
|
+
if (textEdits === null)
|
|
228
|
+
return null;
|
|
229
|
+
return { ...action, textEdits };
|
|
230
|
+
}
|
|
75
231
|
function targetFile(action, snapshot) {
|
|
76
232
|
return action.target?.file ?? snapshot.activeFile;
|
|
77
233
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
234
|
+
// Issue #1391 AC2 — reject a write action that does not pin the document revision it expects to write
|
|
235
|
+
// against. The contract owns both "what is a write action" and "what counts as a precondition"; the
|
|
236
|
+
// server only maps the missing-precondition rule onto the structured PRECONDITION_REQUIRED conflict.
|
|
237
|
+
function preconditionConflict(action) {
|
|
238
|
+
const error = editorAgentWritePreconditionError(action);
|
|
239
|
+
return error === null ? null : conflict(action, "PRECONDITION_REQUIRED", error);
|
|
83
240
|
}
|
|
84
241
|
function conflict(action, code, message) {
|
|
85
242
|
return {
|
|
@@ -91,19 +248,39 @@ function conflict(action, code, message) {
|
|
|
91
248
|
conflict: { code, message },
|
|
92
249
|
};
|
|
93
250
|
}
|
|
251
|
+
// The Issue #1391/#1394 structural write gates, unchanged: a doubly-invalid write reports its most
|
|
252
|
+
// specific failure. Non-write actions have no structural gate.
|
|
253
|
+
function structuralWriteConflict(action, snapshot) {
|
|
254
|
+
if (!isEditorAgentWriteActionType(action.type))
|
|
255
|
+
return null;
|
|
256
|
+
return (dirtyBufferConflict(action, snapshot) ??
|
|
257
|
+
documentVersionConflict(action, snapshot) ??
|
|
258
|
+
contentHashConflict(action, snapshot) ??
|
|
259
|
+
containmentConflict(action, snapshot) ??
|
|
260
|
+
sensitivePathConflict(action, snapshot) ??
|
|
261
|
+
textEditsConflict(action) ??
|
|
262
|
+
patchValidationConflict(action, snapshot) ??
|
|
263
|
+
preconditionConflict(action));
|
|
264
|
+
}
|
|
265
|
+
// Returns a structured conflict result when the action must not be admitted to the queue, or null when
|
|
266
|
+
// it is clear to enqueue. The structural gates run first (above); the Issue #1392 liveness gate runs
|
|
267
|
+
// last so any otherwise-valid action for a session with no live bridge is answered with the structured
|
|
268
|
+
// NO_ACTIVE_BRIDGE conflict (AC1) rather than queued where it could never be executed.
|
|
94
269
|
function preflight(action) {
|
|
95
|
-
const snapshot =
|
|
270
|
+
const snapshot = editorAgentRegistry.snapshotFor(action.sessionId);
|
|
96
271
|
if (snapshot === undefined) {
|
|
97
272
|
return conflict(action, "NO_ACTIVE_SESSION", "No active browser bridge is registered.");
|
|
98
273
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
274
|
+
const structural = structuralWriteConflict(action, snapshot);
|
|
275
|
+
if (structural !== null)
|
|
276
|
+
return structural;
|
|
277
|
+
if (!editorAgentRegistry.hasLiveBridge(action.sessionId)) {
|
|
278
|
+
return conflict(action, "NO_ACTIVE_BRIDGE", "No live browser bridge is connected for this session.");
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
104
281
|
}
|
|
105
282
|
export function handleEditorAgentSessions() {
|
|
106
|
-
return { status: 200, body: { sessions:
|
|
283
|
+
return { status: 200, body: { sessions: editorAgentRegistry.listSessions() } };
|
|
107
284
|
}
|
|
108
285
|
export async function handleEditorAgentSnapshot(ctx) {
|
|
109
286
|
const body = await readJsonObject(ctx.req, MAX_AGENT_BODY_BYTES);
|
|
@@ -114,13 +291,10 @@ export async function handleEditorAgentSnapshot(ctx) {
|
|
|
114
291
|
return { status: 400, body: errorBody("INVALID_REQUEST", parsed.errors.join("; ")) };
|
|
115
292
|
}
|
|
116
293
|
if ("kind" in parsed.value) {
|
|
117
|
-
|
|
118
|
-
emit({ type: "session", snapshot: parsed.value.snapshot });
|
|
294
|
+
editorAgentRegistry.registerSnapshot(parsed.value.snapshot);
|
|
119
295
|
return { status: 200, body: { snapshot: parsed.value.snapshot } };
|
|
120
296
|
}
|
|
121
|
-
const selected = parsed.value.sessionId
|
|
122
|
-
? [...sessions.values()][0]
|
|
123
|
-
: sessions.get(parsed.value.sessionId);
|
|
297
|
+
const selected = editorAgentRegistry.selectSnapshot(parsed.value.sessionId);
|
|
124
298
|
if (selected === undefined)
|
|
125
299
|
return { status: 200, body: { snapshot: null } };
|
|
126
300
|
const maxBytes = parsed.value.maxBytes ?? DEFAULT_SNAPSHOT_TEXT_BUDGET_BYTES;
|
|
@@ -129,6 +303,37 @@ export async function handleEditorAgentSnapshot(ctx) {
|
|
|
129
303
|
body: { snapshot: shapeSnapshot(selected, parsed.value.textMode, maxBytes) },
|
|
130
304
|
};
|
|
131
305
|
}
|
|
306
|
+
// Issue #1395 (ADR-0062) — the workspace-relative target path an action governs, or null when it has
|
|
307
|
+
// no file target. Used both for the policy decision and the (content-free) audit record.
|
|
308
|
+
function resolveActionTargetPath(action, snapshot) {
|
|
309
|
+
return action.target?.file ?? snapshot?.activeFile ?? null;
|
|
310
|
+
}
|
|
311
|
+
// Deterministic policy classification (AC2). Containment reuses the contract guard; sensitivity reuses
|
|
312
|
+
// the always-on workspace deny-list (a keiko-workspace concern the leaf classifier cannot reach, so
|
|
313
|
+
// the boolean is resolved here). Only meaningful for write actions; navigation/layout always allow.
|
|
314
|
+
function decideActionPolicy(action, snapshot) {
|
|
315
|
+
const targetPath = resolveActionTargetPath(action, snapshot);
|
|
316
|
+
const targetSensitive = targetPath !== null && isContainedAgentPath(targetPath) && isDenied(targetPath);
|
|
317
|
+
return classifyEditorAgentAction(action.type, { targetPath, targetSensitive });
|
|
318
|
+
}
|
|
319
|
+
// Issue #1395 (AC1) — record one content-free audit entry for this action at its admission decision.
|
|
320
|
+
// Best-effort: the ledger filters to mutating/denied actions and never throws. `editCount`/
|
|
321
|
+
// `patchByteLength` are counts only, never edit or patch content.
|
|
322
|
+
function auditAction(action, snapshot, decision, result) {
|
|
323
|
+
recordEditorAgentActionAudit({
|
|
324
|
+
occurredAt: Date.now(),
|
|
325
|
+
sessionId: action.sessionId,
|
|
326
|
+
actionId: action.actionId,
|
|
327
|
+
actionType: action.type,
|
|
328
|
+
decision,
|
|
329
|
+
outcome: result.status,
|
|
330
|
+
conflictCode: result.conflict?.code,
|
|
331
|
+
failureCode: result.failure?.code,
|
|
332
|
+
targetPath: resolveActionTargetPath(action, snapshot),
|
|
333
|
+
editCount: action.type === "applyTextEdits" ? action.textEdits?.length : undefined,
|
|
334
|
+
patchByteLength: action.type === "applyPatch" ? action.patch?.length : undefined,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
132
337
|
export async function handleEditorAgentActions(ctx) {
|
|
133
338
|
const body = await readJsonObject(ctx.req, MAX_AGENT_BODY_BYTES);
|
|
134
339
|
if (isRouteResult(body))
|
|
@@ -139,14 +344,14 @@ export async function handleEditorAgentActions(ctx) {
|
|
|
139
344
|
}
|
|
140
345
|
if (!isEditorAgentAction(parsed.value)) {
|
|
141
346
|
const result = parsed.value.result;
|
|
142
|
-
|
|
347
|
+
editorAgentRegistry.reportResult(result);
|
|
143
348
|
return { status: 200, body: { result } };
|
|
144
349
|
}
|
|
145
350
|
const action = parsed.value;
|
|
146
|
-
const
|
|
351
|
+
const requestHash = hashRequest(JSON.stringify(action));
|
|
147
352
|
const replay = idempotency.get(action.idempotencyKey);
|
|
148
353
|
if (replay !== undefined) {
|
|
149
|
-
if (replay.
|
|
354
|
+
if (replay.requestHash !== requestHash) {
|
|
150
355
|
return {
|
|
151
356
|
status: 409,
|
|
152
357
|
body: errorBody("IDEMPOTENCY_CONFLICT", "Idempotency-Key was reused with a different action."),
|
|
@@ -154,44 +359,76 @@ export async function handleEditorAgentActions(ctx) {
|
|
|
154
359
|
}
|
|
155
360
|
return { status: 200, body: { result: replay.result } };
|
|
156
361
|
}
|
|
362
|
+
const snapshot = editorAgentRegistry.snapshotFor(action.sessionId);
|
|
363
|
+
const decision = decideActionPolicy(action, snapshot);
|
|
157
364
|
const failed = preflight(action);
|
|
158
365
|
if (failed !== null) {
|
|
159
|
-
|
|
366
|
+
rememberIdempotency(action.idempotencyKey, requestHash, failed);
|
|
367
|
+
auditAction(action, snapshot, decision, failed);
|
|
368
|
+
editorAgentRegistry.reportResult(failed);
|
|
160
369
|
return { status: 409, body: { result: failed } };
|
|
161
370
|
}
|
|
162
|
-
|
|
371
|
+
return queueAndEmitAction(action, requestHash, snapshot, decision);
|
|
372
|
+
}
|
|
373
|
+
function failedResult(action, message) {
|
|
374
|
+
return {
|
|
163
375
|
schemaVersion: EDITOR_AGENT_SCHEMA_VERSION,
|
|
164
376
|
actionId: action.actionId,
|
|
165
377
|
sessionId: action.sessionId,
|
|
166
|
-
status: "
|
|
378
|
+
status: "failed",
|
|
379
|
+
message,
|
|
167
380
|
};
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
381
|
+
}
|
|
382
|
+
function queueAndEmitAction(action, requestHash, snapshot, decision) {
|
|
383
|
+
const emitAction = snapshot === undefined ? null : buildEmitAction(action, snapshot);
|
|
384
|
+
if (emitAction === null) {
|
|
385
|
+
const result = failedResult(action, "Patch could not be prepared for review.");
|
|
386
|
+
rememberIdempotency(action.idempotencyKey, requestHash, result);
|
|
387
|
+
auditAction(action, snapshot, decision, result);
|
|
388
|
+
return { status: 409, body: { result } };
|
|
389
|
+
}
|
|
390
|
+
const outcome = editorAgentRegistry.queueAction(action, emitAction);
|
|
391
|
+
rememberIdempotency(action.idempotencyKey, requestHash, outcome.result);
|
|
392
|
+
auditAction(action, snapshot, decision, outcome.result);
|
|
393
|
+
if (outcome.kind === "rejected") {
|
|
394
|
+
// QUEUE_FULL is backpressure (429); a duplicate in-flight actionId is a conflict (409).
|
|
395
|
+
const status = outcome.result.failure?.code === "QUEUE_FULL" ? 429 : 409;
|
|
396
|
+
return { status, body: { result: outcome.result } };
|
|
397
|
+
}
|
|
398
|
+
return { status: 202, body: { result: outcome.result } };
|
|
171
399
|
}
|
|
172
400
|
export function handleEditorAgentEvents(ctx) {
|
|
173
|
-
|
|
174
|
-
ctx
|
|
175
|
-
ctx.res.end();
|
|
176
|
-
});
|
|
401
|
+
const sessionId = ctx.url.searchParams.get("sessionId") ?? undefined;
|
|
402
|
+
openAgentSseStream(ctx, sessionId);
|
|
177
403
|
return STREAMING;
|
|
178
404
|
}
|
|
179
|
-
|
|
405
|
+
// Issue #1395 (ADR-0062, AC4) — read-only feed of the bounded audit ledger so users can inspect what
|
|
406
|
+
// an agent changed or attempted. Scoped to the session when `?sessionId=` is present; otherwise a
|
|
407
|
+
// bounded recent-activity view across sessions. Content-free records only (no raw source, no secrets).
|
|
408
|
+
export function handleEditorAgentAudit(ctx) {
|
|
409
|
+
const sessionId = ctx.url.searchParams.get("sessionId") ?? undefined;
|
|
410
|
+
return { status: 200, body: { records: listEditorAgentActionAudit(sessionId) } };
|
|
411
|
+
}
|
|
412
|
+
// Opens the SSE stream and registers the connection as either a session bridge (when `?sessionId=` is
|
|
413
|
+
// present) or a global observer. The disposer drops the subscription — and thus the bridge-liveness
|
|
414
|
+
// contribution — when the response closes (AC1: a dropped bridge makes the session unavailable again).
|
|
415
|
+
function openAgentSseStream(ctx, sessionId) {
|
|
416
|
+
const res = ctx.res;
|
|
180
417
|
res.writeHead(200, SSE_HEADERS);
|
|
181
418
|
const subscriber = (event) => {
|
|
182
419
|
const frame = `id: ${event.eventId}\nevent: editor-agent:${event.type}\ndata: ${JSON.stringify(event)}\n\n`;
|
|
183
420
|
if (!res.write(frame))
|
|
184
421
|
res.destroy();
|
|
185
422
|
};
|
|
186
|
-
|
|
423
|
+
const dispose = editorAgentRegistry.connect(sessionId, subscriber);
|
|
187
424
|
res.write(readyMessage());
|
|
188
|
-
|
|
189
|
-
|
|
425
|
+
ctx.req.on("close", () => {
|
|
426
|
+
res.end();
|
|
190
427
|
});
|
|
428
|
+
res.on("close", dispose);
|
|
191
429
|
}
|
|
192
430
|
export function _resetEditorAgentStateForTests() {
|
|
193
|
-
sessions.clear();
|
|
194
431
|
idempotency.clear();
|
|
195
|
-
|
|
196
|
-
|
|
432
|
+
editorAgentRegistry.reset();
|
|
433
|
+
_resetEditorAgentAuditForTests();
|
|
197
434
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type EditorAgentAction, type EditorAgentActionResult, type EditorAgentEvent, type EditorAgentSessionSnapshot } from "@oscharko-dev/keiko-contracts";
|
|
2
|
+
export declare const EDITOR_AGENT_ACTION_TIMEOUT_MS = 15000;
|
|
3
|
+
export declare const EDITOR_AGENT_MAX_QUEUED_PER_SESSION = 64;
|
|
4
|
+
export declare const EDITOR_AGENT_MAX_SESSIONS = 256;
|
|
5
|
+
export type EditorAgentSubscriber = (event: EditorAgentEvent) => void;
|
|
6
|
+
export interface EditorAgentRegistryOptions {
|
|
7
|
+
readonly actionTimeoutMs?: number | undefined;
|
|
8
|
+
readonly maxQueuedPerSession?: number | undefined;
|
|
9
|
+
readonly maxSessions?: number | undefined;
|
|
10
|
+
readonly setTimer?: ((handler: () => void, ms: number) => unknown) | undefined;
|
|
11
|
+
readonly clearTimer?: ((handle: unknown) => void) | undefined;
|
|
12
|
+
}
|
|
13
|
+
export type EditorAgentQueueOutcome = {
|
|
14
|
+
readonly kind: "queued";
|
|
15
|
+
readonly result: EditorAgentActionResult;
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: "rejected";
|
|
18
|
+
readonly result: EditorAgentActionResult;
|
|
19
|
+
};
|
|
20
|
+
export interface EditorAgentRegistry {
|
|
21
|
+
registerSnapshot(snapshot: EditorAgentSessionSnapshot): void;
|
|
22
|
+
listSessions(): readonly EditorAgentSessionSnapshot[];
|
|
23
|
+
snapshotFor(sessionId: string): EditorAgentSessionSnapshot | undefined;
|
|
24
|
+
selectSnapshot(sessionId?: string): EditorAgentSessionSnapshot | undefined;
|
|
25
|
+
hasLiveBridge(sessionId: string): boolean;
|
|
26
|
+
liveBridgeCount(sessionId: string): number;
|
|
27
|
+
connect(sessionId: string | undefined, send: EditorAgentSubscriber): () => void;
|
|
28
|
+
queueAction(action: EditorAgentAction, emitAction: EditorAgentAction): EditorAgentQueueOutcome;
|
|
29
|
+
reportResult(result: EditorAgentActionResult): void;
|
|
30
|
+
pendingCount(sessionId: string): number;
|
|
31
|
+
reset(): void;
|
|
32
|
+
}
|
|
33
|
+
export declare function createEditorAgentRegistry(options?: EditorAgentRegistryOptions): EditorAgentRegistry;
|
|
34
|
+
export declare const editorAgentRegistry: EditorAgentRegistry;
|
|
35
|
+
//# sourceMappingURL=agentSessionRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentSessionRegistry.d.ts","sourceRoot":"","sources":["../../src/editor/agentSessionRegistry.ts"],"names":[],"mappings":"AAsBA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EAErB,KAAK,0BAA0B,EAChC,MAAM,+BAA+B,CAAC;AAKvC,eAAO,MAAM,8BAA8B,QAAS,CAAC;AACrD,eAAO,MAAM,mCAAmC,KAAK,CAAC;AACtD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAEtE,MAAM,WAAW,0BAA0B;IAEzC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE9C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAElD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAG1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC/D;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAA;CAAE,GACrE;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAA;CAAE,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,CAAC,QAAQ,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAC7D,YAAY,IAAI,SAAS,0BAA0B,EAAE,CAAC;IACtD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS,CAAC;IACvE,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS,CAAC;IAC3E,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1C,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,qBAAqB,GAAG,MAAM,IAAI,CAAC;IAMhF,WAAW,CAAC,MAAM,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,GAAG,uBAAuB,CAAC;IAI/F,YAAY,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACpD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IACxC,KAAK,IAAI,IAAI,CAAC;CACf;AA2ND,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,0BAA+B,GACvC,mBAAmB,CAuCrB;AAID,eAAO,MAAM,mBAAmB,EAAE,mBAAiD,CAAC"}
|