@the-open-engine/zeroshot 6.38.1 → 6.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/event-copy.js +8 -7
- package/cli/event-copy.ts +12 -0
- package/cli/index.js +7 -31
- package/cli/json-export.js +61 -64
- package/cli/json-export.ts +112 -0
- package/cli/message-formatter-utils.js +68 -56
- package/cli/message-formatter-utils.ts +121 -0
- package/cli/message-formatters-normal.js +124 -259
- package/cli/message-formatters-normal.ts +250 -0
- package/cli/message-formatters-watch.js +81 -84
- package/cli/message-formatters-watch.ts +189 -0
- package/lib/cluster/generated/protocol-schema.cjs +1 -1
- package/lib/cluster/generated/protocol-schema.mjs +1 -1
- package/lib/cluster/generated/protocol.d.cts +8 -0
- package/lib/cluster/generated/protocol.d.mts +8 -0
- package/lib/cluster/generated/protocol.d.ts +8 -0
- package/lib/clusters-registry.d.ts +23 -0
- package/lib/clusters-registry.js +17 -29
- package/lib/completion.d.ts +12 -0
- package/lib/completion.js +84 -94
- package/lib/compose-utils.d.ts +32 -0
- package/lib/compose-utils.js +57 -72
- package/lib/detached-startup.d.ts +83 -0
- package/lib/detached-startup.js +231 -302
- package/lib/docker-config.d.ts +43 -0
- package/lib/docker-config.js +150 -325
- package/lib/docker-env-auth.d.ts +17 -0
- package/lib/docker-env-auth.js +75 -0
- package/lib/git-remote-utils.d.ts +48 -0
- package/lib/git-remote-utils.js +147 -213
- package/lib/id-detector.d.ts +15 -0
- package/lib/id-detector.js +37 -41
- package/lib/path-check.d.ts +30 -0
- package/lib/path-check.js +42 -45
- package/lib/process-liveness.d.ts +16 -0
- package/lib/process-liveness.js +19 -12
- package/lib/provider-credential-path.d.ts +16 -0
- package/lib/provider-credential-path.js +31 -29
- package/lib/provider-defaults.d.ts +30 -0
- package/lib/provider-defaults.js +47 -42
- package/lib/provider-detection.d.ts +11 -0
- package/lib/provider-detection.js +91 -54
- package/lib/provider-names.d.ts +38 -0
- package/lib/provider-names.js +56 -64
- package/lib/repo-settings.d.ts +28 -0
- package/lib/repo-settings.js +83 -59
- package/lib/run-mode.d.ts +21 -0
- package/lib/run-mode.js +21 -20
- package/lib/run-plan.d.ts +28 -0
- package/lib/run-plan.js +17 -16
- package/lib/settings/claude-auth.d.ts +35 -0
- package/lib/settings/claude-auth.js +30 -47
- package/lib/settings-defaults.d.ts +20 -0
- package/lib/settings-defaults.js +149 -0
- package/lib/settings-error.d.ts +7 -0
- package/lib/settings-error.js +8 -0
- package/lib/settings-issue-providers.d.ts +10 -0
- package/lib/settings-issue-providers.js +12 -0
- package/lib/settings-models.d.ts +22 -0
- package/lib/settings-models.js +93 -0
- package/lib/settings-storage.d.ts +23 -0
- package/lib/settings-storage.js +205 -0
- package/lib/settings-validation.d.ts +7 -0
- package/lib/settings-validation.js +182 -0
- package/lib/settings.d.ts +29 -0
- package/lib/settings.js +41 -736
- package/lib/setup-apply-types.d.ts +66 -0
- package/lib/setup-apply-types.js +2 -0
- package/lib/setup-apply.d.ts +39 -0
- package/lib/setup-apply.js +267 -264
- package/lib/setup-journal.d.ts +41 -0
- package/lib/setup-journal.js +119 -76
- package/lib/setup-plan-types.d.ts +102 -0
- package/lib/setup-plan-types.js +2 -0
- package/lib/setup-plan.d.ts +30 -0
- package/lib/setup-plan.js +300 -324
- package/lib/setup-undo.d.ts +44 -0
- package/lib/setup-undo.js +61 -74
- package/lib/start-cluster-config.d.ts +26 -0
- package/lib/start-cluster-config.js +56 -0
- package/lib/start-cluster-environment.d.ts +40 -0
- package/lib/start-cluster-environment.js +134 -0
- package/lib/start-cluster-run-options.d.ts +53 -0
- package/lib/start-cluster-run-options.js +147 -0
- package/lib/start-cluster.d.ts +64 -0
- package/lib/start-cluster.js +98 -454
- package/lib/stream-json-parser.d.ts +17 -0
- package/lib/stream-json-parser.js +51 -52
- package/npm-shrinkwrap.json +2 -2
- package/package.json +12 -6
- package/scripts/postinstall.js +27 -0
- package/scripts/rust-distribution.js +23 -14
- package/src/agent/agent-command-proofs-context.js +35 -45
- package/src/agent/agent-command-proofs-context.ts +87 -0
- package/src/agent/agent-config-settings.js +19 -0
- package/src/agent/agent-config-settings.ts +41 -0
- package/src/agent/agent-config.js +122 -231
- package/src/agent/agent-config.ts +285 -0
- package/src/agent/agent-context-builder.js +38 -273
- package/src/agent/agent-context-builder.ts +51 -0
- package/src/agent/agent-context-environment-sections.js +105 -0
- package/src/agent/agent-context-environment-sections.ts +134 -0
- package/src/agent/agent-context-packs.js +165 -0
- package/src/agent/agent-context-packs.ts +296 -0
- package/src/agent/agent-context-prompt-sections.js +100 -0
- package/src/agent/agent-context-prompt-sections.ts +148 -0
- package/src/agent/agent-context-sections.js +25 -334
- package/src/agent/agent-context-sections.ts +36 -0
- package/src/agent/agent-context-sources.js +96 -149
- package/src/agent/agent-context-sources.ts +253 -0
- package/src/agent/agent-context-types.js +2 -0
- package/src/agent/agent-context-types.ts +132 -0
- package/src/agent/agent-context-validation-sections.js +73 -0
- package/src/agent/agent-context-validation-sections.ts +129 -0
- package/src/agent/agent-input-injector.js +99 -118
- package/src/agent/agent-input-injector.ts +195 -0
- package/src/agent/agent-liveness-poll.js +74 -78
- package/src/agent/agent-liveness-poll.ts +163 -0
- package/src/agent/agent-quality-gate-schema.js +77 -86
- package/src/agent/agent-quality-gate-schema.ts +135 -0
- package/src/agent/agent-quality-gates-context.js +44 -50
- package/src/agent/agent-quality-gates-context.ts +91 -0
- package/src/agent/agent-stuck-detector.js +171 -239
- package/src/agent/agent-stuck-detector.ts +288 -0
- package/src/agent/agent-trigger-evaluator.js +29 -46
- package/src/agent/agent-trigger-evaluator.ts +98 -0
- package/src/agent/context-metrics.js +110 -141
- package/src/agent/context-metrics.ts +261 -0
- package/src/agent/context-pack-builder.js +72 -358
- package/src/agent/context-pack-builder.ts +105 -0
- package/src/agent/context-pack-core.js +70 -0
- package/src/agent/context-pack-core.ts +96 -0
- package/src/agent/context-pack-selection.js +119 -0
- package/src/agent/context-pack-selection.ts +187 -0
- package/src/agent/context-pack-truncation.js +139 -0
- package/src/agent/context-pack-truncation.ts +208 -0
- package/src/agent/context-pack-types.js +2 -0
- package/src/agent/context-pack-types.ts +98 -0
- package/src/agent/context-replay-policy.js +30 -39
- package/src/agent/context-replay-policy.ts +71 -0
- package/src/agent/critical-agent-policy.js +6 -10
- package/src/agent/critical-agent-policy.ts +20 -0
- package/src/agent/guidance-queue.js +74 -87
- package/src/agent/guidance-queue.ts +166 -0
- package/src/agent/output-extraction-error-detail.js +45 -0
- package/src/agent/output-extraction-error-detail.ts +49 -0
- package/src/agent/output-extraction-failures.js +125 -0
- package/src/agent/output-extraction-failures.ts +149 -0
- package/src/agent/output-extraction-json.js +234 -0
- package/src/agent/output-extraction-json.ts +235 -0
- package/src/agent/output-extraction-pi.js +124 -0
- package/src/agent/output-extraction-pi.ts +137 -0
- package/src/agent/output-extraction-types.js +2 -0
- package/src/agent/output-extraction-types.ts +49 -0
- package/src/agent/output-extraction.js +17 -617
- package/src/agent/output-extraction.ts +30 -0
- package/src/agent/output-reformatter-errors.js +83 -0
- package/src/agent/output-reformatter-errors.ts +106 -0
- package/src/agent/output-reformatter-types.js +2 -0
- package/src/agent/output-reformatter-types.ts +86 -0
- package/src/agent/output-reformatter.js +140 -185
- package/src/agent/output-reformatter.ts +238 -0
- package/src/agent/pi-terminal-lifecycle-types.js +2 -0
- package/src/agent/pi-terminal-lifecycle-types.ts +41 -0
- package/src/agent/pi-terminal-lifecycle.js +186 -206
- package/src/agent/pi-terminal-lifecycle.ts +297 -0
- package/src/agent/provider-control-plane.js +22 -21
- package/src/agent/provider-control-plane.ts +52 -0
- package/src/agent/provider-terminal-failure-types.js +2 -0
- package/src/agent/provider-terminal-failure-types.ts +60 -0
- package/src/agent/provider-terminal-failure.js +194 -191
- package/src/agent/provider-terminal-failure.ts +262 -0
- package/src/agent/rate-limit-backoff.js +31 -74
- package/src/agent/rate-limit-backoff.ts +71 -0
- package/src/agent/schema-utils.js +85 -125
- package/src/agent/schema-utils.ts +148 -0
- package/src/agent/structured-output-error.js +34 -33
- package/src/agent/structured-output-error.ts +105 -0
- package/src/agent/validation-platform.js +27 -27
- package/src/agent/validation-platform.ts +49 -0
- package/src/attach/attach-client.js +232 -405
- package/src/attach/attach-client.ts +300 -0
- package/src/attach/attach-server-cleanup.js +43 -0
- package/src/attach/attach-server-cleanup.ts +39 -0
- package/src/attach/attach-server-clients.js +117 -0
- package/src/attach/attach-server-clients.ts +122 -0
- package/src/attach/attach-server-events.js +38 -0
- package/src/attach/attach-server-events.ts +36 -0
- package/src/attach/attach-server-pty.js +45 -0
- package/src/attach/attach-server-pty.ts +64 -0
- package/src/attach/attach-server-runtime.js +73 -0
- package/src/attach/attach-server-runtime.ts +62 -0
- package/src/attach/attach-server-socket.js +28 -0
- package/src/attach/attach-server-socket.ts +23 -0
- package/src/attach/attach-server-types.js +2 -0
- package/src/attach/attach-server-types.ts +82 -0
- package/src/attach/attach-server.js +106 -523
- package/src/attach/attach-server.ts +158 -0
- package/src/attach/index.js +18 -35
- package/src/attach/index.ts +18 -0
- package/src/attach/protocol.js +95 -184
- package/src/attach/protocol.ts +181 -0
- package/src/attach/ring-buffer.js +76 -102
- package/src/attach/ring-buffer.ts +109 -0
- package/src/attach/send-input.js +64 -75
- package/src/attach/send-input.ts +94 -0
- package/src/attach/socket-discovery.js +164 -218
- package/src/attach/socket-discovery.ts +230 -0
- package/src/attach/socket-paths.js +42 -61
- package/src/attach/socket-paths.ts +81 -0
- package/src/claude-credentials.js +51 -54
- package/src/claude-credentials.ts +89 -0
- package/src/cluster/generated/protocol-schema.ts +1 -1
- package/src/cluster/generated/protocol.ts +2 -1
- package/src/command-proofs.js +110 -141
- package/src/command-proofs.ts +216 -0
- package/src/config-router.js +81 -73
- package/src/config-router.ts +131 -0
- package/src/copy-worker.js +53 -29
- package/src/copy-worker.ts +75 -0
- package/src/darwin-keychain-boundary.js +80 -111
- package/src/darwin-keychain-boundary.ts +148 -0
- package/src/guidance-topics.js +4 -5
- package/src/guidance-topics.ts +10 -0
- package/src/input-helpers.js +33 -54
- package/src/input-helpers.ts +58 -0
- package/src/ledger-sequence.js +45 -48
- package/src/ledger-sequence.ts +63 -0
- package/src/legacy-lib/clusters-registry.ts +40 -0
- package/src/legacy-lib/completion.ts +148 -0
- package/src/legacy-lib/compose-utils.ts +102 -0
- package/src/legacy-lib/detached-startup.ts +449 -0
- package/src/legacy-lib/docker-config.ts +282 -0
- package/src/legacy-lib/docker-env-auth.ts +116 -0
- package/src/legacy-lib/git-remote-utils.ts +244 -0
- package/src/legacy-lib/id-detector.ts +57 -0
- package/src/legacy-lib/js-yaml.d.ts +3 -0
- package/src/legacy-lib/omelette.d.ts +15 -0
- package/src/legacy-lib/path-check.ts +89 -0
- package/src/legacy-lib/process-liveness.ts +36 -0
- package/src/legacy-lib/provider-credential-path.ts +57 -0
- package/src/legacy-lib/provider-defaults.ts +114 -0
- package/src/legacy-lib/provider-detection.ts +67 -0
- package/src/legacy-lib/provider-names.ts +126 -0
- package/src/legacy-lib/repo-settings.ts +88 -0
- package/src/legacy-lib/run-mode.ts +58 -0
- package/src/legacy-lib/run-plan.ts +49 -0
- package/src/legacy-lib/settings/claude-auth.ts +80 -0
- package/src/legacy-lib/settings-defaults.ts +212 -0
- package/src/legacy-lib/settings-error.ts +8 -0
- package/src/legacy-lib/settings-issue-providers.ts +18 -0
- package/src/legacy-lib/settings-models.ts +124 -0
- package/src/legacy-lib/settings-storage.ts +277 -0
- package/src/legacy-lib/settings-validation.ts +220 -0
- package/src/legacy-lib/settings.ts +87 -0
- package/src/legacy-lib/setup-apply-types.ts +70 -0
- package/src/legacy-lib/setup-apply.ts +456 -0
- package/src/legacy-lib/setup-journal.ts +185 -0
- package/src/legacy-lib/setup-plan-types.ts +96 -0
- package/src/legacy-lib/setup-plan.ts +500 -0
- package/src/legacy-lib/setup-undo.ts +142 -0
- package/src/legacy-lib/start-cluster-config.ts +124 -0
- package/src/legacy-lib/start-cluster-environment.ts +165 -0
- package/src/legacy-lib/start-cluster-run-options.ts +279 -0
- package/src/legacy-lib/start-cluster.ts +237 -0
- package/src/legacy-lib/stream-json-parser.ts +88 -0
- package/src/message-buffer.js +55 -71
- package/src/message-buffer.ts +107 -0
- package/src/message-bus-bridge.js +92 -133
- package/src/message-bus-bridge.ts +149 -0
- package/src/name-generator-shared.js +220 -0
- package/src/name-generator-shared.ts +231 -0
- package/src/name-generator.js +8 -217
- package/src/name-generator.ts +27 -0
- package/src/omp-blob-root.js +83 -64
- package/src/omp-blob-root.ts +116 -0
- package/src/omp-config-overlay.js +65 -38
- package/src/omp-config-overlay.ts +110 -0
- package/src/omp-execution-fingerprint.js +38 -43
- package/src/omp-execution-fingerprint.ts +92 -0
- package/src/omp-session-limits.js +10 -15
- package/src/omp-session-limits.ts +53 -0
- package/src/omp-session-partition.js +2 -2
- package/src/omp-session-verifier.js +1 -1
- package/src/orchestrator.js +19 -4
- package/src/providers/anthropic/index.js +3 -1
- package/src/providers/anthropic/index.ts +13 -0
- package/src/providers/capabilities.js +19 -27
- package/src/providers/capabilities.ts +44 -0
- package/src/providers/google/index.js +3 -1
- package/src/providers/google/index.ts +13 -0
- package/src/providers/openai/index.js +3 -1
- package/src/providers/openai/index.ts +13 -0
- package/src/providers/opencode/index.js +3 -1
- package/src/providers/opencode/index.ts +13 -0
- package/src/quality-gates.js +67 -127
- package/src/quality-gates.ts +149 -0
- package/src/repo-settings-access.js +40 -0
- package/src/repo-settings-access.ts +64 -0
- package/src/schemas/sub-cluster.js +127 -183
- package/src/schemas/sub-cluster.ts +238 -0
- package/src/state-snapshot-normalization.js +224 -0
- package/src/state-snapshot-normalization.ts +222 -0
- package/src/state-snapshot.js +192 -359
- package/src/state-snapshot.ts +291 -0
- package/src/state-snapshotter.js +118 -130
- package/src/state-snapshotter.ts +167 -0
- package/src/sub-cluster-wrapper.js +4 -13
- package/src/task-run-model-args.js +87 -124
- package/src/task-run-model-args.ts +204 -0
- package/src/task-runner.js +5 -25
- package/src/task-runner.ts +28 -0
- package/src/task-startup-error.js +73 -58
- package/src/task-startup-error.ts +126 -0
- package/src/template-validation/consensus-gate-contracts.js +2 -0
- package/src/template-validation/consensus-gate-contracts.ts +70 -0
- package/src/template-validation/consensus-gate-scenarios.js +76 -0
- package/src/template-validation/consensus-gate-scenarios.ts +130 -0
- package/src/template-validation/consensus-gate-stage.js +34 -0
- package/src/template-validation/consensus-gate-stage.ts +56 -0
- package/src/template-validation/random-topology-contracts.js +2 -0
- package/src/template-validation/random-topology-contracts.ts +54 -0
- package/src/template-validation/random-topology-dispatch.js +25 -0
- package/src/template-validation/random-topology-dispatch.ts +33 -0
- package/src/template-validation/random-topology-message-loop.js +53 -0
- package/src/template-validation/random-topology-message-loop.ts +73 -0
- package/src/template-validation/random-topology-operations.js +79 -0
- package/src/template-validation/random-topology-operations.ts +101 -0
- package/src/template-validation/random-topology-runtime.js +25 -0
- package/src/template-validation/random-topology-runtime.ts +43 -0
- package/src/template-validation/random-topology-scenario.js +52 -0
- package/src/template-validation/random-topology-scenario.ts +57 -0
- package/src/template-validation/random-topology-schema.js +159 -0
- package/src/template-validation/random-topology-schema.ts +190 -0
- package/src/template-validation/random-topology-state.js +28 -0
- package/src/template-validation/random-topology-state.ts +30 -0
- package/src/template-validation/random-topology-trigger-evaluation.js +45 -0
- package/src/template-validation/random-topology-trigger-evaluation.ts +65 -0
- package/src/template-validation/random-topology-trigger.js +75 -0
- package/src/template-validation/random-topology-trigger.ts +88 -0
- package/src/template-validation/report-formatter.js +40 -46
- package/src/template-validation/report-formatter.ts +101 -0
- package/src/template-validation/simulate-consensus-gates.js +111 -302
- package/src/template-validation/simulate-consensus-gates.ts +196 -0
- package/src/template-validation/simulate-random-topology.js +26 -519
- package/src/template-validation/simulate-random-topology.ts +57 -0
- package/src/template-validation/simulate-two-stage-validation.js +41 -265
- package/src/template-validation/simulate-two-stage-validation.ts +55 -0
- package/src/template-validation/simulation-agent-runtime.js +25 -0
- package/src/template-validation/simulation-agent-runtime.ts +40 -0
- package/src/template-validation/simulation-agent.js +29 -0
- package/src/template-validation/simulation-agent.ts +73 -0
- package/src/template-validation/simulation-runtime.js +34 -0
- package/src/template-validation/simulation-runtime.ts +72 -0
- package/src/template-validation/two-stage-contracts.js +2 -0
- package/src/template-validation/two-stage-contracts.ts +41 -0
- package/src/template-validation/two-stage-inputs.js +21 -0
- package/src/template-validation/two-stage-inputs.ts +29 -0
- package/src/template-validation/two-stage-results.js +30 -0
- package/src/template-validation/two-stage-results.ts +40 -0
- package/src/template-validation/two-stage-scenario.js +86 -0
- package/src/template-validation/two-stage-scenario.ts +120 -0
- package/src/worktree-claude-config.js +182 -220
- package/src/worktree-claude-config.ts +272 -0
- package/src/worktree-tooling-env.js +103 -125
- package/src/worktree-tooling-env.ts +142 -0
- package/task-lib/completion.js +2 -3
- package/task-lib/completion.ts +9 -0
- package/task-lib/config.js +1 -4
- package/task-lib/config.ts +11 -0
- package/task-lib/name-generator.js +4 -226
- package/task-lib/name-generator.ts +11 -0
- package/task-lib/omp-session-cleanup.js +1 -1
- package/task-lib/omp-storage-root.js +8 -12
- package/task-lib/omp-storage-root.ts +62 -0
- package/task-lib/process-termination.js +143 -166
- package/task-lib/process-termination.ts +268 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol - Message framing for attach/detach IPC
|
|
3
|
+
*
|
|
4
|
+
* Uses length-prefixed JSON messages over Unix sockets.
|
|
5
|
+
* Format: [4-byte length (BE)] [JSON payload]
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const MAX_MESSAGE_SIZE = 10 * 1024 * 1024; // 10MB max message
|
|
9
|
+
|
|
10
|
+
const MessageType = {
|
|
11
|
+
// Client → Server
|
|
12
|
+
ATTACH: 'attach',
|
|
13
|
+
DETACH: 'detach',
|
|
14
|
+
RESIZE: 'resize',
|
|
15
|
+
SIGNAL: 'signal',
|
|
16
|
+
STDIN: 'stdin',
|
|
17
|
+
|
|
18
|
+
// Server → Client
|
|
19
|
+
OUTPUT: 'output',
|
|
20
|
+
HISTORY: 'history',
|
|
21
|
+
STATE: 'state',
|
|
22
|
+
EXIT: 'exit',
|
|
23
|
+
ERROR: 'error',
|
|
24
|
+
} as const;
|
|
25
|
+
|
|
26
|
+
type BinaryData = Buffer | string;
|
|
27
|
+
type MessageWithData = { data?: string | null };
|
|
28
|
+
type AttachMessage = {
|
|
29
|
+
type: typeof MessageType.ATTACH;
|
|
30
|
+
clientId: string;
|
|
31
|
+
cols: number;
|
|
32
|
+
rows: number;
|
|
33
|
+
};
|
|
34
|
+
type DetachMessage = { type: typeof MessageType.DETACH; clientId: string };
|
|
35
|
+
type ResizeMessage = { type: typeof MessageType.RESIZE; cols: number; rows: number };
|
|
36
|
+
type SignalMessage = { type: typeof MessageType.SIGNAL; signal: string };
|
|
37
|
+
type DataMessage<T extends string> = { type: T; data: string };
|
|
38
|
+
type OutputMessage = DataMessage<typeof MessageType.OUTPUT> & { timestamp: number };
|
|
39
|
+
type ExitMessage = {
|
|
40
|
+
type: typeof MessageType.EXIT;
|
|
41
|
+
code: number | null;
|
|
42
|
+
signal: string | number | undefined | null;
|
|
43
|
+
};
|
|
44
|
+
type ErrorMessage = { type: typeof MessageType.ERROR; message: string };
|
|
45
|
+
|
|
46
|
+
/** Encode a message for transmission. */
|
|
47
|
+
function encode(message: object): Buffer {
|
|
48
|
+
const json = JSON.stringify(message) as string;
|
|
49
|
+
const payload = Buffer.from(json, 'utf8');
|
|
50
|
+
|
|
51
|
+
if (payload.length > MAX_MESSAGE_SIZE) {
|
|
52
|
+
throw new Error(`Message too large: ${payload.length} bytes (max ${MAX_MESSAGE_SIZE})`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const frame = Buffer.alloc(4 + payload.length);
|
|
56
|
+
frame.writeUInt32BE(payload.length, 0);
|
|
57
|
+
payload.copy(frame, 4);
|
|
58
|
+
|
|
59
|
+
return frame;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Streaming decoder for framed messages. */
|
|
63
|
+
class MessageDecoder {
|
|
64
|
+
buffer: Buffer;
|
|
65
|
+
|
|
66
|
+
constructor() {
|
|
67
|
+
this.buffer = Buffer.alloc(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Feed a received data chunk into the decoder. */
|
|
71
|
+
feed(data: Buffer): unknown[] {
|
|
72
|
+
this.buffer = Buffer.concat([this.buffer, data]);
|
|
73
|
+
const messages: unknown[] = [];
|
|
74
|
+
|
|
75
|
+
while (this.buffer.length >= 4) {
|
|
76
|
+
const length = this.buffer.readUInt32BE(0);
|
|
77
|
+
|
|
78
|
+
if (length > MAX_MESSAGE_SIZE) {
|
|
79
|
+
throw new Error(`Message too large: ${length} bytes (max ${MAX_MESSAGE_SIZE})`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (this.buffer.length < 4 + length) {
|
|
83
|
+
// Incomplete message, wait for more data
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const payload = this.buffer.slice(4, 4 + length);
|
|
88
|
+
this.buffer = this.buffer.slice(4 + length);
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const message: unknown = JSON.parse(payload.toString('utf8'));
|
|
92
|
+
messages.push(message);
|
|
93
|
+
} catch (error: unknown) {
|
|
94
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
95
|
+
throw new Error(`Invalid JSON in message: ${reason}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return messages;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Reset decoder state. */
|
|
103
|
+
reset(): void {
|
|
104
|
+
this.buffer = Buffer.alloc(0);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function createAttachMessage(clientId: string, cols: number, rows: number): AttachMessage {
|
|
109
|
+
return { type: MessageType.ATTACH, clientId, cols, rows };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function createDetachMessage(clientId: string): DetachMessage {
|
|
113
|
+
return { type: MessageType.DETACH, clientId };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function createResizeMessage(cols: number, rows: number): ResizeMessage {
|
|
117
|
+
return { type: MessageType.RESIZE, cols, rows };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function createSignalMessage(signal: string): SignalMessage {
|
|
121
|
+
if (!['SIGINT', 'SIGTERM', 'SIGKILL', 'SIGTSTP'].includes(signal)) {
|
|
122
|
+
throw new Error(`Invalid signal: ${signal}`);
|
|
123
|
+
}
|
|
124
|
+
return { type: MessageType.SIGNAL, signal };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function createStdinMessage(data: BinaryData): DataMessage<typeof MessageType.STDIN> {
|
|
128
|
+
const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
129
|
+
return { type: MessageType.STDIN, data: buf.toString('base64') };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function createOutputMessage(data: BinaryData, timestamp = Date.now()): OutputMessage {
|
|
133
|
+
const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
134
|
+
return { type: MessageType.OUTPUT, data: buf.toString('base64'), timestamp };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function createHistoryMessage(data: BinaryData): DataMessage<typeof MessageType.HISTORY> {
|
|
138
|
+
const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
139
|
+
return { type: MessageType.HISTORY, data: buf.toString('base64') };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function createStateMessage(state: Record<string, unknown>): Record<string, unknown> {
|
|
143
|
+
return { type: MessageType.STATE, ...state };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function createExitMessage(
|
|
147
|
+
code: number | null,
|
|
148
|
+
signal: string | number | undefined | null
|
|
149
|
+
): ExitMessage {
|
|
150
|
+
return { type: MessageType.EXIT, code, signal };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function createErrorMessage(message: string): ErrorMessage {
|
|
154
|
+
return { type: MessageType.ERROR, message };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Decode the base64 data field from OUTPUT/HISTORY/STDIN messages. */
|
|
158
|
+
function decodeData(message: MessageWithData): Buffer | null {
|
|
159
|
+
if (message.data) {
|
|
160
|
+
return Buffer.from(message.data, 'base64');
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export = {
|
|
166
|
+
encode,
|
|
167
|
+
MessageDecoder,
|
|
168
|
+
MessageType,
|
|
169
|
+
createAttachMessage,
|
|
170
|
+
createDetachMessage,
|
|
171
|
+
createResizeMessage,
|
|
172
|
+
createSignalMessage,
|
|
173
|
+
createStdinMessage,
|
|
174
|
+
createOutputMessage,
|
|
175
|
+
createHistoryMessage,
|
|
176
|
+
createStateMessage,
|
|
177
|
+
createExitMessage,
|
|
178
|
+
createErrorMessage,
|
|
179
|
+
decodeData,
|
|
180
|
+
MAX_MESSAGE_SIZE,
|
|
181
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* RingBuffer - Fixed-size circular buffer for output history
|
|
3
4
|
*
|
|
@@ -9,113 +10,86 @@
|
|
|
9
10
|
* - O(1) write and read operations
|
|
10
11
|
* - Thread-safe for single writer (Node.js is single-threaded)
|
|
11
12
|
*/
|
|
12
|
-
|
|
13
13
|
class RingBuffer {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
buffer;
|
|
15
|
+
maxSize;
|
|
16
|
+
writePos;
|
|
17
|
+
size;
|
|
18
|
+
/**
|
|
19
|
+
* @param maxSize - Maximum buffer size in bytes (default 1MB)
|
|
20
|
+
*/
|
|
21
|
+
constructor(maxSize = 1024 * 1024) {
|
|
22
|
+
if (maxSize <= 0) {
|
|
23
|
+
throw new Error('RingBuffer maxSize must be positive');
|
|
24
|
+
}
|
|
25
|
+
this.buffer = Buffer.alloc(maxSize);
|
|
26
|
+
this.maxSize = maxSize;
|
|
27
|
+
this.writePos = 0; // Next write position
|
|
28
|
+
this.size = 0; // Current data size (0 to maxSize)
|
|
20
29
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
/** Write data to the buffer. */
|
|
31
|
+
write(data) {
|
|
32
|
+
const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
33
|
+
if (buf.length === 0)
|
|
34
|
+
return;
|
|
35
|
+
// If data is larger than buffer, only keep the last maxSize bytes
|
|
36
|
+
if (buf.length >= this.maxSize) {
|
|
37
|
+
buf.copy(this.buffer, 0, buf.length - this.maxSize);
|
|
38
|
+
this.writePos = 0;
|
|
39
|
+
this.size = this.maxSize;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Calculate how much wraps around
|
|
43
|
+
const spaceToEnd = this.maxSize - this.writePos;
|
|
44
|
+
if (buf.length <= spaceToEnd) {
|
|
45
|
+
// No wrap needed
|
|
46
|
+
buf.copy(this.buffer, this.writePos);
|
|
47
|
+
this.writePos += buf.length;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// Wrap around
|
|
51
|
+
buf.copy(this.buffer, this.writePos, 0, spaceToEnd);
|
|
52
|
+
buf.copy(this.buffer, 0, spaceToEnd);
|
|
53
|
+
this.writePos = buf.length - spaceToEnd;
|
|
54
|
+
}
|
|
55
|
+
// Update size (capped at maxSize)
|
|
56
|
+
this.size = Math.min(this.size + buf.length, this.maxSize);
|
|
42
57
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
/** Read all buffered data. */
|
|
59
|
+
read() {
|
|
60
|
+
if (this.size === 0) {
|
|
61
|
+
return Buffer.alloc(0);
|
|
62
|
+
}
|
|
63
|
+
const result = Buffer.alloc(this.size);
|
|
64
|
+
if (this.size < this.maxSize) {
|
|
65
|
+
// Buffer not full yet, data starts at 0
|
|
66
|
+
this.buffer.copy(result, 0, 0, this.size);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// Buffer is full, data starts at writePos (oldest data)
|
|
70
|
+
const startPos = this.writePos;
|
|
71
|
+
const firstChunkSize = this.maxSize - startPos;
|
|
72
|
+
this.buffer.copy(result, 0, startPos, this.maxSize);
|
|
73
|
+
this.buffer.copy(result, firstChunkSize, 0, startPos);
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
56
76
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Read all buffered data
|
|
64
|
-
* @returns {Buffer} - All data currently in buffer
|
|
65
|
-
*/
|
|
66
|
-
read() {
|
|
67
|
-
if (this.size === 0) {
|
|
68
|
-
return Buffer.alloc(0);
|
|
77
|
+
/** Clear the buffer. */
|
|
78
|
+
clear() {
|
|
79
|
+
this.writePos = 0;
|
|
80
|
+
this.size = 0;
|
|
69
81
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this.buffer.copy(result, 0, startPos, this.maxSize);
|
|
82
|
-
this.buffer.copy(result, firstChunkSize, 0, startPos);
|
|
82
|
+
/** Get current data size. */
|
|
83
|
+
getSize() {
|
|
84
|
+
return this.size;
|
|
85
|
+
}
|
|
86
|
+
/** Check if buffer is empty. */
|
|
87
|
+
isEmpty() {
|
|
88
|
+
return this.size === 0;
|
|
89
|
+
}
|
|
90
|
+
/** Check if buffer is full. */
|
|
91
|
+
isFull() {
|
|
92
|
+
return this.size === this.maxSize;
|
|
83
93
|
}
|
|
84
|
-
|
|
85
|
-
return result;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Clear the buffer
|
|
90
|
-
*/
|
|
91
|
-
clear() {
|
|
92
|
-
this.writePos = 0;
|
|
93
|
-
this.size = 0;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Get current data size
|
|
98
|
-
* @returns {number}
|
|
99
|
-
*/
|
|
100
|
-
getSize() {
|
|
101
|
-
return this.size;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Check if buffer is empty
|
|
106
|
-
* @returns {boolean}
|
|
107
|
-
*/
|
|
108
|
-
isEmpty() {
|
|
109
|
-
return this.size === 0;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Check if buffer is full
|
|
114
|
-
* @returns {boolean}
|
|
115
|
-
*/
|
|
116
|
-
isFull() {
|
|
117
|
-
return this.size === this.maxSize;
|
|
118
|
-
}
|
|
119
94
|
}
|
|
120
|
-
|
|
121
95
|
module.exports = RingBuffer;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RingBuffer - Fixed-size circular buffer for output history
|
|
3
|
+
*
|
|
4
|
+
* Used by AttachServer to store recent output for late-joining clients.
|
|
5
|
+
* When buffer fills, oldest data is overwritten.
|
|
6
|
+
*
|
|
7
|
+
* Design:
|
|
8
|
+
* - Fixed allocation (no dynamic resizing)
|
|
9
|
+
* - O(1) write and read operations
|
|
10
|
+
* - Thread-safe for single writer (Node.js is single-threaded)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
class RingBuffer {
|
|
14
|
+
buffer: Buffer;
|
|
15
|
+
maxSize: number;
|
|
16
|
+
writePos: number;
|
|
17
|
+
size: number;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param maxSize - Maximum buffer size in bytes (default 1MB)
|
|
21
|
+
*/
|
|
22
|
+
constructor(maxSize = 1024 * 1024) {
|
|
23
|
+
if (maxSize <= 0) {
|
|
24
|
+
throw new Error('RingBuffer maxSize must be positive');
|
|
25
|
+
}
|
|
26
|
+
this.buffer = Buffer.alloc(maxSize);
|
|
27
|
+
this.maxSize = maxSize;
|
|
28
|
+
this.writePos = 0; // Next write position
|
|
29
|
+
this.size = 0; // Current data size (0 to maxSize)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Write data to the buffer. */
|
|
33
|
+
write(data: Buffer | string): void {
|
|
34
|
+
const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
35
|
+
|
|
36
|
+
if (buf.length === 0) return;
|
|
37
|
+
|
|
38
|
+
// If data is larger than buffer, only keep the last maxSize bytes
|
|
39
|
+
if (buf.length >= this.maxSize) {
|
|
40
|
+
buf.copy(this.buffer, 0, buf.length - this.maxSize);
|
|
41
|
+
this.writePos = 0;
|
|
42
|
+
this.size = this.maxSize;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Calculate how much wraps around
|
|
47
|
+
const spaceToEnd = this.maxSize - this.writePos;
|
|
48
|
+
|
|
49
|
+
if (buf.length <= spaceToEnd) {
|
|
50
|
+
// No wrap needed
|
|
51
|
+
buf.copy(this.buffer, this.writePos);
|
|
52
|
+
this.writePos += buf.length;
|
|
53
|
+
} else {
|
|
54
|
+
// Wrap around
|
|
55
|
+
buf.copy(this.buffer, this.writePos, 0, spaceToEnd);
|
|
56
|
+
buf.copy(this.buffer, 0, spaceToEnd);
|
|
57
|
+
this.writePos = buf.length - spaceToEnd;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Update size (capped at maxSize)
|
|
61
|
+
this.size = Math.min(this.size + buf.length, this.maxSize);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Read all buffered data. */
|
|
65
|
+
read(): Buffer {
|
|
66
|
+
if (this.size === 0) {
|
|
67
|
+
return Buffer.alloc(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const result = Buffer.alloc(this.size);
|
|
71
|
+
|
|
72
|
+
if (this.size < this.maxSize) {
|
|
73
|
+
// Buffer not full yet, data starts at 0
|
|
74
|
+
this.buffer.copy(result, 0, 0, this.size);
|
|
75
|
+
} else {
|
|
76
|
+
// Buffer is full, data starts at writePos (oldest data)
|
|
77
|
+
const startPos = this.writePos;
|
|
78
|
+
const firstChunkSize = this.maxSize - startPos;
|
|
79
|
+
|
|
80
|
+
this.buffer.copy(result, 0, startPos, this.maxSize);
|
|
81
|
+
this.buffer.copy(result, firstChunkSize, 0, startPos);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Clear the buffer. */
|
|
88
|
+
clear(): void {
|
|
89
|
+
this.writePos = 0;
|
|
90
|
+
this.size = 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Get current data size. */
|
|
94
|
+
getSize(): number {
|
|
95
|
+
return this.size;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Check if buffer is empty. */
|
|
99
|
+
isEmpty(): boolean {
|
|
100
|
+
return this.size === 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Check if buffer is full. */
|
|
104
|
+
isFull(): boolean {
|
|
105
|
+
return this.size === this.maxSize;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export = RingBuffer;
|
package/src/attach/send-input.js
CHANGED
|
@@ -1,88 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* sendInput - write stdin data to a live attach socket
|
|
3
4
|
*
|
|
4
5
|
* Uses the attach protocol's STDIN message to forward input to the PTY.
|
|
5
6
|
* Returns { ok, error } instead of throwing on transport failures.
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
12
|
+
const node_net_1 = __importDefault(require("node:net"));
|
|
13
|
+
const protocol_1 = __importDefault(require("./protocol"));
|
|
12
14
|
const DEFAULT_TIMEOUT_MS = 1500;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Send input to an attach socket via STDIN message.
|
|
16
|
-
* @param {object} options
|
|
17
|
-
* @param {string} options.socketPath - Unix socket path
|
|
18
|
-
* @param {Buffer|string} options.data - Data to send
|
|
19
|
-
* @param {number} [options.timeoutMs=1500] - Timeout in ms
|
|
20
|
-
* @returns {Promise<{ok: boolean, error: string|null}>}
|
|
21
|
-
*/
|
|
15
|
+
/** Send input to an attach socket via STDIN message. */
|
|
22
16
|
function sendInput(options = {}) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
17
|
+
const { socketPath, data, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
|
|
18
|
+
if (!socketPath) {
|
|
19
|
+
throw new Error('sendInput: socketPath is required');
|
|
20
|
+
}
|
|
21
|
+
if (data === undefined || data === null) {
|
|
22
|
+
throw new Error('sendInput: data is required');
|
|
23
|
+
}
|
|
24
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
25
|
+
throw new Error(`sendInput: timeoutMs must be positive (got ${timeoutMs})`);
|
|
26
|
+
}
|
|
27
|
+
if (!node_fs_1.default.existsSync(socketPath)) {
|
|
28
|
+
return { ok: false, error: `Socket not found: ${socketPath}` };
|
|
29
|
+
}
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
let settled = false;
|
|
32
|
+
let timeout;
|
|
33
|
+
const socket = node_net_1.default.createConnection(socketPath);
|
|
34
|
+
const finish = (result) => {
|
|
35
|
+
if (settled)
|
|
36
|
+
return;
|
|
37
|
+
settled = true;
|
|
38
|
+
if (timeout) {
|
|
39
|
+
clearTimeout(timeout);
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
socket.end();
|
|
43
|
+
socket.destroy();
|
|
44
|
+
}
|
|
45
|
+
catch (cleanupError) {
|
|
46
|
+
console.warn('[sendInput] socket cleanup failed:', cleanupError);
|
|
47
|
+
}
|
|
48
|
+
resolve(result);
|
|
49
|
+
};
|
|
50
|
+
timeout = setTimeout(() => {
|
|
51
|
+
finish({ ok: false, error: 'Timeout waiting for socket connection' });
|
|
52
|
+
}, timeoutMs);
|
|
53
|
+
socket.on('connect', () => {
|
|
54
|
+
try {
|
|
55
|
+
const encoded = protocol_1.default.encode(protocol_1.default.createStdinMessage(data));
|
|
56
|
+
socket.write(encoded, (error) => {
|
|
57
|
+
if (error) {
|
|
58
|
+
finish({ ok: false, error: error.message });
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
finish({ ok: true, error: null });
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
67
|
+
finish({ ok: false, error: reason });
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
socket.on('error', (error) => {
|
|
71
|
+
finish({ ok: false, error: error.message });
|
|
74
72
|
});
|
|
75
|
-
} catch (err) {
|
|
76
|
-
finish({ ok: false, error: err.message });
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
socket.on('error', (err) => {
|
|
81
|
-
finish({ ok: false, error: err.message });
|
|
82
73
|
});
|
|
83
|
-
});
|
|
84
74
|
}
|
|
85
|
-
|
|
86
75
|
module.exports = {
|
|
87
|
-
|
|
76
|
+
sendInput,
|
|
88
77
|
};
|